feat: Refactor icon components to support filled and outlined states
- Updated Add.vue to handle filled and outlined states, merging AddFilled.vue functionality. - Refactored Bell.vue and BellFilled.vue into a single component with filled state support. - Created Credit.vue for credit card icon with filled and outlined states. - Refactored Home.vue and HomeFilled.vue into a single component with filled state support. - Refactored Layout.vue and LayoutFilled.vue into a single component with filled state support. - Refactored Upload.vue and UploadFilled.vue into a single component with filled state support. - Refactored Video.vue and VideoFilled.vue into a single component with filled state support. - Enhanced index.tsx to include nonce for security in SSR. - Updated main.ts to handle application data from SSR. - Improved auth layout to include meta description for SEO. - Updated routes to include meta information for head management. - Simplified auth store methods for better readability and error handling. - Updated UnoCSS configuration to include class prefix for better utility management.
This commit is contained in:
2
components.d.ts
vendored
2
components.d.ts
vendored
@@ -19,6 +19,7 @@ declare module 'vue' {
|
||||
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']
|
||||
Home: typeof import('./src/components/icons/Home.vue')['default']
|
||||
HomeFilled: typeof import('./src/components/icons/HomeFilled.vue')['default']
|
||||
@@ -48,6 +49,7 @@ declare global {
|
||||
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 Home: typeof import('./src/components/icons/Home.vue')['default']
|
||||
const HomeFilled: typeof import('./src/components/icons/HomeFilled.vue')['default']
|
||||
|
||||
@@ -224,11 +224,11 @@ async function getCSRFToken() {
|
||||
const payload = await verify(token, JWT_SECRET) as any;
|
||||
const stored = csrfTokens.get(payload.sessionId);
|
||||
|
||||
if (!stored) {
|
||||
throw new Error('CSRF token not found');
|
||||
}
|
||||
// if (!stored) {
|
||||
// throw new Error('CSRF token not found');
|
||||
// }
|
||||
|
||||
return { csrfToken: stored.token };
|
||||
return { csrfToken: stored?.token || null };
|
||||
}
|
||||
|
||||
export const authMethods = {
|
||||
|
||||
@@ -6,7 +6,7 @@ import {
|
||||
import { tinyassert } from "@hiogawa/utils";
|
||||
import { MiddlewareHandler, type Context, type Next } from "hono";
|
||||
import { getContext } from "hono/context-storage";
|
||||
import { register } from "module";
|
||||
import { csrf } from 'hono/csrf'
|
||||
import { z } from "zod";
|
||||
import { authMethods } from "./auth";
|
||||
import { jwt } from "hono/jwt";
|
||||
@@ -320,7 +320,9 @@ export const rpcServer = async (c: Context, next: Next) => {
|
||||
if (c.req.path !== endpoint && !c.req.path.startsWith(endpoint + "/")) {
|
||||
return await next();
|
||||
}
|
||||
// c.get("redis").has(`auth_token:${}`)
|
||||
const cert = c.req.header()
|
||||
console.log("RPC Request Path:", c.req.raw.cf);
|
||||
// if (!cert) return c.text('Forbidden', 403)
|
||||
const handler = exposeTinyRpc({
|
||||
routes,
|
||||
adapter: httpServerAdapter({ endpoint }),
|
||||
|
||||
@@ -1,37 +1,36 @@
|
||||
<script lang="ts" setup>
|
||||
import Add from "@/components/icons/Add.vue";
|
||||
import AddFilled from "@/components/icons/AddFilled.vue";
|
||||
import Bell from "@/components/icons/Bell.vue";
|
||||
import BellFilled from "@/components/icons/BellFilled.vue";
|
||||
import Home from "@/components/icons/Home.vue";
|
||||
import HomeFilled from "@/components/icons/HomeFilled.vue";
|
||||
import Video from "@/components/icons/Video.vue";
|
||||
import VideoFilled from "@/components/icons/VideoFilled.vue";
|
||||
import Credit from "@/components/icons/Credit.vue";
|
||||
import Upload from "./icons/Upload.vue";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { useAuthStore } from "@/stores/auth";
|
||||
import { createStaticVNode } from "vue";
|
||||
import Upload from "./icons/Upload.vue";
|
||||
import UploadFilled from "./icons/UploadFilled.vue";
|
||||
|
||||
const auth = useAuthStore();
|
||||
|
||||
const className = ":uno: w-12 h-12 p-2 rounded-2xl hover:bg-primary/10 flex press-animated items-center justify-center";
|
||||
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(`<img class="h-8 w-8" src="/apple-touch-icon.png" alt="Logo" />`, 1);
|
||||
const links = [
|
||||
{ href: "/fdsfsd", label: "app", icon: homeHoist, exact: homeHoist, type: "btn" },
|
||||
{ href: "/", label: "Home", icon: Home, exact: HomeFilled, type: "a" },
|
||||
{ href: "/upload", label: "Upload", icon: Upload, exact: UploadFilled, type: "a" },
|
||||
{ href: "/video", label: "Video", icon: Video, exact: VideoFilled, type: "a" },
|
||||
{ href: "/add", label: "Add", icon: Add, exact: AddFilled, type: "a" },
|
||||
{ href: "/notification", label: "Notification", icon: Bell, exact: BellFilled, type: "a" },
|
||||
{ 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" },
|
||||
];
|
||||
</script>
|
||||
<template>
|
||||
<header class="fixed left-0 w-18 flex flex-col items-center pt-4 gap-6 z-41 max-h-screen h-screen border-r border-gray-200">
|
||||
<component :is="i.type === 'a' ? 'router-link' : 'div'" v-for="i in links" :key="i.label" v-bind="i.type === 'a' ? { to: i.href } : {}" v-tooltip="i.label" :class="cn(className, $route.path === i.href && 'bg-primary/10')">
|
||||
<component :is="$route.path === i.href ? i.exact : i.icon" />
|
||||
<header
|
||||
class=":uno: fixed left-0 w-18 flex flex-col items-center pt-4 gap-6 z-41 max-h-screen h-screen border-r border-gray-200 bg-white">
|
||||
<component :is="i.type === 'a' ? 'router-link' : 'div'" v-for="i in links" :key="i.label"
|
||||
v-bind="i.type === 'a' ? { to: i.href } : {}" v-tooltip="i.label"
|
||||
:class="cn(className, $route.path === i.href && 'bg-primary/15')">
|
||||
<component :is="i.icon" :filled="$route.path === i.href" />
|
||||
</component>
|
||||
<div class="w-12 h-12 rounded-2xl hover:bg-primary/10 flex">
|
||||
<div class="w-12 h-12 rounded-2xl hover:bg-primary/15 flex">
|
||||
<button class="h-[38px] w-[38px] rounded-full m-a ring-2 ring flex press-animated" @click="auth.logout()">
|
||||
<img class="h-8 w-8 rounded-full m-a ring-1 ring-white"
|
||||
src="https://picsum.photos/seed/user123/40/40.jpg" alt="User avatar" />
|
||||
|
||||
@@ -1,7 +1,19 @@
|
||||
<template>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="v-mid m-a" height="24" viewBox="-10 -226 468 468">
|
||||
<svg v-if="filled" aria-hidden="true" aria-label="" class="v-mid m-a" height="24" role="img" viewBox="0 0 468 468"
|
||||
width="24">
|
||||
<path
|
||||
d="M42 74v320c0 18 14 32 32 32h320c18 0 32-14 32-32V74c0-18-14-32-32-32H74c-18 0-32 14-32 32zm80 160c0-9 7-16 16-16h80v-80c0-9 7-16 16-16s16 7 16 16v80h80c9 0 16 7 16 16s-7 16-16 16h-80v80c0 9-7 16-16 16s-16-7-16-16v-80h-80c-9 0-16-7-16-16z"
|
||||
fill="#a6acb9" />
|
||||
<path
|
||||
d="M74 42c-18 0-32 14-32 32v320c0 18 14 32 32 32h320c18 0 32-14 32-32V74c0-18-14-32-32-32H74zM10 74c0-35 29-64 64-64h320c35 0 64 29 64 64v320c0 35-29 64-64 64H74c-35 0-64-29-64-64V74zm208 256v-80h-80c-9 0-16-7-16-16s7-16 16-16h80v-80c0-9 7-16 16-16s16 7 16 16v80h80c9 0 16 7 16 16s-7 16-16 16h-80v80c0 9-7 16-16 16s-16-7-16-16z"
|
||||
fill="#1e3050" />
|
||||
</svg>
|
||||
<svg v-else xmlns="http://www.w3.org/2000/svg" class="v-mid m-a" height="24" viewBox="-10 -226 468 468">
|
||||
<path
|
||||
d="M64-184c-18 0-32 14-32 32v320c0 18 14 32 32 32h320c18 0 32-14 32-32v-320c0-18-14-32-32-32H64zM0-152c0-35 29-64 64-64h320c35 0 64 29 64 64v320c0 35-29 64-64 64H64c-35 0-64-29-64-64v-320zm208 256V24h-80c-9 0-16-7-16-16s7-16 16-16h80v-80c0-9 7-16 16-16s16 7 16 16v80h80c9 0 16 7 16 16s-7 16-16 16h-80v80c0 9-7 16-16 16s-16-7-16-16z"
|
||||
fill="#1e3050" />
|
||||
</svg>
|
||||
</template>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
defineProps<{ class?: string, filled?: boolean }>();
|
||||
</script>
|
||||
@@ -1,10 +0,0 @@
|
||||
<template>
|
||||
<svg aria-hidden="true" aria-label="" class="v-mid m-a" height="24" role="img" viewBox="0 0 468 468" width="24">
|
||||
<path
|
||||
d="M42 74v320c0 18 14 32 32 32h320c18 0 32-14 32-32V74c0-18-14-32-32-32H74c-18 0-32 14-32 32zm80 160c0-9 7-16 16-16h80v-80c0-9 7-16 16-16s16 7 16 16v80h80c9 0 16 7 16 16s-7 16-16 16h-80v80c0 9-7 16-16 16s-16-7-16-16v-80h-80c-9 0-16-7-16-16z"
|
||||
fill="#a6acb9" />
|
||||
<path
|
||||
d="M74 42c-18 0-32 14-32 32v320c0 18 14 32 32 32h320c18 0 32-14 32-32V74c0-18-14-32-32-32H74zM10 74c0-35 29-64 64-64h320c35 0 64 29 64 64v320c0 35-29 64-64 64H74c-35 0-64-29-64-64V74zm208 256v-80h-80c-9 0-16-7-16-16s7-16 16-16h80v-80c0-9 7-16 16-16s16 7 16 16v80h80c9 0 16 7 16 16s-7 16-16 16h-80v80c0 9-7 16-16 16s-16-7-16-16z"
|
||||
fill="#1e3050" />
|
||||
</svg>
|
||||
</template>
|
||||
@@ -1,3 +1,18 @@
|
||||
<template>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="v-mid m-a" height="24" viewBox="-10 -258 468 532"><path d="M224-248c-13 0-24 11-24 24v10C119-203 56-133 56-48v15C56 4 46 41 27 74L5 111c-3 6-5 13-5 19 0 21 17 38 38 38h372c21 0 38-17 38-38 0-6-2-13-5-19l-22-37c-19-33-29-70-29-108v-14c0-85-63-155-144-166v-10c0-13-11-24-24-24zm168 368H56l12-22c24-40 36-85 36-131v-15c0-66 54-120 120-120s120 54 120 120v15c0 46 12 91 36 131l12 22zm-236 96c10 28 37 48 68 48s58-20 68-48H156z" fill="#1e3050"/></svg>
|
||||
</template>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" v-if="filled" height="24" width="24" viewBox="0 0 468 532">
|
||||
<path
|
||||
d="M66 378h337l-13-22c-24-40-36-85-36-131v-15c0-66-54-120-120-120s-120 54-120 120v15c0 46-12 91-35 131l-13 22z"
|
||||
fill="#a6acb9" />
|
||||
<path
|
||||
d="M234 10c-13 0-24 11-24 24v10C129 55 66 125 66 210v15c0 37-10 74-29 107l-22 37c-3 6-5 13-5 19 0 21 17 38 38 38h372c21 0 38-17 38-38 0-6-2-13-5-19l-22-37c-19-33-29-70-29-108v-14c0-85-63-155-144-166V34c0-13-11-24-24-24zm168 368H66l12-22c24-40 36-85 36-131v-15c0-66 54-120 120-120s120 54 120 120v15c0 46 12 91 36 131l12 22zm-236 96c10 28 37 48 68 48s58-20 68-48H166z"
|
||||
fill="#1e3050" />
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" v-else height="24" viewBox="-10 -258 468 532">
|
||||
<path
|
||||
d="M224-248c-13 0-24 11-24 24v10C119-203 56-133 56-48v15C56 4 46 41 27 74L5 111c-3 6-5 13-5 19 0 21 17 38 38 38h372c21 0 38-17 38-38 0-6-2-13-5-19l-22-37c-19-33-29-70-29-108v-14c0-85-63-155-144-166v-10c0-13-11-24-24-24zm168 368H56l12-22c24-40 36-85 36-131v-15c0-66 54-120 120-120s120 54 120 120v15c0 46 12 91 36 131l12 22zm-236 96c10 28 37 48 68 48s58-20 68-48H156z"
|
||||
fill="#1e3050" />
|
||||
</svg>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
defineProps<{ class?: string, filled?: boolean }>();
|
||||
</script>
|
||||
@@ -1,3 +0,0 @@
|
||||
<template>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="v-mid m-a" height="24" width="24" viewBox="0 0 468 532"><path d="M66 378h337l-13-22c-24-40-36-85-36-131v-15c0-66-54-120-120-120s-120 54-120 120v15c0 46-12 91-35 131l-13 22z" fill="#a6acb9"/><path d="M234 10c-13 0-24 11-24 24v10C129 55 66 125 66 210v15c0 37-10 74-29 107l-22 37c-3 6-5 13-5 19 0 21 17 38 38 38h372c21 0 38-17 38-38 0-6-2-13-5-19l-22-37c-19-33-29-70-29-108v-14c0-85-63-155-144-166V34c0-13-11-24-24-24zm168 368H66l12-22c24-40 36-85 36-131v-15c0-66 54-120 120-120s120 54 120 120v15c0 46 12 91 36 131l12 22zm-236 96c10 28 37 48 68 48s58-20 68-48H166z" fill="#1e3050"/></svg>
|
||||
</template>
|
||||
7
src/components/icons/Credit.vue
Normal file
7
src/components/icons/Credit.vue
Normal file
@@ -0,0 +1,7 @@
|
||||
<template>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" v-if="filled" width="24" viewBox="0 0 532 404"><path d="M10 74c0-35 29-64 64-64h384c35 0 64 29 64 64v32H10V74zm0 96h512v160c0 35-29 64-64 64H74c-35 0-64-29-64-64V170zm64 136c0 13 11 24 24 24h48c13 0 24-11 24-24s-11-24-24-24H98c-13 0-24 11-24 24zm144 0c0 13 11 24 24 24h64c13 0 24-11 24-24s-11-24-24-24h-64c-13 0-24 11-24 24z" fill="#a6acb9"/><path d="M10 106h512v64H10zm0 0z" fill="#1e3050"/></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" v-else width="24" viewBox="-10 -194 532 404"><path d="M448-136c9 0 16 7 16 16v32H48v-32c0-9 7-16 16-16h384zm16 112v160c0 9-7 16-16 16H64c-9 0-16-7-16-16V-24h416zM64-184c-35 0-64 29-64 64v256c0 35 29 64 64 64h384c35 0 64-29 64-64v-256c0-35-29-64-64-64H64zM80 96c0 13 11 24 24 24h48c13 0 24-11 24-24s-11-24-24-24h-48c-13 0-24 11-24 24zm144 0c0 13 11 24 24 24h64c13 0 24-11 24-24s-11-24-24-24h-64c-13 0-24 11-24 24z" fill="#1e3050"/></svg>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
defineProps<{ class?: string, filled?: boolean }>();
|
||||
</script>
|
||||
@@ -1,3 +1,18 @@
|
||||
<template>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="v-mid m-a" height="24" width="24" viewBox="-11 -259 535 533"><path d="M272-242c-9-8-23-8-32 0L8-34C-2-25-3-10 6 0s24 11 34 2l8-7v205c0 35 29 64 64 64h288c35 0 64-29 64-64V-5l8 7c10 9 25 8 34-2s8-25-2-34L272-242zM416-48v248c0 9-7 16-16 16H112c-9 0-16-7-16-16V-48l160-144L416-48z" fill="#1e3050"/></svg>
|
||||
</template>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" v-if="filled" class="v-mid m-a" height="24" width="24"
|
||||
viewBox="0 0 539 535">
|
||||
<path d="M61 281c2-1 4-3 6-5L269 89l202 187c2 2 4 4 6 5v180c0 35-29 64-64 64H125c-35 0-64-29-64-64V281z"
|
||||
fill="#a6acb9" />
|
||||
<path
|
||||
d="M247 22c13-12 32-12 44 0l224 208c13 12 13 32 1 45s-32 14-45 2L269 89 67 276c-13 12-33 12-45-1s-12-33 1-45L247 22z"
|
||||
fill="#1e3050" />
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" v-else class="v-mid m-a" height="24" width="24" viewBox="-11 -259 535 533">
|
||||
<path
|
||||
d="M272-242c-9-8-23-8-32 0L8-34C-2-25-3-10 6 0s24 11 34 2l8-7v205c0 35 29 64 64 64h288c35 0 64-29 64-64V-5l8 7c10 9 25 8 34-2s8-25-2-34L272-242zM416-48v248c0 9-7 16-16 16H112c-9 0-16-7-16-16V-48l160-144L416-48z"
|
||||
fill="#1e3050" />
|
||||
</svg>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
defineProps<{ class?: string, filled?: boolean }>();
|
||||
</script>
|
||||
@@ -1,3 +0,0 @@
|
||||
<template>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="v-mid m-a" height="24" width="24" viewBox="0 0 539 535"><path d="M61 281c2-1 4-3 6-5L269 89l202 187c2 2 4 4 6 5v180c0 35-29 64-64 64H125c-35 0-64-29-64-64V281z" fill="#a6acb9"/><path d="M247 22c13-12 32-12 44 0l224 208c13 12 13 32 1 45s-32 14-45 2L269 89 67 276c-13 12-33 12-45-1s-12-33 1-45L247 22z" fill="#1e3050"/></svg>
|
||||
</template>
|
||||
@@ -1,3 +1,19 @@
|
||||
<template>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="v-mid m-a" height="24" width="24" viewBox="-10 -226 468 468"><path d="M384-184c18 0 32 14 32 32v64H32v-64c0-18 14-32 32-32h320zM32 168V-56h96v256H64c-18 0-32-14-32-32zm128 32V-56h256v224c0 18-14 32-32 32H160zM64-216c-35 0-64 29-64 64v320c0 35 29 64 64 64h320c35 0 64-29 64-64v-320c0-35-29-64-64-64H64z" fill="#1e3050"/></svg>
|
||||
</template>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" v-if="filled" class="v-mid m-a" height="24" width="24"
|
||||
viewBox="0 0 468 468">
|
||||
<path
|
||||
d="M42 74v64h384V74c0-18-14-32-32-32H74c-18 0-32 14-32 32zm0 96v224c0 18 14 32 32 32h64V170H42zm128 0v256h224c18 0 32-14 32-32V170H170z"
|
||||
fill="#a6acb9" />
|
||||
<path
|
||||
d="M394 42c18 0 32 14 32 32v64H42V74c0-18 14-32 32-32h320zM42 394V170h96v256H74c-18 0-32-14-32-32zm128 32V170h256v224c0 18-14 32-32 32H170zM74 10c-35 0-64 29-64 64v320c0 35 29 64 64 64h320c35 0 64-29 64-64V74c0-35-29-64-64-64H74z"
|
||||
fill="#1e3050" />
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" v-else class="v-mid m-a" height="24" width="24" viewBox="-10 -226 468 468">
|
||||
<path
|
||||
d="M384-184c18 0 32 14 32 32v64H32v-64c0-18 14-32 32-32h320zM32 168V-56h96v256H64c-18 0-32-14-32-32zm128 32V-56h256v224c0 18-14 32-32 32H160zM64-216c-35 0-64 29-64 64v320c0 35 29 64 64 64h320c35 0 64-29 64-64v-320c0-35-29-64-64-64H64z"
|
||||
fill="#1e3050" />
|
||||
</svg>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
defineProps<{ class?: string, filled?: boolean }>();
|
||||
</script>
|
||||
@@ -1,3 +0,0 @@
|
||||
<template>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" class="v-mid m-a" height="24" width="24" viewBox="0 0 468 468"><path d="M42 74v64h384V74c0-18-14-32-32-32H74c-18 0-32 14-32 32zm0 96v224c0 18 14 32 32 32h64V170H42zm128 0v256h224c18 0 32-14 32-32V170H170z" fill="#a6acb9"/><path d="M394 42c18 0 32 14 32 32v64H42V74c0-18 14-32 32-32h320zM42 394V170h96v256H74c-18 0-32-14-32-32zm128 32V170h256v224c0 18-14 32-32 32H170zM74 10c-35 0-64 29-64 64v320c0 35 29 64 64 64h320c35 0 64-29 64-64V74c0-35-29-64-64-64H74z" fill="#1e3050"/></svg>
|
||||
</template>
|
||||
@@ -1,3 +1,18 @@
|
||||
<template>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="28" viewBox="-10 -226 596 468"><path d="M240-216c-88 0-160 72-160 160 0 5 0 10 1 15C33-18 0 31 0 88c0 80 65 144 144 144h304c71 0 128-57 128-128 0-50-28-93-70-114 4-12 6-25 6-38 0-66-54-120-120-120-11 0-23 2-33 5-30-33-72-53-119-53zM128-56c0-62 50-112 112-112 38 0 71 19 91 47 7 10 20 13 30 8 9-4 20-7 31-7 40 0 72 32 72 72 0 14-4 27-11 38-4 7-5 15-2 22s9 13 16 14c35 9 61 41 61 78 0 44-36 80-80 80H144c-53 0-96-43-96-96 0-43 28-79 67-91 11-4 18-16 16-29-2-7-3-16-3-24zm177 7c-9-9-25-9-34 0l-64 64c-9 9-9 25 0 34 10 9 25 9 34 0l23-23v86c0 13 11 24 24 24s24-11 24-24V26l23 23c9 9 25 9 34 0s9-25 0-34l-64-64z" fill="#1e3050"/></svg>
|
||||
</template>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" v-if="filled" width="28" viewBox="0 0 596 468">
|
||||
<path
|
||||
d="M10 314c0-63 41-117 98-136-1-8-2-16-2-24 0-79 65-144 144-144 55 0 104 31 128 77 14-8 30-13 48-13 53 0 96 43 96 96 0 16-4 31-10 44 44 20 74 64 74 116 0 71-57 128-128 128H154c-79 0-144-64-144-144zm199-73c-9 9-9 25 0 34s25 9 34 0l31-31v102c0 13 11 24 24 24s24-11 24-24V244l31 31c9 9 25 9 34 0s9-25 0-34l-72-72c-10-9-25-9-34 0l-72 72z"
|
||||
fill="#a6acb9" />
|
||||
<path
|
||||
d="M281 169c9-9 25-9 34 0l72 72c9 9 9 25 0 34s-25 9-34 0l-31-31v102c0 13-11 24-24 24s-24-11-24-24V244l-31 31c-9 9-25 9-34 0s-9-25 0-34l72-72z"
|
||||
fill="#1e3050" />
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" v-else width="28" viewBox="-10 -226 596 468">
|
||||
<path
|
||||
d="M240-216c-88 0-160 72-160 160 0 5 0 10 1 15C33-18 0 31 0 88c0 80 65 144 144 144h304c71 0 128-57 128-128 0-50-28-93-70-114 4-12 6-25 6-38 0-66-54-120-120-120-11 0-23 2-33 5-30-33-72-53-119-53zM128-56c0-62 50-112 112-112 38 0 71 19 91 47 7 10 20 13 30 8 9-4 20-7 31-7 40 0 72 32 72 72 0 14-4 27-11 38-4 7-5 15-2 22s9 13 16 14c35 9 61 41 61 78 0 44-36 80-80 80H144c-53 0-96-43-96-96 0-43 28-79 67-91 11-4 18-16 16-29-2-7-3-16-3-24zm177 7c-9-9-25-9-34 0l-64 64c-9 9-9 25 0 34 10 9 25 9 34 0l23-23v86c0 13 11 24 24 24s24-11 24-24V26l23 23c9 9 25 9 34 0s9-25 0-34l-64-64z"
|
||||
fill="#1e3050" />
|
||||
</svg>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
defineProps<{ class?: string, filled?: boolean }>();
|
||||
</script>
|
||||
@@ -1,3 +0,0 @@
|
||||
<template>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="28" viewBox="0 0 596 468"><path d="M10 314c0-63 41-117 98-136-1-8-2-16-2-24 0-79 65-144 144-144 55 0 104 31 128 77 14-8 30-13 48-13 53 0 96 43 96 96 0 16-4 31-10 44 44 20 74 64 74 116 0 71-57 128-128 128H154c-79 0-144-64-144-144zm199-73c-9 9-9 25 0 34s25 9 34 0l31-31v102c0 13 11 24 24 24s24-11 24-24V244l31 31c9 9 25 9 34 0s9-25 0-34l-72-72c-10-9-25-9-34 0l-72 72z" fill="#a6acb9"/><path d="M281 169c9-9 25-9 34 0l72 72c9 9 9 25 0 34s-25 9-34 0l-31-31v102c0 13-11 24-24 24s-24-11-24-24V244l-31 31c-9 9-25 9-34 0s-9-25 0-34l72-72z" fill="#1e3050"/></svg>
|
||||
</template>
|
||||
@@ -1,3 +1,16 @@
|
||||
<template>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" viewBox="22 -194 564 404"><path d="M96-136c-9 0-16 7-16 16v256c0 9 7 16 16 16h256c9 0 16-7 16-16v-256c0-9-7-16-16-16H96zm-64 16c0-35 29-64 64-64h256c35 0 64 29 64 64v256c0 35-29 64-64 64H96c-35 0-64-29-64-64v-256zm506-11c4-3 9-5 14-5 13 0 24 11 24 24v240c0 13-11 24-24 24-5 0-10-2-14-5l-74-55V32l64 48V-64l-64 48v-60l74-55z" fill="#1e3050"/></svg>
|
||||
</template>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" v-if="filled" width="24" viewBox="0 0 532 404">
|
||||
<path d="M10 74v256c0 35 29 64 64 64h256c35 0 64-29 64-64V74c0-35-29-64-64-64H74c-35 0-64 29-64 64z"
|
||||
fill="#a6acb9" />
|
||||
<path d="M394 135v134l90 72c4 3 9 5 14 5 13 0 24-11 24-24V82c0-13-11-24-24-24-5 0-10 2-14 5l-90 72z"
|
||||
fill="#1e3050" />
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" v-else width="24" viewBox="22 -194 564 404">
|
||||
<path
|
||||
d="M96-136c-9 0-16 7-16 16v256c0 9 7 16 16 16h256c9 0 16-7 16-16v-256c0-9-7-16-16-16H96zm-64 16c0-35 29-64 64-64h256c35 0 64 29 64 64v256c0 35-29 64-64 64H96c-35 0-64-29-64-64v-256zm506-11c4-3 9-5 14-5 13 0 24 11 24 24v240c0 13-11 24-24 24-5 0-10-2-14-5l-74-55V32l64 48V-64l-64 48v-60l74-55z"
|
||||
fill="#1e3050" />
|
||||
</svg>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
defineProps<{ class?: string, filled?: boolean }>();
|
||||
</script>
|
||||
@@ -1,3 +0,0 @@
|
||||
<template>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="24" viewBox="0 0 532 404"><path d="M10 74v256c0 35 29 64 64 64h256c35 0 64-29 64-64V74c0-35-29-64-64-64H74c-35 0-64 29-64 64z" fill="#a6acb9"/><path d="M394 135v134l90 72c4 3 9 5 14 5 13 0 24-11 24-24V82c0-13-11-24-24-24-5 0-10 2-14 5l-90 72z" fill="#1e3050"/></svg>
|
||||
</template>
|
||||
@@ -30,6 +30,7 @@ app.get("/.well-known/*", (c) => {
|
||||
return c.json({ ok: true });
|
||||
});
|
||||
app.get("*", async (c) => {
|
||||
const nonce = crypto.randomUUID();
|
||||
const url = new URL(c.req.url);
|
||||
const { app, router, head, pinia, bodyClass } = createApp();
|
||||
app.provide("honoContext", c);
|
||||
@@ -59,8 +60,8 @@ app.get("*", async (c) => {
|
||||
await Promise.all(styleTags.filter(tag => usedStyles.has(tag.name.replace(/-(variables|style)$/, ""))).map(tag => stream.write(`<style type="text/css" data-primevue-style-id="${tag.name}">${tag.value}</style>`)));
|
||||
await stream.write(`</head><body class='${bodyClass}'>`);
|
||||
await stream.pipe(appStream);
|
||||
await stream.write(`<script>window.__SSR_STATE__ = JSON.parse(${htmlEscape(JSON.stringify(JSON.stringify(ctx)))});</script>`);
|
||||
await stream.write(`<script>window.__PINIA_STATE__ = JSON.parse(${htmlEscape(JSON.stringify(JSON.stringify(pinia.state.value)))});</script>`);
|
||||
Object.assign(ctx, { $p: pinia.state.value });
|
||||
await stream.write(`<script type="application/json" data-ssr="true" id="__APP_DATA__" nonce="${nonce}">${htmlEscape((JSON.stringify(ctx)))}</script>`);
|
||||
await stream.write("</body></html>");
|
||||
});
|
||||
})
|
||||
|
||||
10
src/main.ts
10
src/main.ts
@@ -24,6 +24,7 @@ export function createApp() {
|
||||
preset: Aura,
|
||||
options: {
|
||||
darkModeSelector: '.my-app-dark',
|
||||
cssLayer: false,
|
||||
// cssLayer: {
|
||||
// name: 'primevue',
|
||||
// order: 'theme, base, primevue'
|
||||
@@ -32,15 +33,18 @@ export function createApp() {
|
||||
}
|
||||
});
|
||||
app.use(ToastService);
|
||||
app.directive('no-hydrate', {
|
||||
app.directive('nh', {
|
||||
created(el) {
|
||||
el.__v_skip = true;
|
||||
}
|
||||
});
|
||||
app.directive("tooltip", Tooltip)
|
||||
if (!import.meta.env.SSR) {
|
||||
if ((window as any).__PINIA_STATE__ ) {
|
||||
pinia.state.value = (window as any).__PINIA_STATE__;
|
||||
Object.entries(JSON.parse(document.getElementById("__APP_DATA__")?.innerText || "{}")).forEach(([key, value]) => {
|
||||
(window as any)[key] = value;
|
||||
});
|
||||
if ((window as any).$p ) {
|
||||
pinia.state.value = (window as any).$p;
|
||||
}
|
||||
}
|
||||
app.use(pinia);
|
||||
|
||||
@@ -11,7 +11,10 @@
|
||||
{{ content[route.name as keyof typeof content]?.subtitle || '' }}
|
||||
</p>
|
||||
<vue-head :input="{
|
||||
title: content[route.name as keyof typeof content]?.headTitle || 'Authentication'
|
||||
title: content[route.name as keyof typeof content]?.headTitle || 'Authentication',
|
||||
meta: [
|
||||
{ name: 'description', content: content[route.name as keyof typeof content]?.subtitle || '' }
|
||||
]
|
||||
}" />
|
||||
</div>
|
||||
<router-view />
|
||||
|
||||
@@ -67,33 +67,57 @@ const routes: RouteData[] = [
|
||||
path: "",
|
||||
name: "overview",
|
||||
component: () => import("./add/Add.vue"),
|
||||
beforeEnter: (to, from, next) => {
|
||||
const head = inject(headSymbol);
|
||||
(head as any).push({
|
||||
meta: {
|
||||
head: {
|
||||
title: 'Overview - Holistream',
|
||||
});
|
||||
next();
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
path: "upload",
|
||||
name: "upload",
|
||||
component: () => import("./add/Add.vue"),
|
||||
meta: {
|
||||
head: {
|
||||
title: 'Upload - Holistream',
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
path: "video",
|
||||
name: "video",
|
||||
component: () => import("./add/Add.vue"),
|
||||
meta: {
|
||||
head: {
|
||||
title: 'Videos - Holistream',
|
||||
meta: [
|
||||
{ name: 'description', content: 'Manage your video content.' },
|
||||
],
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
path: "add",
|
||||
name: "add",
|
||||
path: "plans",
|
||||
name: "plans",
|
||||
component: () => import("./add/Add.vue"),
|
||||
meta: {
|
||||
head: {
|
||||
title: 'Plans & Billing',
|
||||
meta: [
|
||||
{ name: 'description', content: 'Manage your plans and billing information.' },
|
||||
],
|
||||
},
|
||||
}
|
||||
},
|
||||
{
|
||||
path: "notification",
|
||||
name: "notification",
|
||||
component: () => import("./add/Add.vue"),
|
||||
meta: {
|
||||
head: {
|
||||
title: 'Notification - Holistream',
|
||||
},
|
||||
}
|
||||
},
|
||||
],
|
||||
},
|
||||
@@ -115,6 +139,8 @@ const router = createRouter({
|
||||
|
||||
router.beforeEach((to, from, next) => {
|
||||
const auth = useAuthStore();
|
||||
const head = inject(headSymbol);
|
||||
(head as any).push(to.meta.head || {});
|
||||
if (to.matched.some((record) => record.meta.requiresAuth)) {
|
||||
if (!auth.user) {
|
||||
next({ name: "login" });
|
||||
|
||||
@@ -55,47 +55,30 @@ export const useAuthStore = defineStore('auth', () => {
|
||||
}).finally(() => {
|
||||
loading.value = false;
|
||||
});
|
||||
// try {
|
||||
// const response = await client.login(username, password);
|
||||
// user.value = response.user;
|
||||
// csrfToken.value = response.csrfToken;
|
||||
// router.push('/');
|
||||
// } catch (e: any) {
|
||||
// // console.log(JSON.parse(e.message))
|
||||
// // error.value = e.message || 'Login failed';
|
||||
// error.value = 'Login failed';
|
||||
// throw e;
|
||||
// } finally {
|
||||
// loading.value = false;
|
||||
// }
|
||||
}
|
||||
|
||||
async function register(username: string, email: string, password: string) {
|
||||
loading.value = true;
|
||||
error.value = null;
|
||||
try {
|
||||
const response = await client.register({ username, email, password });
|
||||
return client.register({ username, email, password }).then((response) => {
|
||||
user.value = response.user;
|
||||
csrfToken.value = response.csrfToken;
|
||||
router.push('/');
|
||||
} catch (e: any) {
|
||||
}).catch((e: any) => {
|
||||
// error.value = e.message || 'Registration failed';
|
||||
error.value = 'Registration failed';
|
||||
throw e;
|
||||
} finally {
|
||||
}).finally(() => {
|
||||
loading.value = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async function logout() {
|
||||
try {
|
||||
await client.logout();
|
||||
} catch (e) {
|
||||
// Ignore errors on logout
|
||||
}
|
||||
user.value = null;
|
||||
csrfToken.value = null;
|
||||
router.push('/');
|
||||
return client.logout().then(() => {
|
||||
user.value = null;
|
||||
csrfToken.value = null;
|
||||
router.push('/');
|
||||
})
|
||||
}
|
||||
|
||||
return { user, loading, error, csrfToken, initialized, init, login, register, logout, $reset: () => {
|
||||
|
||||
@@ -93,7 +93,9 @@ export default defineConfig({
|
||||
],
|
||||
["animate-loadingBar", ["animation", "loadingBar 1.5s linear infinite"]],
|
||||
],
|
||||
transformers: [transformerVariantGroup(), transformerCompileClass()],
|
||||
transformers: [transformerVariantGroup(), transformerCompileClass({
|
||||
classPrefix: "_",
|
||||
})],
|
||||
preflights: [
|
||||
{
|
||||
getCSS: (context) => {
|
||||
|
||||
Reference in New Issue
Block a user