add mock video
This commit is contained in:
@@ -1,59 +1,13 @@
|
||||
<script lang="ts" setup>
|
||||
import Add from "@/components/icons/Add.vue";
|
||||
import Bell from "@/components/icons/Bell.vue";
|
||||
import Home from "@/components/icons/Home.vue";
|
||||
import Video from "@/components/icons/Video.vue";
|
||||
import Credit from "@/components/icons/Credit.vue";
|
||||
import Upload from "./icons/Upload.vue";
|
||||
import NotificationDrawer from "./NotificationDrawer.vue";
|
||||
import DashboardNav from "./DashboardNav.vue";
|
||||
import GlobalUploadIndicator from "./GlobalUploadIndicator.vue";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { createStaticVNode, ref } from "vue";
|
||||
|
||||
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 profileHoist = createStaticVNode(`<div class="h-[38px] w-[38px] rounded-full m-a ring-2 ring flex press-animated">
|
||||
<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" />
|
||||
</div>`, 1);
|
||||
const notificationPopover = ref<InstanceType<typeof NotificationDrawer>>();
|
||||
const isNotificationOpen = ref(false);
|
||||
|
||||
const handleNotificationClick = (event: Event) => {
|
||||
notificationPopover.value?.toggle(event);
|
||||
};
|
||||
const links = [
|
||||
{ href: "/#home", 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: "/payments-and-plans", label: "Payments & Plans", icon: Credit, type: "a", className },
|
||||
{ href: "/notification", label: "Notification", icon: Bell, type: "btn", className, action: handleNotificationClick, isActive: isNotificationOpen },
|
||||
{ href: "/profile", label: "Profile", icon: profileHoist, type: "a", className: 'w-12 h-12 rounded-2xl hover:bg-primary/15 flex' },
|
||||
];
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<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">
|
||||
<template v-for="i in links" :key="i.label">
|
||||
<component :name="i.label" :is="i.type === 'a' ? 'router-link' : 'div'"
|
||||
v-bind="i.type === 'a' ? { to: i.href } : {}" v-tooltip="i.label" @click="i.action && i.action($event)"
|
||||
:class="cn(i.className, ($route.path === i.href || i.isActive?.value) && 'bg-primary/15')">
|
||||
<component :is="i.icon" class="w-6 h-6" :filled="$route.path === i.href || i.isActive?.value" />
|
||||
</component>
|
||||
</template>
|
||||
<ClientOnly>
|
||||
<NotificationDrawer ref="notificationPopover" @change="(val) => isNotificationOpen = val" />
|
||||
</ClientOnly>
|
||||
</header>
|
||||
|
||||
|
||||
|
||||
<main class="flex flex-1 overflow-hidden md:ps-18">
|
||||
<div class=":uno: flex-1 overflow-auto p-4 bg-[#FAF8F8] rounded-lg md:(mr-2 mb-2) min-h-[calc(100vh-8rem)]">
|
||||
<DashboardNav />
|
||||
<main class="flex flex-1 flex-col transition-all duration-300 ease-in-out bg-page md:ps-18">
|
||||
<div class=":uno: flex-1 overflow-auto p-4 bg-page rounded-lg md:(mr-2 mb-2) min-h-[calc(100vh-8rem)]">
|
||||
<router-view v-slot="{ Component }">
|
||||
<Transition enter-active-class="transition-all duration-300 ease-in-out"
|
||||
enter-from-class="opacity-0 transform translate-y-4"
|
||||
|
||||
56
src/components/DashboardNav.vue
Normal file
56
src/components/DashboardNav.vue
Normal file
@@ -0,0 +1,56 @@
|
||||
<script lang="ts" setup>
|
||||
import Bell from "@/components/icons/Bell.vue";
|
||||
import Home from "@/components/icons/Home.vue";
|
||||
import Video from "@/components/icons/Video.vue";
|
||||
import Credit from "@/components/icons/Credit.vue";
|
||||
import Upload from "@/components/icons/Upload.vue";
|
||||
import NotificationDrawer from "./NotificationDrawer.vue";
|
||||
import { cn } from "@/lib/utils";
|
||||
import { createStaticVNode, ref } from "vue";
|
||||
|
||||
const className = ":uno: w-12 h-12 p-2 rounded-2xl hover:bg-primary/15 flex press-animated items-center justify-center shrink-0";
|
||||
const homeHoist = createStaticVNode(`<img class="h-8 w-8" src="/apple-touch-icon.png" alt="Logo" />`, 1);
|
||||
const profileHoist = createStaticVNode(`<div class="h-[38px] w-[38px] rounded-full m-a ring-2 ring flex press-animated">
|
||||
<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" />
|
||||
</div>`, 1);
|
||||
const notificationPopover = ref<InstanceType<typeof NotificationDrawer>>();
|
||||
const isNotificationOpen = ref(false);
|
||||
|
||||
const handleNotificationClick = (event: Event) => {
|
||||
notificationPopover.value?.toggle(event);
|
||||
};
|
||||
|
||||
const links = [
|
||||
{ href: "/#home", 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: "/payments-and-plans", label: "Payments & Plans", icon: Credit, type: "a", className },
|
||||
{ href: "/notification", label: "Notification", icon: Bell, type: "btn", className, action: handleNotificationClick, isActive: isNotificationOpen },
|
||||
{ href: "/profile", label: "Profile", icon: profileHoist, type: "a", className: 'w-12 h-12 rounded-2xl hover:bg-primary/15 flex shrink-0' },
|
||||
];
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<header
|
||||
class=":uno: fixed left-0 flex flex-col items-center pt-4 gap-6 z-41 max-h-screen h-screen bg-muted transition-all duration-300 ease-in-out w-18 items-center">
|
||||
|
||||
<template v-for="i in links" :key="i.label">
|
||||
<component :name="i.label" :is="i.type === 'a' ? 'router-link' : 'div'"
|
||||
v-bind="i.type === 'a' ? { to: i.href } : {}" v-tooltip="i.label" @click="i.action && i.action($event)"
|
||||
:class="cn(
|
||||
i.className,
|
||||
($route.path === i.href || i.isActive?.value) && 'bg-primary/15'
|
||||
)">
|
||||
<component :is="i.icon" class="w-6 h-6 shrink-0"
|
||||
:filled="$route.path === i.href || i.isActive?.value" />
|
||||
</component>
|
||||
</template>
|
||||
</header>
|
||||
<ClientOnly>
|
||||
<NotificationDrawer ref="notificationPopover" @change="(val) => isNotificationOpen = val" />
|
||||
</ClientOnly>
|
||||
</template>
|
||||
@@ -25,7 +25,7 @@ const props = defineProps<Props>();
|
||||
|
||||
const getButtonClass = (variant?: string) => {
|
||||
const baseClass = 'px-4 py-2.5 rounded-lg font-medium transition-all press-animated flex items-center gap-2';
|
||||
|
||||
|
||||
switch (variant) {
|
||||
case 'primary':
|
||||
return `${baseClass} bg-primary hover:bg-primary-600 text-white shadow-sm`;
|
||||
@@ -43,20 +43,14 @@ const getButtonClass = (variant?: string) => {
|
||||
<!-- Breadcrumb -->
|
||||
<nav v-if="breadcrumbs && breadcrumbs.length" class="flex items-center gap-2 text-sm mb-2">
|
||||
<template v-for="(crumb, index) in breadcrumbs" :key="index">
|
||||
<router-link
|
||||
v-if="crumb.to"
|
||||
:to="crumb.to"
|
||||
class="text-gray-500 hover:text-primary transition-colors"
|
||||
>
|
||||
<router-link v-if="crumb.to" :to="crumb.to" class="text-gray-500 hover:text-primary transition-colors">
|
||||
{{ crumb.label }}
|
||||
</router-link>
|
||||
<span v-else class="text-gray-700 font-medium">{{ crumb.label }}</span>
|
||||
|
||||
<span
|
||||
v-if="index < breadcrumbs.length - 1"
|
||||
class="w-4 h-4 text-gray-400"
|
||||
>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor" aria-hidden="true">
|
||||
|
||||
<span v-if="index < breadcrumbs.length - 1" class="w-4 h-4 text-gray-400">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor"
|
||||
aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
|
||||
</svg>
|
||||
</span>
|
||||
@@ -72,17 +66,9 @@ const getButtonClass = (variant?: string) => {
|
||||
</div>
|
||||
|
||||
<div v-if="actions && actions.length" class="flex items-center gap-2 flex-shrink-0">
|
||||
<button
|
||||
v-for="(action, index) in actions"
|
||||
:key="index"
|
||||
@click="action.onClick"
|
||||
:class="getButtonClass(action.variant)"
|
||||
>
|
||||
<component
|
||||
v-if="action.icon"
|
||||
:is="action.icon"
|
||||
class="w-5 h-5"
|
||||
/>
|
||||
<button v-for="(action, index) in actions" :key="index" @click="action.onClick"
|
||||
:class="getButtonClass(action.variant)">
|
||||
<component v-if="action.icon" :is="action.icon" class="w-5 h-5" />
|
||||
{{ action.label }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -37,7 +37,7 @@ const iconColors = {
|
||||
|
||||
<template>
|
||||
<div :class="[
|
||||
'transform translate-y-0 relative overflow-hidden rounded-2xl p-6 bg-white',
|
||||
'transform translate-y-0 relative overflow-hidden rounded-2xl p-6 bg-surface',
|
||||
// gradients[color],
|
||||
'border border-gray-300 transition-all duration-300',
|
||||
// 'group cursor-pointer'
|
||||
|
||||
@@ -13,5 +13,5 @@
|
||||
</svg>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
defineProps<{ filled?: boolean }>();
|
||||
defineProps<{ filled?: boolean }>();
|
||||
</script>
|
||||
17
src/components/icons/PanelLeft.vue
Normal file
17
src/components/icons/PanelLeft.vue
Normal file
@@ -0,0 +1,17 @@
|
||||
<script setup lang="ts">
|
||||
import { cn } from "@/lib/utils";
|
||||
|
||||
defineProps<{
|
||||
class?: string;
|
||||
filled?: boolean;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<svg :class="cn('w-6 h-6', $props.class)" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M19 21H5C3.89543 21 3 20.1046 3 19V5C3 3.89543 3.89543 3 5 3H19C20.1046 3 21 3.89543 21 5V19C21 20.1046 20.1046 21 19 21Z"
|
||||
stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
||||
<path d="M9 3V21" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
|
||||
</svg>
|
||||
</template>
|
||||
Reference in New Issue
Block a user