diff --git a/components.d.ts b/components.d.ts index 1956eda..efee8df 100644 --- a/components.d.ts +++ b/components.d.ts @@ -13,30 +13,32 @@ export {} declare module 'vue' { export interface GlobalComponents { Add: typeof import('./src/components/icons/Add.vue')['default'] - AddFilled: typeof import('./src/components/icons/AddFilled.vue')['default'] Bell: typeof import('./src/components/icons/Bell.vue')['default'] - BellFilled: typeof import('./src/components/icons/BellFilled.vue')['default'] Button: typeof import('primevue/button')['default'] Checkbox: typeof import('primevue/checkbox')['default'] CheckIcon: typeof import('./src/components/icons/CheckIcon.vue')['default'] Credit: typeof import('./src/components/icons/Credit.vue')['default'] DashboardLayout: typeof import('./src/components/DashboardLayout.vue')['default'] + DashboardSidebar: typeof import('./src/components/dashboard/DashboardSidebar.vue')['default'] + DashboardTopbar: typeof import('./src/components/dashboard/DashboardTopbar.vue')['default'] + EmptyState: typeof import('./src/components/dashboard/EmptyState.vue')['default'] Home: typeof import('./src/components/icons/Home.vue')['default'] - HomeFilled: typeof import('./src/components/icons/HomeFilled.vue')['default'] + IconField: typeof import('primevue/iconfield')['default'] + InputIcon: typeof import('primevue/inputicon')['default'] InputText: typeof import('primevue/inputtext')['default'] Layout: typeof import('./src/components/icons/Layout.vue')['default'] - LayoutFilled: typeof import('./src/components/icons/LayoutFilled.vue')['default'] Message: typeof import('primevue/message')['default'] + OverlayPanel: typeof import('primevue/overlaypanel')['default'] + PageHeader: typeof import('./src/components/dashboard/PageHeader.vue')['default'] Password: typeof import('primevue/password')['default'] RootLayout: typeof import('./src/components/RootLayout.vue')['default'] RouterLink: typeof import('vue-router')['RouterLink'] RouterView: typeof import('vue-router')['RouterView'] + StatsCard: typeof import('./src/components/dashboard/StatsCard.vue')['default'] TestIcon: typeof import('./src/components/icons/TestIcon.vue')['default'] Toast: typeof import('primevue/toast')['default'] Upload: typeof import('./src/components/icons/Upload.vue')['default'] - UploadFilled: typeof import('./src/components/icons/UploadFilled.vue')['default'] Video: typeof import('./src/components/icons/Video.vue')['default'] - VideoFilled: typeof import('./src/components/icons/VideoFilled.vue')['default'] VueHead: typeof import('./src/components/VueHead.tsx')['default'] } } @@ -44,29 +46,31 @@ declare module 'vue' { // For TSX support declare global { const Add: typeof import('./src/components/icons/Add.vue')['default'] - const AddFilled: typeof import('./src/components/icons/AddFilled.vue')['default'] const Bell: typeof import('./src/components/icons/Bell.vue')['default'] - const BellFilled: typeof import('./src/components/icons/BellFilled.vue')['default'] const Button: typeof import('primevue/button')['default'] const Checkbox: typeof import('primevue/checkbox')['default'] const CheckIcon: typeof import('./src/components/icons/CheckIcon.vue')['default'] const Credit: typeof import('./src/components/icons/Credit.vue')['default'] const DashboardLayout: typeof import('./src/components/DashboardLayout.vue')['default'] + const DashboardSidebar: typeof import('./src/components/dashboard/DashboardSidebar.vue')['default'] + const DashboardTopbar: typeof import('./src/components/dashboard/DashboardTopbar.vue')['default'] + const EmptyState: typeof import('./src/components/dashboard/EmptyState.vue')['default'] const Home: typeof import('./src/components/icons/Home.vue')['default'] - const HomeFilled: typeof import('./src/components/icons/HomeFilled.vue')['default'] + const IconField: typeof import('primevue/iconfield')['default'] + const InputIcon: typeof import('primevue/inputicon')['default'] const InputText: typeof import('primevue/inputtext')['default'] const Layout: typeof import('./src/components/icons/Layout.vue')['default'] - const LayoutFilled: typeof import('./src/components/icons/LayoutFilled.vue')['default'] const Message: typeof import('primevue/message')['default'] + const OverlayPanel: typeof import('primevue/overlaypanel')['default'] + const PageHeader: typeof import('./src/components/dashboard/PageHeader.vue')['default'] const Password: typeof import('primevue/password')['default'] const RootLayout: typeof import('./src/components/RootLayout.vue')['default'] const RouterLink: typeof import('vue-router')['RouterLink'] const RouterView: typeof import('vue-router')['RouterView'] + const StatsCard: typeof import('./src/components/dashboard/StatsCard.vue')['default'] const TestIcon: typeof import('./src/components/icons/TestIcon.vue')['default'] const Toast: typeof import('primevue/toast')['default'] const Upload: typeof import('./src/components/icons/Upload.vue')['default'] - const UploadFilled: typeof import('./src/components/icons/UploadFilled.vue')['default'] const Video: typeof import('./src/components/icons/Video.vue')['default'] - const VideoFilled: typeof import('./src/components/icons/VideoFilled.vue')['default'] const VueHead: typeof import('./src/components/VueHead.tsx')['default'] } \ No newline at end of file diff --git a/src/api/httpClientAdapter.server.ts b/src/api/httpClientAdapter.server.ts index fa2d829..6152e73 100644 --- a/src/api/httpClientAdapter.server.ts +++ b/src/api/httpClientAdapter.server.ts @@ -2,18 +2,19 @@ import { tryGetContext } from "hono/context-storage"; export const customFetch = async (url: string, options: RequestInit) => { options.credentials = "include"; - if (!options.headers) { - options.headers = {}; - } if (import.meta.env.SSR) { const c = tryGetContext(); if (!c) { throw new Error("Hono context not found in SSR"); } - // Object.entries(c.req.header()).forEach(([k, v]) => { - // Object.assign(options.headers!, { [k]: v }); - // }); - return await c.get("fetch")(url, options); + Object.assign(options, { + headers: c.req.header() + }); + const res = await fetch(url, options); + res.headers.forEach((value, key) => { + c.header(key, value); + }); + return res; } return fetch(url, options); } \ No newline at end of file diff --git a/src/components/DashboardLayout.vue b/src/components/DashboardLayout.vue index 194bff9..38c2650 100644 --- a/src/components/DashboardLayout.vue +++ b/src/components/DashboardLayout.vue @@ -13,13 +13,18 @@ const auth = useAuthStore(); const className = ":uno: w-12 h-12 p-2 rounded-2xl hover:bg-primary/15 flex press-animated items-center justify-center"; const homeHoist = createStaticVNode(`Logo`, 1); +const profileHoist = createStaticVNode(`
+ User avatar +
`, 1); const links = [ - { href: "/fdsfsd", label: "app", icon: homeHoist, type: "btn" }, - { href: "/", label: "Home", icon: Home, type: "a" }, - { href: "/upload", label: "Upload", icon: Upload, type: "a" }, - { href: "/video", label: "Video", icon: Video, type: "a" }, - { href: "/plans", label: "Plans", icon: Credit, type: "a" }, - { href: "/notification", label: "Notification", icon: Bell, type: "a" }, + { href: "/fdsfsd", label: "app", icon: homeHoist, type: "btn", className }, + { href: "/", label: "Overview", icon: Home, type: "a", className }, + { href: "/upload", label: "Upload", icon: Upload, type: "a", className }, + { href: "/video", label: "Video", icon: Video, type: "a", className }, + { href: "/plans", label: "Plans", icon: Credit, type: "a", className }, + { href: "/notification", label: "Notification", icon: Bell, type: "a", className }, + { href: "/profile", label: "Profile", icon: profileHoist, type: "a", className: 'w-12 h-12 rounded-2xl hover:bg-primary/15 flex' }, ]; diff --git a/src/routes/auth/forgot.vue b/src/routes/auth/forgot.vue index 3c445e8..447efcf 100644 --- a/src/routes/auth/forgot.vue +++ b/src/routes/auth/forgot.vue @@ -39,7 +39,7 @@ import { z } from 'zod'; import { useAuthStore } from '@/stores/auth'; import { useToast } from "primevue/usetoast"; -import { forgotPassword } from '@/lib/firebase'; +import { client } from '@/api/client'; const auth = useAuthStore(); const toast = useToast(); @@ -56,11 +56,18 @@ const resolver = zodResolver( const onFormSubmit = ({ valid, values }: FormSubmitEvent) => { if (valid) { - forgotPassword(values.email).then(() => { - toast.add({ severity: 'success', summary: 'Success', detail: 'Reset link sent', life: 3000 }); - }).catch(() => { - toast.add({ severity: 'error', summary: 'Error', detail: auth.error, life: 3000 }); - }); + client.auth.forgotPasswordCreate({ email: values.email }) + .then(() => { + toast.add({ severity: 'success', summary: 'Success', detail: 'Reset link sent', life: 3000 }); + }) + .catch((error) => { + toast.add({ severity: 'error', summary: 'Error', detail: error.message || 'An error occurred', life: 3000 }); + }); + // forgotPassword(values.email).then(() => { + // toast.add({ severity: 'success', summary: 'Success', detail: 'Reset link sent', life: 3000 }); + // }).catch(() => { + // toast.add({ severity: 'error', summary: 'Error', detail: auth.error, life: 3000 }); + // }); } }; \ No newline at end of file diff --git a/src/routes/index.ts b/src/routes/index.ts index 68e95f6..a8a36b3 100644 --- a/src/routes/index.ts +++ b/src/routes/index.ts @@ -112,13 +112,23 @@ const routes: RouteData[] = [ { path: "notification", name: "notification", - component: () => import("./add/Add.vue"), + component: () => import("./add/Add.vue"), // TODO: create notification page meta: { head: { title: 'Notification - Holistream', }, } }, + { + path: "profile", + name: "profile", + component: () => import("./add/Add.vue"), // TODO: create profile page + meta: { + head: { + title: 'Profile - Holistream', + }, + } + }, ], }, { diff --git a/src/routes/video/Videos.vue b/src/routes/video/Videos.vue index d636341..6f7e055 100644 --- a/src/routes/video/Videos.vue +++ b/src/routes/video/Videos.vue @@ -1,73 +1,61 @@ - - + + diff --git a/src/stores/auth.ts b/src/stores/auth.ts index 79c50f1..381ad72 100644 --- a/src/stores/auth.ts +++ b/src/stores/auth.ts @@ -12,23 +12,30 @@ export const useAuthStore = defineStore('auth', () => { // Initial check for session could go here if there was a /me endpoint or token check async function init() { - // if (initialized.value) return; - const response = await client.request< - ResponseResponse & { - data?: ModelUser; - }, - ResponseResponse - >({ + if (initialized.value) return; + await client.request({ path: '/me', - method: 'GET' - }); - if (response.ok) { - // user.value = response.data?.data; - if (response.data?.data) { - user.value = response.data.data; + method: 'GET', + format: "json", + }).then(r => r.json()).then(r => { + if (r.data) { + user.value = r.data as ModelUser; } + }).catch(() => {}).finally(() => { initialized.value = true; - } + }); + // client.request< + // ResponseResponse & { + // data?: ModelUser; + // }, + // ResponseResponse + // >({ + // path: '/me', + // method: 'GET' + // }).then(console.log) + // .finally(() => { + // initialized.value = true; + // }); } async function login(username: string, password: string) {