How It Works
diff --git a/components/overlay/loading/clipboard.vue b/components/overlay/loading/clipboard.vue
new file mode 100644
index 0000000..7cf933d
--- /dev/null
+++ b/components/overlay/loading/clipboard.vue
@@ -0,0 +1,64 @@
+
+
+
+
\ No newline at end of file
diff --git a/components/overlay/loading/flipping-book-page.vue b/components/overlay/loading/flipping-book-page.vue
new file mode 100644
index 0000000..9fba9b6
--- /dev/null
+++ b/components/overlay/loading/flipping-book-page.vue
@@ -0,0 +1,62 @@
+
+
+
+
\ No newline at end of file
diff --git a/components/overlay/loading/flipping-card.vue b/components/overlay/loading/flipping-card.vue
new file mode 100644
index 0000000..c4538b3
--- /dev/null
+++ b/components/overlay/loading/flipping-card.vue
@@ -0,0 +1,28 @@
+
+
+
+
\ No newline at end of file
diff --git a/components/overlay/loading/padlock.vue b/components/overlay/loading/padlock.vue
new file mode 100644
index 0000000..c3de6c6
--- /dev/null
+++ b/components/overlay/loading/padlock.vue
@@ -0,0 +1,55 @@
+
+
+
+
\ No newline at end of file
diff --git a/components/overlay/loading/pulse-ring.vue b/components/overlay/loading/pulse-ring.vue
new file mode 100644
index 0000000..e9289c8
--- /dev/null
+++ b/components/overlay/loading/pulse-ring.vue
@@ -0,0 +1,41 @@
+
+
+
+
\ No newline at end of file
diff --git a/components/overlay/loading/text.vue b/components/overlay/loading/text.vue
new file mode 100644
index 0000000..156b058
--- /dev/null
+++ b/components/overlay/loading/text.vue
@@ -0,0 +1,44 @@
+
+ {{ props?.loaderText || 'Loading' }}
+
+
+
\ No newline at end of file
diff --git a/components/overlay/loading/trailing-letter.vue b/components/overlay/loading/trailing-letter.vue
new file mode 100644
index 0000000..81f3978
--- /dev/null
+++ b/components/overlay/loading/trailing-letter.vue
@@ -0,0 +1,61 @@
+
+
+
+
\ No newline at end of file
diff --git a/components/ui/card/Card.vue b/components/ui/card/Card.vue
new file mode 100644
index 0000000..94b6903
--- /dev/null
+++ b/components/ui/card/Card.vue
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
diff --git a/components/ui/card/CardContent.vue b/components/ui/card/CardContent.vue
new file mode 100644
index 0000000..785913a
--- /dev/null
+++ b/components/ui/card/CardContent.vue
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
diff --git a/components/ui/card/CardDescription.vue b/components/ui/card/CardDescription.vue
new file mode 100644
index 0000000..d5faedd
--- /dev/null
+++ b/components/ui/card/CardDescription.vue
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
diff --git a/components/ui/card/CardFooter.vue b/components/ui/card/CardFooter.vue
new file mode 100644
index 0000000..1ed2efe
--- /dev/null
+++ b/components/ui/card/CardFooter.vue
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
diff --git a/components/ui/card/CardHeader.vue b/components/ui/card/CardHeader.vue
new file mode 100644
index 0000000..951d227
--- /dev/null
+++ b/components/ui/card/CardHeader.vue
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
diff --git a/components/ui/card/CardTitle.vue b/components/ui/card/CardTitle.vue
new file mode 100644
index 0000000..fc302e2
--- /dev/null
+++ b/components/ui/card/CardTitle.vue
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
diff --git a/components/ui/card/index.ts b/components/ui/card/index.ts
new file mode 100644
index 0000000..9ff6d5e
--- /dev/null
+++ b/components/ui/card/index.ts
@@ -0,0 +1,6 @@
+export { default as Card } from './Card.vue'
+export { default as CardContent } from './CardContent.vue'
+export { default as CardDescription } from './CardDescription.vue'
+export { default as CardFooter } from './CardFooter.vue'
+export { default as CardHeader } from './CardHeader.vue'
+export { default as CardTitle } from './CardTitle.vue'
diff --git a/components/ui/label/Label.vue b/components/ui/label/Label.vue
new file mode 100644
index 0000000..b4991db
--- /dev/null
+++ b/components/ui/label/Label.vue
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
diff --git a/components/ui/label/index.ts b/components/ui/label/index.ts
new file mode 100644
index 0000000..572c2f0
--- /dev/null
+++ b/components/ui/label/index.ts
@@ -0,0 +1 @@
+export { default as Label } from './Label.vue'
diff --git a/layouts/auth.vue b/layouts/default.vue
similarity index 55%
rename from layouts/auth.vue
rename to layouts/default.vue
index 6adee2b..fba6288 100644
--- a/layouts/auth.vue
+++ b/layouts/default.vue
@@ -1,3 +1,3 @@
-
+
\ No newline at end of file
diff --git a/layouts/landing-page.vue b/layouts/landing-page.vue
index 598dd9e..65de245 100644
--- a/layouts/landing-page.vue
+++ b/layouts/landing-page.vue
@@ -2,9 +2,17 @@
-
+
+
\ No newline at end of file
diff --git a/middleware/forgot-password-confirmation.ts b/middleware/forgot-password-confirmation.ts
new file mode 100644
index 0000000..ada9576
--- /dev/null
+++ b/middleware/forgot-password-confirmation.ts
@@ -0,0 +1,42 @@
+export default defineNuxtRouteMiddleware(async (to, from) => {
+ const token = to.params.token;
+ const forgotPasswordTokenStatus = useState<'unset' | 'invalid' | 'valid'>('forgot-password-token-status', () => 'unset')
+
+ if (!token) {
+ return navigateTo('/login');
+ }
+
+ try {
+ const isValid = await verifyToken(token as string);
+
+ if (!isValid) {
+ forgotPasswordTokenStatus.value = 'invalid'
+ } else {
+ forgotPasswordTokenStatus.value = 'valid'
+ }
+ } catch (error) {
+ forgotPasswordTokenStatus.value = 'invalid'
+ }
+
+ async function verifyToken(token: string) {
+ return new Promise((resolve) => setTimeout(() => {
+ if (token === 'success') {
+ return resolve(true)
+ } else {
+ return resolve(false)
+ }
+ }, 2000))
+ // const response = await fetch('https://your-backend.com/api/verify-token', {
+ // method: 'POST',
+ // headers: {
+ // 'Content-Type': 'application/json',
+ // },
+ // body: JSON.stringify({ token }),
+ // });
+
+ // const data = await response.json();
+
+ // return data.isValid;
+ }
+
+});
diff --git a/nuxt.config.ts b/nuxt.config.ts
index afc3378..a2a0147 100644
--- a/nuxt.config.ts
+++ b/nuxt.config.ts
@@ -1,5 +1,15 @@
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
+ nitro: {
+ routeRules: {
+ '/_nuxt/**': {
+ headers: {
+ 'cache-control': 'public, max-age=31536000, immutable',
+ 'content-encoding': 'br'
+ }
+ }
+ }
+ },
compatibilityDate: '2024-11-01',
devtools: { enabled: true },
modules: ['@nuxt/image', '@nuxt/ui', 'shadcn-nuxt'],
@@ -16,5 +26,9 @@ export default defineNuxtConfig({
* @default "./components/ui"
*/
componentDir: './components/ui'
+ },
+ image: {
+ format: ['webp'],
+ quality: 80,
}
})
\ No newline at end of file
diff --git a/package-lock.json b/package-lock.json
index 6ea59da..fc28c3f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -14,12 +14,13 @@
"clsx": "^2.1.1",
"lucide-vue-next": "^0.485.0",
"nuxt": "^3.16.1",
- "reka-ui": "^2.1.1",
+ "reka-ui": "^2.2.0",
"shadcn-nuxt": "^1.0.3",
"tailwind-merge": "^3.0.2",
"tailwindcss-animate": "^1.0.7",
"vue": "^3.5.13",
- "vue-router": "^4.5.0"
+ "vue-router": "^4.5.0",
+ "zod": "^3.24.2"
}
},
"node_modules/@alloc/quick-lru": {
@@ -8904,9 +8905,9 @@
}
},
"node_modules/reka-ui": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/reka-ui/-/reka-ui-2.1.1.tgz",
- "integrity": "sha512-awvpQ041LPXAvf2uRVFwedsyz9SwsuoWlRql1fg4XimUCxEI2GOfHo6FIdL44dSPb/eG/gWbdGhoGHLlbX5gPA==",
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/reka-ui/-/reka-ui-2.2.0.tgz",
+ "integrity": "sha512-eeRrLI4LwJ6dkdwks6KFNKGs0+beqZlHO3JMHen7THDTh+yJ5Z0KNwONmOhhV/0hZC2uJCEExgG60QPzGstkQg==",
"license": "MIT",
"dependencies": {
"@floating-ui/dom": "^1.6.13",
@@ -11544,6 +11545,15 @@
"engines": {
"node": ">= 14"
}
+ },
+ "node_modules/zod": {
+ "version": "3.24.2",
+ "resolved": "https://registry.npmjs.org/zod/-/zod-3.24.2.tgz",
+ "integrity": "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/colinhacks"
+ }
}
}
}
diff --git a/package.json b/package.json
index addb688..af5f9eb 100644
--- a/package.json
+++ b/package.json
@@ -17,11 +17,12 @@
"clsx": "^2.1.1",
"lucide-vue-next": "^0.485.0",
"nuxt": "^3.16.1",
- "reka-ui": "^2.1.1",
+ "reka-ui": "^2.2.0",
"shadcn-nuxt": "^1.0.3",
"tailwind-merge": "^3.0.2",
"tailwindcss-animate": "^1.0.7",
"vue": "^3.5.13",
- "vue-router": "^4.5.0"
+ "vue-router": "^4.5.0",
+ "zod": "^3.24.2"
}
}
diff --git a/pages/auth/activate-email.vue b/pages/auth/activate-email.vue
index a1d1757..e919578 100644
--- a/pages/auth/activate-email.vue
+++ b/pages/auth/activate-email.vue
@@ -1,5 +1,5 @@
-
+
diff --git a/pages/auth/change-password.vue b/pages/auth/change-password.vue
deleted file mode 100644
index a1d1757..0000000
--- a/pages/auth/change-password.vue
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
diff --git a/pages/auth/forgot-password.vue b/pages/auth/forgot-password.vue
deleted file mode 100644
index a1d1757..0000000
--- a/pages/auth/forgot-password.vue
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
diff --git a/pages/auth/forgot-password/[token].vue b/pages/auth/forgot-password/[token].vue
new file mode 100644
index 0000000..ba42135
--- /dev/null
+++ b/pages/auth/forgot-password/[token].vue
@@ -0,0 +1,89 @@
+
+
+
+
+
+
+
+ true
+ false
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Submit
+
+
+
+
+
+
+ Invalid or Expired Token
+
+
+
+ The password reset link you used is either invalid, expired, or has already been used.
+
+
+ Please request a new reset link to continue.
+
+
+
+ {
+ authSection = 'forgot-password',
+ navigateTo('/auth')
+ }">
+ Request New Link
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/pages/auth/index.vue b/pages/auth/index.vue
new file mode 100644
index 0000000..bff9b36
--- /dev/null
+++ b/pages/auth/index.vue
@@ -0,0 +1,9 @@
+
+
+
+
+
diff --git a/pages/auth/sign-in.vue b/pages/auth/sign-in.vue
deleted file mode 100644
index a1d1757..0000000
--- a/pages/auth/sign-in.vue
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
diff --git a/pages/auth/sign-up.vue b/pages/auth/sign-up.vue
deleted file mode 100644
index a1d1757..0000000
--- a/pages/auth/sign-up.vue
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
-
-
diff --git a/public/assets/icons/logo-text.png b/public/assets/icons/logo-text.png
new file mode 100644
index 0000000..c4dbd93
Binary files /dev/null and b/public/assets/icons/logo-text.png differ
diff --git a/public/assets/icons/logo.png b/public/assets/icons/logo.png
new file mode 100644
index 0000000..fb86fd1
Binary files /dev/null and b/public/assets/icons/logo.png differ