@feathersdev/websites 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/app/assets/icons/feathers.svg +12 -0
  2. package/app/assets/icons/pinion.svg +3 -0
  3. package/app/assets/icons/talon.svg +3 -0
  4. package/app/components/CodePreview.vue +139 -0
  5. package/app/components/CodeSnippet.vue +119 -0
  6. package/app/components/Discord.vue +33 -0
  7. package/app/components/DocsPage.vue +11 -0
  8. package/app/components/DocsSearch.vue +62 -0
  9. package/app/components/DocsSearchModal.vue +831 -0
  10. package/app/components/DocsSidebar.vue +43 -0
  11. package/app/components/DocsTiles.vue +121 -0
  12. package/app/components/FooterMain.vue +46 -0
  13. package/app/components/HeroProduct.vue +148 -0
  14. package/app/components/MoonSurface.vue +1599 -0
  15. package/app/components/NewsletterSubscribe.vue +21 -0
  16. package/app/components/SidebarMenuSection.vue +45 -0
  17. package/app/components/TableOfContents.vue +221 -0
  18. package/app/components/ThemeToggle.vue +10 -0
  19. package/app/components/Titles.vue +39 -0
  20. package/app/components/TocTree.vue +49 -0
  21. package/app/components/content/BlueskyEmbed.vue +92 -0
  22. package/app/components/content/CodeWrapper.vue +10 -0
  23. package/app/components/content/ProseA.vue +19 -0
  24. package/app/components/content/ProseAlert.vue +11 -0
  25. package/app/components/content/ProseBlockquote.vue +11 -0
  26. package/app/components/content/ProseEm.vue +5 -0
  27. package/app/components/content/ProseH1.vue +17 -0
  28. package/app/components/content/ProseH2.vue +17 -0
  29. package/app/components/content/ProseH3.vue +17 -0
  30. package/app/components/content/ProseH4.vue +17 -0
  31. package/app/components/content/ProseH5.vue +17 -0
  32. package/app/components/content/ProseH6.vue +17 -0
  33. package/app/components/content/ProseHr.vue +3 -0
  34. package/app/components/content/ProseImg.vue +37 -0
  35. package/app/components/content/ProseLi.vue +3 -0
  36. package/app/components/content/ProseOl.vue +5 -0
  37. package/app/components/content/ProseP.vue +3 -0
  38. package/app/components/content/ProsePre.vue +49 -0
  39. package/app/components/content/ProsePre2.vue +69 -0
  40. package/app/components/content/ProseScript.vue +37 -0
  41. package/app/components/content/ProseStrong.vue +5 -0
  42. package/app/components/content/ProseTable.vue +7 -0
  43. package/app/components/content/ProseTbody.vue +5 -0
  44. package/app/components/content/ProseTd.vue +5 -0
  45. package/app/components/content/ProseTh.vue +5 -0
  46. package/app/components/content/ProseThead.vue +5 -0
  47. package/app/components/content/ProseTr.vue +5 -0
  48. package/app/components/content/ProseUl.vue +5 -0
  49. package/app/composables/useGlobalSearch.ts +22 -0
  50. package/app/composables/useTheme.ts +17 -0
  51. package/app/layouts/default.vue +46 -0
  52. package/app/layouts/docs.vue +62 -0
  53. package/app/layouts/page.vue +11 -0
  54. package/app/pages/help.vue +19 -0
  55. package/app/pages/privacy.vue +30 -0
  56. package/app/pages/tos.vue +28 -0
  57. package/content/pages/privacy.md +152 -0
  58. package/content/pages/tos.md +133 -0
  59. package/content/products/1-auth.yaml +13 -0
  60. package/content/products/2-feathers.yaml +13 -0
  61. package/content/products/3-pinion.yaml +13 -0
  62. package/content/products/4-daisyui-kit.yaml +14 -0
  63. package/content/products/lofi.yaml +14 -0
  64. package/content.config.ts +36 -0
  65. package/nuxt.config.ts +102 -0
  66. package/package.json +33 -0
  67. package/public/img/bird-comms.png +0 -0
  68. package/public/img/bird-yellow.svg +125 -0
  69. package/public/img/logo-auth-white.svg +22 -0
  70. package/public/img/logos/feathersdev-white.svg +24 -0
  71. package/public/img/logos/talon-auth-white.svg +19 -0
  72. package/public/img/planet-yellow.svg +31 -0
  73. package/public/img/rock-lg.svg +6 -0
  74. package/public/img/rock-md.svg +6 -0
  75. package/public/img/top_background.svg +56 -0
  76. package/vitest.config.ts +7 -0
