Skip to content

Commit

Permalink
progress commit
Browse files Browse the repository at this point in the history
  • Loading branch information
harlan-zw committed Oct 5, 2024
1 parent d4b4efa commit d53227f
Show file tree
Hide file tree
Showing 112 changed files with 4,910 additions and 258 deletions.
1 change: 1 addition & 0 deletions docs/.npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
shamefully-hoist=true
20 changes: 20 additions & 0 deletions docs/app/app.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export default defineAppConfig({
toaster: {
position: 'bottom-right' as const,
expand: true,
duration: 5000,
},
ui: {
colors: {
primary: 'green',
gray: 'slate',
},
},
uiPro: {
prose: {
codeIcon: {
'robots.txt': 'vscode-icons:file-type-robots',
},
},
},
})
145 changes: 145 additions & 0 deletions docs/app/app.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
<script setup lang="ts">
import fetchStats from '~/composables/stats'
import { modules } from '../../src/const'
const { data: navigation } = await useAsyncData('navigation', () => fetchContentNavigation())
const { data: stats } = await useAsyncData('stats', () => fetchStats())
const route = useRoute()
const publicRuntimeConfig = useRuntimeConfig().public
const segment = computed(() => route.path.split('/')[1])
const children = computed(() => {
return navigation!.value!.find(i => i._path === `/${segment.value}`)?.children || []
})
provide('stats', stats)
provide('navigation', navigation)
provide('docsAsideLinks', children)
provide('modules', modules)
provide('module', computed(() => {
const m = SeoModules.find(l => l?.slug === segment.value)
const stats = (publicRuntimeConfig.moduleStats || []).find(m2 => m2.id === m?.id)?.stats || {}
return m
}))
useSeoMeta({
ogTitle: 'Nuxt SEO · All the boring SEO work for Nuxt done.',
// twitterTitle: 'Nuxt SEO - All the boring SEO work for Nuxt done.',
})
</script>

<template>
<div>
<Header />

<NuxtLayout>
<NuxtPage />
</NuxtLayout>

<ClientOnly />

<footer class="relative z-10 antialiased font-sans bg-white dark:bg-gray-900 text-sm text-gray-700 dark:text-gray-200 mt-20">
<div class="border-t border-gray-200 dark:border-gray-800">
<UContainer>
<div class="py-10 grid xl:grid-cols-3 lg:gap-20 gap-10">
<div>
<div class="mb-5">
<NuxtLink to="/" title="Home" class="flex items-end gap-1.5 font-bold text-xl text-gray-900 dark:text-white font-title">
<Logo />
</NuxtLink>
</div>
<nav>
<ul class="space-y-6">
<li>
<NuxtLink to="/docs/nuxt-seo/getting-started/what-is-nuxt-seo">
What is Nuxt SEO?
</NuxtLink>
</li>
<li>
<NuxtLink to="/docs/nuxt-seo/getting-started/installation">
Install Nuxt SEO
</NuxtLink>
</li>
</ul>
</nav>
</div>
<div>
<h3 class="font-bold mb-5">
Modules
</h3>
<nav>
<ul class="grid grid-cols-2 gap-6">
<li v-for="(module, key) in modules" :key="key">
<NuxtLink :to="module.to">
<UIcon dynamic :name="module.icon" />
{{ module.label }}
</NuxtLink>
</li>
</ul>
</nav>
</div>
<div>
<div class="bg-gray-50 dark:bg-gray-800 flex rounded-xl shadow p-5">
<div>
<div class="mb-2">
Hey <UIcon name="i-noto-waving-hand" /> My name is <a href="https://harlanzw.com" target="_blank" class="underline">Harlan</a> and I'm the author and maintainer of Nuxt SEO.
</div>
<div>
I'd love to have your <a href="https://github.com/sponsors/harlan-zw" class="underline">support</a>!
</div>
</div>
<div class="gap-3">
<img alt="Harlan Wilton" loading="lazy" src="https://avatars.githubusercontent.com/u/5326365?v=4" class="mx-auto rounded-full w-10 h-10 mb-3">
<div class="flex justify-center items-center opacity-70">
<UButton color="white" title="Twitter" variant="ghost" to="https://twitter.com/harlan_zw" target="_blank">
<UIcon name="i-logos-twitter" class="text-xl" />
</UButton>
<UButton color="white" title="GitHub" aria-label="GitHub" variant="ghost" to="https://github.com/harlan-zw" target="_blank">
<UIcon name="i-logos-github-icon" class="text-xl" />
</UButton>
</div>
</div>
</div>
</div>
</div>
</UContainer>
</div>
<div class="border-t border-gray-200 dark:border-gray-800">
<UContainer>
<div class="py-10">
Copyright © 2023-{{ new Date().getFullYear() }} Harlan Wilton - <a href="https://github.com/harlan-zw/nuxt-seo/blob/main/LICENSE">MIT License</a>
</div>
</UContainer>
</div>
</footer>
<NuxtLoadingIndicator />
</div>
</template>

<style>
@import "tailwindcss";
@import "@nuxt/ui-pro";
@source "../content/**/*.md";
@theme {
--font-family-sans: 'Public Sans', sans-serif;
--font-family-mono: 'Fira Code', monospace;
--color-green-50: #EFFDF5;
--color-green-100: #D9FBE8;
--color-green-200: #B3F5D1;
--color-green-300: #75EDAE;
--color-green-400: #00DC82;
--color-green-500: #00C16A;
--color-green-600: #00A155;
--color-green-700: #007F45;
--color-green-800: #016538;
--color-green-900: #0A5331;
--color-green-950: #052E16;
}
:root {
--container-width: 90rem;
}
</style>
7 changes: 7 additions & 0 deletions docs/app/components/Banner.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<template>
<UBanner icon="i-heroicons-wrench-screwdriver" :actions="[{ label: 'Go to Nuxt UI v2', to: 'https://ui.nuxt.com', trailingIcon: 'i-heroicons-arrow-right-20-solid', class: 'rounded-full' }]" :close="false">
<template #title>
You're looking at the documentation for <span class="font-semibold">Nuxt SEO</span>!
</template>
</UBanner>
</template>
166 changes: 166 additions & 0 deletions docs/app/components/BouncingBots.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
<script lang="ts" setup>
import { onMounted, ref, useElementHover, useIntervalFn, watch } from '#imports'
import { useMouseInElement } from '@vueuse/core'
defineProps<{
icon: string
interval: number
}>()
const robotsInject = inject('robots')
const container = ref()
// we're not moving anywhere
const direction = {
x: Math.random() > 0.5 ? 1 : -1,
y: Math.random() > 0.5 ? 1 : -1,
}
const pos = {
x: 0,
y: 0,
}
const size = {
// tiny buffer
width: 33,
height: 33,
}
const styles = ref({
opacity: 0,
transform: '',
})
let rotation = 0
let speed = 0
const isHovered = ref(robotsInject.value.hover)
onMounted(() => {
// parent node for bounding box
const parentNode = container.value.parentNode
// hover requires a class
const parentHover = useElementHover(container.value.closest('.showcase-card'))
watch(parentHover, () => {
isHovered.value = parentHover.value
})
const { width, height } = parentNode.getBoundingClientRect()
const { elementX: mouseX, elementY: mouseY } = useMouseInElement(parentNode)
// set facing rotation, should be 0, 90, 180, 270
rotation = 0
// start in a random spot
pos.x = Math.min(Math.random() * width, width - size.width)
pos.y = Math.min(Math.random() * height, height - size.height)
// start at a speed between 1-3
speed = 0
const maxSpeed = Math.random() * 2 + 3
// start by assigning a reandom diagonal direction to head towards
direction.x = Math.random() > 0.5 ? -1 : -1
direction.y = Math.random() > 0.5 ? 1 : -1
let isEvadingMouse = false
const { pause, resume } = useIntervalFn(() => {
// increase speed if it's not at max
if (speed < maxSpeed)
speed += 0.1
// if it's too fast, slow it down
if (speed > maxSpeed)
speed -= 0.1
// do the movement
pos.x += Math.round(direction.x * speed)
pos.y += Math.round(direction.y * speed)
// we want to create a DVD screensaver effect, we move diagonally until we hit a wall then we bounce off of it
// travel diagonally, each time we hit the corner, add a carriage
// if we hit the top or bottom, reverse the y direction
// if we hit the left or right, reverse the x direction
// only if the direction is still heading out of bounds
if (pos.x + size.width > width && direction.x === 1) {
rotation = 90
direction.x *= -1
// only if we're not going 1.5x the max speed, increase the speed for a bounce effect
speed = Math.min(speed + maxSpeed * 1.5, maxSpeed * 1.5)
}
if (pos.x < 0 && direction.x === -1) {
rotation = 270
direction.x *= -1
speed = Math.min(speed + maxSpeed * 1.5, maxSpeed * 1.5)
}
if (pos.y + size.height > height && direction.y === 1) {
rotation = 0
direction.y *= -1
speed = Math.min(speed + maxSpeed * 1.5, maxSpeed * 1.5)
}
if (pos.y < 0 && direction.y === -1) {
rotation = 180
direction.y *= -1
speed = Math.min(speed + maxSpeed * 1.5, maxSpeed * 1.5)
}
// also collide with the mouse
if (pos.x < mouseX.value && pos.x + size.width > mouseX.value && pos.y < mouseY.value && pos.y + size.height > mouseY.value) {
if (isEvadingMouse)
return
// we're colliding with the mouse, so we need to bounce off of it
// we need to figure out which side we're colliding with
// we can do this by figuring out which side is closer
const xDist = Math.min(Math.abs(pos.x - mouseX.value), Math.abs(pos.x + size.width - mouseX.value))
const yDist = Math.min(Math.abs(pos.y - mouseY.value), Math.abs(pos.y + size.height - mouseY.value))
if (xDist < yDist) {
// we're colliding with the left or right side
direction.x *= -1
rotation = 90
}
else {
// we're colliding with the top or bottom side
direction.y *= -1
rotation = 0
}
isEvadingMouse = true
robotsInject.value.collisions += 1
speed = Math.min(speed + maxSpeed * 1.5, maxSpeed * 1.5)
}
else {
isEvadingMouse = false
}
const stylesTmp: Record<string, any> = {}
// apply transform style to container
if (rotation === 180) {
// we need to flip instread
stylesTmp.transform = `translate(${pos.x}px, ${pos.y}px) rotateX(${rotation}deg)`
}
else {
stylesTmp.transform = `translate(${pos.x}px, ${pos.y}px) rotate(${rotation}deg)`
}
stylesTmp.opacity = Math.min(styles.value.opacity + 0.01 + Math.random() * 0.01, 1)
styles.value = stylesTmp
}, 1000 / 30 /* 30 fps */, {
immediate: isHovered.value,
})
watch(parentHover, (hovered) => {
if (hovered) {
resume()
robotsInject.value.hover = true
}
else {
robotsInject.value.hover = false
pause()
rotation = 0
speed = 0
styles.value = {
opacity: 0,
transform: styles.value.transform,
}
}
})
})
</script>