@@ -0,0 +1,43 @@
1
+ <script setup>
2
+ const $emit = defineEmits(['close'])
3
+
4
+ const { data } = await useAsyncData('menu-docs', () =>
5
+ queryCollection('menus').where('stem', '==', 'menus/docs').first()
6
+ )
7
+ </script>
8
+
9
+ <template>
10
+ <div class="relative menu w-60 bg-base-200 text-base-content h-full overflow-y-auto">
11
+ <div class="relative z-10">
12
+ <Flex justify-end class="absolute right-2 lg:hidden z-20 top-4">
13
+ <Button square ghost @click="$emit('close')">
14
+ <Icon name="feather:x" size="24" />
15
+ </Button>
16
+ </Flex>
17
+
18
+ <Flex col class="pb-12 pl-2">
19
+ <div class="px-2 pb-4 pt-2">
20
+ <DocsSearch />
21
+ </div>
22
+
23
+ <template v-for="link in data?.items" :key="link.path">
24
+ <template v-if="link.children">
25
+ <SidebarMenuSection :section="link" />
26
+ </template>
27
+ <template v-else>
28
+ <MenuItem class="ml-2">
29
+ <NuxtLink :to="link.path" exact-active-class="menu-active" class="flex flex-row items-center">
30
+ <Icon v-if="link.icon" :name="link.icon" class="w-5 h-5 mr-1" />
31
+ <Text class="grow">
32
+ {{ link.title }}
33
+ </Text>
34
+ <Badge v-if="link.meta?.new" sm accent class="ml-2"> new </Badge>
35
+ </NuxtLink>
36
+ </MenuItem>
37
+ </template>
38
+ </template>
39
+ </Flex>
40
+ <!-- <pre class="text-xs">{{ data }}</pre> -->
41
+ </div>
42
+ </div>
43
+ </template>
@@ -0,0 +1,121 @@
1
+ <script setup lang="ts">
2
+ import type { AuthDocsCollectionItem, FeathersDocsCollectionItem, PinionDocsCollectionItem } from '@nuxt/content'
3
+
4
+ defineProps<{
5
+ pages: (PinionDocsCollectionItem | AuthDocsCollectionItem | FeathersDocsCollectionItem)[]
6
+ }>()
7
+ </script>
8
+
9
+ <template>
10
+ <section class="mx-auto">
11
+ <div v-if="pages" class="pt-6 px-3 lg:px-6 grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8" role="list">
12
+ <Card
13
+ is="article"
14
+ v-for="(page, index) in pages"
15
+ :key="page.id"
16
+ class="card bg-base-300/20 rounded-xl h-full flex flex-col overflow-hidden"
17
+ role="listitem"
18
+ >
19
+ <header
20
+ :class="[
21
+ 'blob-pattern',
22
+ 'pattern-variant-' + (index % 5),
23
+ 'aspect-video',
24
+ 'flex',
25
+ 'items-center',
26
+ 'justify-center',
27
+ 'relative',
28
+ 'overflow-hidden',
29
+ ]"
30
+ >
31
+ <NuxtLink :to="page.path" class="w-full h-full flex items-center justify-center z-10">
32
+ <h3 class="text-2xl text-center">{{ page.title }}</h3>
33
+ </NuxtLink>
34
+ </header>
35
+ <CardBody class="grow flex flex-col">
36
+ <Text>{{ page.description }}</Text>
37
+
38
+ <div class="grow" />
39
+
40
+ <CardActions>
41
+ <NuxtLink :to="page.path" class="btn btn-ghost" :aria-label="`Read more about ${page.title}`">
42
+ Read More
43
+ <Icon name="feather:chevron-right" size="24" />
44
+ </NuxtLink>
45
+ </CardActions>
46
+ </CardBody>
47
+ </Card>
48
+ </div>
49
+ <!-- <pre class="text-xs">{{ pages.map(page => ({ ...page, body: undefined })) }}</pre> -->
50
+ </section>
51
+ </template>
52
+
53
+ <style scoped>
54
+ .blob-pattern {
55
+ background-color: var(--color-base-300);
56
+ position: relative;
57
+ }
58
+
59
+ .blob-pattern::before {
60
+ content: '';
61
+ position: absolute;
62
+ top: 0;
63
+ left: 0;
64
+ right: 0;
65
+ bottom: 0;
66
+ opacity: 0.2;
67
+ transition: opacity 0.3s ease;
68
+ }
69
+
70
+ /* Create a subtle hover effect */
71
+ .blob-pattern:hover::before {
72
+ opacity: 0.3;
73
+ }
74
+
75
+ /* Pattern variant 0 */
76
+ .pattern-variant-0::before {
77
+ background:
78
+ radial-gradient(circle at 20% 30%, rgba(255, 255, 255, 0.3) 0%, transparent 25%),
79
+ radial-gradient(circle at 70% 65%, rgba(255, 255, 255, 0.3) 0%, transparent 20%),
80
+ radial-gradient(circle at 40% 80%, rgba(255, 255, 255, 0.3) 0%, transparent 30%),
81
+ radial-gradient(circle at 80% 15%, rgba(255, 255, 255, 0.3) 0%, transparent 20%),
82
+ radial-gradient(circle at 10% 60%, rgba(255, 255, 255, 0.3) 0%, transparent 15%);
83
+ }
84
+
85
+ /* Pattern variant 1 */
86
+ .pattern-variant-1::before {
87
+ background:
88
+ radial-gradient(ellipse at 65% 25%, rgba(255, 255, 255, 0.3) 0%, transparent 30%),
89
+ radial-gradient(circle at 15% 55%, rgba(255, 255, 255, 0.3) 0%, transparent 25%),
90
+ radial-gradient(ellipse at 75% 70%, rgba(255, 255, 255, 0.3) 0%, transparent 18%),
91
+ radial-gradient(circle at 35% 10%, rgba(255, 255, 255, 0.3) 0%, transparent 22%);
92
+ }
93
+
94
+ /* Pattern variant 2 */
95
+ .pattern-variant-2::before {
96
+ background:
97
+ radial-gradient(circle at 30% 20%, rgba(255, 255, 255, 0.3) 0%, transparent 28%),
98
+ radial-gradient(ellipse at 60% 50%, rgba(255, 255, 255, 0.3) 0%, transparent 35%),
99
+ radial-gradient(circle at 10% 80%, rgba(255, 255, 255, 0.3) 0%, transparent 15%),
100
+ radial-gradient(circle at 85% 35%, rgba(255, 255, 255, 0.3) 0%, transparent 25%);
101
+ }
102
+
103
+ /* Pattern variant 3 */
104
+ .pattern-variant-3::before {
105
+ background:
106
+ radial-gradient(ellipse at 45% 45%, rgba(255, 255, 255, 0.3) 0%, transparent 40%),
107
+ radial-gradient(circle at 85% 75%, rgba(255, 255, 255, 0.3) 0%, transparent 20%),
108
+ radial-gradient(circle at 5% 35%, rgba(255, 255, 255, 0.3) 0%, transparent 18%),
109
+ radial-gradient(ellipse at 70% 15%, rgba(255, 255, 255, 0.3) 0%, transparent 22%);
110
+ }
111
+
112
+ /* Pattern variant 4 */
113
+ .pattern-variant-4::before {
114
+ background:
115
+ radial-gradient(circle at 25% 15%, rgba(255, 255, 255, 0.3) 0%, transparent 22%),
116
+ radial-gradient(circle at 50% 65%, rgba(255, 255, 255, 0.3) 0%, transparent 30%),
117
+ radial-gradient(ellipse at 80% 25%, rgba(255, 255, 255, 0.3) 0%, transparent 25%),
118
+ radial-gradient(circle at 15% 75%, rgba(255, 255, 255, 0.3) 0%, transparent 18%),
119
+ radial-gradient(ellipse at 90% 85%, rgba(255, 255, 255, 0.3) 0%, transparent 15%);
120
+ }
121
+ </style>
@@ -0,0 +1,46 @@
1
+ <script setup lang="ts">
2
+ const { data: products } = await useAsyncData(() => queryCollection('products').where('published', '=', true).all())
3
+ </script>
4
+
5
+ <template>
6
+ <MoonSurface />
7
+ <div class="bg-[#251938]" data-theme="dark">
8
+ <div class="flex items-center justify-center py-8">
9
+ <Logo />
10
+ </div>
11
+ <Footer
12
+ class="sm:footer-horizontal text-neutral-content max-w-[87rem] mx-auto p-10 justify-evenly text-lg -ml-5.5 sm:ml-0"
13
+ >
14
+ <nav class="flex flex-col gap-4">
15
+ <FooterTitle class="normal-case">Projects</FooterTitle>
16
+ <NuxtLink
17
+ v-for="product in products"
18
+ :key="product.slug"
19
+ class="link link-hover"
20
+ :to="product.link"
21
+ target="_blank"
22
+ >
23
+ {{ product.title }}
24
+ </NuxtLink>
25
+ </nav>
26
+ <nav class="flex flex-col gap-4">
27
+ <FooterTitle class="normal-case">Learn</FooterTitle>
28
+ <NuxtLink class="link link-hover" to="/blog"> Blog </NuxtLink>
29
+ <NuxtLink class="link link-hover" to="https://discord.gg/qa8kez8QBx"> Discord </NuxtLink>
30
+ <NuxtLink class="link link-hover" to="https://github.com/feathersdev"> Github </NuxtLink>
31
+ </nav>
32
+ <nav class="flex flex-col gap-4">
33
+ <FooterTitle class="normal-case">About</FooterTitle>
34
+ <NuxtLink class="link link-hover" to="/tos"> Terms of Service </NuxtLink>
35
+ <NuxtLink class="link link-hover" to="/privacy"> Privacy Policy </NuxtLink>
36
+ </nav>
37
+ </Footer>
38
+
39
+ <div class="bg-gradient-to-r from-primary/10 via-primary/20 to-primary/10 h-1 max-w-[87rem] mx-auto" />
40
+ <div class="flex items-center justify-center py-3">
41
+ <p class="text-center text-sm text-neutral-content/30">
42
+ Copyright © 2012 - {{ new Date().getFullYear() }} feathers.dev
43
+ </p>
44
+ </div>
45
+ </div>
46
+ </template>
@@ -0,0 +1,148 @@
1
+ <script setup lang="ts">
2
+ import type { Product } from '~~/content.config.schema'
3
+
4
+ defineProps<{
5
+ product: Product
6
+ birdClasses: string
7
+ planetClasses: string
8
+ }>()
9
+ </script>
10
+
11
+ <template>
12
+ <div v-if="product" class="pb-32 bg-transparent" data-theme="dark">
13
+ <Flex col class="mx-auto max-w-6xl text-left lg:text-left gap-10 mt-28 sm:mt-32 relative md:px-4 lg:flex-row">
14
+ <Flex col items-center class="lg:items-start gap-8 lg:gap-12 flex-1">
15
+ <Text size="lg" class="text-balance lg:text-3xl text-center md:text-left">{{ product.description }}</Text>
16
+
17
+ <div>
18
+ <NuxtImg :src="product.logo" class="w-96" />
19
+ </div>
20
+
21
+ <Text is="div" base center class="lg:text-left">
22
+ {{ product.longDescription }}
23
+ </Text>
24
+
25
+ <Flex col class="sm:flex-row gap-4 w-full justify-center lg:justify-start">
26
+ <Button
27
+ is="NuxtLink"
28
+ v-if="product.link"
29
+ :to="product.link"
30
+ lg
31
+ class="bg-primary-content text-neutral hover:bg-primary-content/80"
32
+ >
33
+ Get Started
34
+ </Button>
35
+ <Button is="NuxtLink" v-if="product.meta.docLink" :to="product.meta.docLink" lg neutral>
36
+ Documentation
37
+ </Button>
38
+ </Flex>
39
+ </Flex>
40
+
41
+ <Flex class="relative flex-1">
42
+ <NuxtImg :src="product.meta.birdImage" :class="birdClasses" />
43
+ <NuxtImg :src="product.meta.planetImage" :class="planetClasses" />
44
+ <NuxtImg
45
+ src="/img/rock-md.svg"
46
+ class="absolute w-[144px] opacity-0 md:opacity-100 md:block top-50 left-72 lg:-top-1 lg:left-0 transition-all duration-500 ease-in-out floating-rock-1"
47
+ />
48
+ <NuxtImg
49
+ src="/img/rock-lg.svg"
50
+ class="absolute w-[386px] -bottom-24 -right-28 transition-all duration-500 ease-in-out floating-rock-2 hidden lg:block"
51
+ />
52
+ </Flex>
53
+ </Flex>
54
+ </div>
55
+ </template>
56
+
57
+ <style scoped>
58
+ @keyframes float {
59
+ 0%,
60
+ 100% {
61
+ transform: translateY(0);
62
+ }
63
+ 50% {
64
+ transform: translateY(-15px);
65
+ }
66
+ }
67
+
68
+ @keyframes float-rock-1 {
69
+ 0%,
70
+ 100% {
71
+ transform: translate(0, 0) rotate(0deg);
72
+ }
73
+ 33% {
74
+ transform: translate(20px, -15px) rotate(24deg);
75
+ }
76
+ 76% {
77
+ transform: translate(-28px, 15px) rotate(54deg);
78
+ }
79
+ }
80
+
81
+ @keyframes float-rock-2 {
82
+ 0%,
83
+ 100% {
84
+ transform: translate(0, 0) rotate(0deg);
85
+ }
86
+ 30% {
87
+ transform: translate(-5px, -10px) rotate(-4deg);
88
+ }
89
+ 70% {
90
+ transform: translate(8px, 8px) rotate(4deg);
91
+ }
92
+ }
93
+
94
+ .floating {
95
+ animation: float 6s ease-in-out infinite;
96
+ will-change: transform;
97
+ }
98
+
99
+ .floating-rock-1 {
100
+ animation: float-rock-1 18s ease-in-out infinite;
101
+ will-change: transform;
102
+ transform-origin: center;
103
+ }
104
+
105
+ .floating-rock-2 {
106
+ animation: float-rock-2 19s ease-in-out infinite;
107
+ will-change: transform;
108
+ transform-origin: center;
109
+ }
110
+
111
+ @keyframes float-shuttle {
112
+ 0%,
113
+ 100% {
114
+ transform: translate(0, 0) rotate(-1deg) scale(1);
115
+ }
116
+ 25% {
117
+ transform: translate(-5px, -3px) rotate(0.5deg) scale(1.005);
118
+ }
119
+ 50% {
120
+ transform: translate(3px, 2px) rotate(-0.5deg) scale(0.995);
121
+ }
122
+ 75% {
123
+ transform: translate(-2px, 4px) rotate(0.3deg) scale(1.002);
124
+ }
125
+ }
126
+
127
+ .floating-shuttle {
128
+ animation: float-shuttle 20s ease-in-out infinite;
129
+ will-change: transform;
130
+ transform-origin: center;
131
+ }
132
+
133
+ @keyframes planet-wobble {
134
+ 0%,
135
+ 100% {
136
+ transform: rotate(0deg);
137
+ }
138
+ 50% {
139
+ transform: rotate(-32deg);
140
+ }
141
+ }
142
+
143
+ .planet-wobble {
144
+ animation: planet-wobble 60s infinite;
145
+ will-change: transform;
146
+ transform-origin: center;
147
+ }
148
+ </style>