<template>
<div ref="container" class="absolute top-0 left-0">
<UIcon dynamic :name="icon" size="30" class="transition-opacity" :style="styles" />
</div>
</template>
18 changes: 18 additions & 0 deletions docs/app/components/Discord.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<script lang="ts" setup>
defineProps<{ username: string, image: string }>()
</script>

<template>
<div class="tweet max-w-[550px] mx-auto my-15 dark:bg-black bg-white p-4 rounded-xl border not-prose dark:border-gray-700 px-5 py-5 text-black dark:text-white relative">
<UIcon name="i-logos-discord-icon" class="opacity-60 absolute top-3 right-4 w-6 h-6" />
<div class="flex gap-3">
<div><UAvatar class="mt-1" :src="image" :alt="`Discord user ${username}`" /></div>
<div class="opacity-90">
<div class="font-semibold">
{{ username }}
</div>
<slot />
</div>
</div>
</div>
</template>
24 changes: 24 additions & 0 deletions docs/app/components/Header.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<script setup lang="ts">
// import { Dialog, DialogPanel, TransitionRoot } from '@headlessui/vue'
//
const isDialogOpen = ref(false)
</script>

<template>
<header class="sticky top-0 z-50 w-full backdrop-blur flex-none dark:border-gray-800">
<HeaderLinks v-model="isDialogOpen" />

<!-- <TransitionRoot :show="isDialogOpen" as="template">-->
<!-- <Dialog as="div" @close="isDialogOpen = false">-->
<!-- <DialogPanel class="fixed inset-0 z-50 overflow-y-auto bg-white dark:bg-gray-900 lg:hidden">-->
<!-- <div class="px-4 sm:px-6 sticky top-0 border-b border-gray-200 dark:border-gray-800 bg-white/75 dark:bg-gray-900/75 backdrop-blur z-10">-->
<!-- <HeaderLinks v-model="isDialogOpen" :links="links" />-->
<!-- </div>-->
<!-- <div class="px-4 sm:px-6 py-4 sm:py-6">-->
<!-- &lt;!&ndash; <UDocsAsideLinks @click="isDialogOpen = false" /> &ndash;&gt;-->
<!-- </div>-->
<!-- </DialogPanel>-->
<!-- </Dialog>-->
<!-- </TransitionRoot>-->
</header>
</template>
Loading

0 comments on commit d53227f

Please sign in to comment.