change color
This commit is contained in:
2
components.d.ts
vendored
2
components.d.ts
vendored
@@ -14,6 +14,7 @@ declare module 'vue' {
|
||||
export interface GlobalComponents {
|
||||
Add: typeof import('./src/components/icons/Add.vue')['default']
|
||||
AlertTriangleIcon: typeof import('./src/components/icons/AlertTriangleIcon.vue')['default']
|
||||
ArrowDownTray: typeof import('./src/components/icons/ArrowDownTray.vue')['default']
|
||||
ArrowRightIcon: typeof import('./src/components/icons/ArrowRightIcon.vue')['default']
|
||||
Bell: typeof import('./src/components/icons/Bell.vue')['default']
|
||||
Button: typeof import('primevue/button')['default']
|
||||
@@ -61,6 +62,7 @@ declare module 'vue' {
|
||||
declare global {
|
||||
const Add: typeof import('./src/components/icons/Add.vue')['default']
|
||||
const AlertTriangleIcon: typeof import('./src/components/icons/AlertTriangleIcon.vue')['default']
|
||||
const ArrowDownTray: typeof import('./src/components/icons/ArrowDownTray.vue')['default']
|
||||
const ArrowRightIcon: typeof import('./src/components/icons/ArrowRightIcon.vue')['default']
|
||||
const Bell: typeof import('./src/components/icons/Bell.vue')['default']
|
||||
const Button: typeof import('primevue/button')['default']
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import { cn } from '@/lib/utils';
|
||||
import { VNode } from 'vue';
|
||||
import VueHead from '@/components/VueHead';
|
||||
|
||||
interface Breadcrumb {
|
||||
label: string;
|
||||
@@ -16,7 +15,7 @@ interface Action {
|
||||
}
|
||||
|
||||
interface Props {
|
||||
title: string;
|
||||
title: string | VNode;
|
||||
description?: string;
|
||||
breadcrumbs?: Breadcrumb[];
|
||||
actions?: Action[];
|
||||
@@ -67,8 +66,8 @@ const getButtonClass = (variant?: string) => {
|
||||
<!-- Title & Actions -->
|
||||
<div class="flex items-start justify-between gap-4 flex-wrap">
|
||||
<div class="flex-1 min-w-0">
|
||||
<h1 class="text-3xl font-bold text-gray-900 mb-1">{{ title }}</h1>
|
||||
<vue-head :input="{ title, meta: [{ name: 'description', content: description || '' }] }" />
|
||||
<h1 v-if="typeof props.title == 'string'" class="text-3xl font-bold text-gray-900 mb-1">{{ title }}</h1>
|
||||
<component v-else :is="title" />
|
||||
<p v-if="description" class="text-gray-600">{{ description }}</p>
|
||||
</div>
|
||||
|
||||
|
||||
17
src/components/icons/ArrowDownTray.vue
Normal file
17
src/components/icons/ArrowDownTray.vue
Normal file
@@ -0,0 +1,17 @@
|
||||
<template>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"
|
||||
v-if="!filled">
|
||||
<path stroke-linecap="round" stroke-linejoin="round"
|
||||
d="M3 16.5v2.25A2.25 2.25 0 0 0 5.25 21h13.5A2.25 2.25 0 0 0 21 18.75V16.5M16.5 12 12 16.5m0 0L7.5 12m4.5 4.5V3" />
|
||||
</svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" v-else>
|
||||
<path fill-rule="evenodd"
|
||||
d="M12 2.25a.75.75 0 0 1 .75.75v11.69l3.22-3.22a.75.75 0 1 1 1.06 1.06l-4.5 4.5a.75.75 0 0 1-1.06 0l-4.5-4.5a.75.75 0 1 1 1.06-1.06l3.22 3.22V3a.75.75 0 0 1 .75-.75Zm-9 13.5a.75.75 0 0 1 .75.75v2.25a1.5 1.5 0 0 0 1.5 1.5h13.5a1.5 1.5 0 0 0 1.5-1.5V16.5a.75.75 0 0 1 1.5 0v2.25a3 3 0 0 1-3 3H5.25a3 3 0 0 1-3-3V16.5a.75.75 0 0 1 .75-.75Z"
|
||||
clip-rule="evenodd" />
|
||||
</svg>
|
||||
</template>
|
||||
<script lang="ts" setup>
|
||||
defineProps<{
|
||||
filled?: boolean
|
||||
}>()
|
||||
</script>
|
||||
@@ -1,13 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
<script setup lang="tsx">
|
||||
import { client, type ModelVideo } from '@/api/client';
|
||||
import PageHeader from '@/components/dashboard/PageHeader.vue';
|
||||
import { useAuthStore } from '@/stores/auth';
|
||||
import { onMounted, ref } from 'vue';
|
||||
import NameGradient from './components/NameGradient.vue';
|
||||
import QuickActions from './components/QuickActions.vue';
|
||||
import RecentVideos from './components/RecentVideos.vue';
|
||||
import StatsOverview from './components/StatsOverview.vue';
|
||||
|
||||
const auth = useAuthStore()
|
||||
const loading = ref(true);
|
||||
const recentVideos = ref<ModelVideo[]>([]);
|
||||
|
||||
@@ -53,12 +52,12 @@ const fetchDashboardData = async () => {
|
||||
onMounted(() => {
|
||||
fetchDashboardData();
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="dashboard-overview">
|
||||
<PageHeader :title="`Welcome back, ${auth.user?.username}! 👋`" description="Here's what's happening with your videos."
|
||||
:breadcrumbs="[
|
||||
<PageHeader :title="NameGradient" description="Welcome back, Here's what's happening with your videos." :breadcrumbs="[
|
||||
{ label: 'Dashboard' }
|
||||
]" />
|
||||
|
||||
|
||||
10
src/routes/overview/components/NameGradient.vue
Normal file
10
src/routes/overview/components/NameGradient.vue
Normal file
@@ -0,0 +1,10 @@
|
||||
<template>
|
||||
<div class="text-3xl font-bold text-gray-900 mb-1">
|
||||
<span class=":uno: bg-[linear-gradient(130deg,#14a74b_0%,#22c55e_35%,#10b981_65%,#06b6d4_100%)] bg-clip-text text-transparent">Hello, {{ auth.user?.username }}</span>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { useAuthStore } from '@/stores/auth';
|
||||
|
||||
const auth = useAuthStore()
|
||||
</script>
|
||||
@@ -29,19 +29,38 @@ const getStatusSeverity = (status: string) => {
|
||||
return 'info';
|
||||
}
|
||||
};
|
||||
import { useToast } from 'primevue/usetoast';
|
||||
import ArrowDownTray from '@/components/icons/ArrowDownTray.vue';
|
||||
|
||||
const toast = useToast();
|
||||
|
||||
|
||||
|
||||
const downloadInvoice = (item: PaymentHistoryItem) => {
|
||||
toast.add({
|
||||
severity: 'info',
|
||||
summary: 'Downloading',
|
||||
detail: `Downloading invoice #${item.invoiceId}...`,
|
||||
life: 2000
|
||||
});
|
||||
|
||||
// Simulate download delay
|
||||
setTimeout(() => {
|
||||
toast.add({
|
||||
severity: 'success',
|
||||
summary: 'Downloaded',
|
||||
detail: `Invoice #${item.invoiceId} downloaded successfully`,
|
||||
life: 3000
|
||||
});
|
||||
}, 1500);
|
||||
};
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<section>
|
||||
<h2 class="text-2xl font-bold mb-6 text-gray-900">Billing History</h2>
|
||||
<div class="bg-white border border-gray-200 rounded-xl overflow-hidden shadow-sm">
|
||||
<DataTable :value="history" tableStyle="min-width: 50rem"
|
||||
:pt="{
|
||||
thead: { class: 'bg-gray-50 border-b border-gray-200' },
|
||||
headerRow: { class: 'text-gray-500 text-xs font-semibold uppercase tracking-wider' },
|
||||
bodyRow: { class: 'text-gray-700 hover:bg-gray-50/50' }
|
||||
}"
|
||||
>
|
||||
<div class="bg-white border border-gray-200 rounded-xl overflow-hidden">
|
||||
<DataTable :value="history" responsiveLayout="scroll" class="w-full">
|
||||
<template #empty>
|
||||
<div class="text-center py-8 text-gray-500">No payment history found.</div>
|
||||
</template>
|
||||
@@ -54,19 +73,20 @@ const getStatusSeverity = (status: string) => {
|
||||
<Column field="plan" header="Plan"></Column>
|
||||
<Column field="status" header="Status">
|
||||
<template #body="slotProps">
|
||||
<Tag
|
||||
:value="slotProps.data.status"
|
||||
:severity="getStatusSeverity(slotProps.data.status)"
|
||||
class="capitalize px-2 py-0.5 text-xs"
|
||||
:rounded="true"
|
||||
/>
|
||||
<Tag :value="slotProps.data.status" :severity="getStatusSeverity(slotProps.data.status)"
|
||||
class="capitalize px-2 py-0.5 text-xs" :rounded="true" />
|
||||
</template>
|
||||
</Column>
|
||||
<Column header="" style="width: 3rem">
|
||||
<template #body>
|
||||
<Button icon="i-heroicons-arrow-down-tray" text rounded severity="secondary" size="small" />
|
||||
<!-- <Column header="" style="width: 3rem">
|
||||
<template #body="slotProps">
|
||||
<Button text rounded severity="secondary" size="small" @click="downloadInvoice(slotProps.data)"
|
||||
v-tooltip="'Download Invoice'">
|
||||
<template #icon>
|
||||
<ArrowDownTray class="w-5 h-5" />
|
||||
</template>
|
||||
</Column>
|
||||
</Button>
|
||||
</template>
|
||||
</Column> -->
|
||||
</DataTable>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { formatBytes } from '@/lib/utils';
|
||||
import ProgressBar from 'primevue/progressbar';
|
||||
import { computed } from 'vue';
|
||||
import { formatBytes } from '@/lib/utils';
|
||||
|
||||
const props = defineProps<{
|
||||
storageUsed: number;
|
||||
@@ -15,7 +15,7 @@ const uploadsPercentage = computed(() => Math.min(Math.round((props.uploadsUsed
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="bg-white border border-gray-200 rounded-2xl p-8 shadow-sm flex flex-col justify-center">
|
||||
<div class="bg-white border border-gray-200 rounded-2xl p-8 flex flex-col justify-center">
|
||||
<h3 class="text-lg font-bold text-gray-900 mb-6">Usage Statistics</h3>
|
||||
|
||||
<div class="mb-6">
|
||||
|
||||
@@ -21,7 +21,7 @@ const formatBytes = (bytes: number) => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="bg-white border border-gray-200 rounded-2xl p-6 shadow-sm">
|
||||
<div class="bg-white border border-gray-200 rounded-2xl p-6">
|
||||
<h3 class="text-lg font-bold text-gray-900 mb-4">Account Status</h3>
|
||||
<div class="space-y-4">
|
||||
<div>
|
||||
|
||||
@@ -3,7 +3,7 @@ import Tag from 'primevue/tag';
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="bg-white border border-gray-200 rounded-2xl p-6 shadow-sm">
|
||||
<div class="bg-white border border-gray-200 rounded-2xl p-6">
|
||||
<h3 class="text-lg font-bold text-gray-900 mb-4">Linked Accounts</h3>
|
||||
<div class="space-y-3">
|
||||
<div class="flex items-center justify-between p-3 rounded-lg border border-gray-100 hover:border-gray-200 transition-colors">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import type { ModelUser } from '@/api/client';
|
||||
import InputText from 'primevue/inputtext';
|
||||
import Button from 'primevue/button';
|
||||
import InputText from 'primevue/inputtext';
|
||||
|
||||
defineProps<{
|
||||
user: ModelUser | null;
|
||||
@@ -14,7 +14,7 @@ const emit = defineEmits<{
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="bg-white border border-gray-200 rounded-2xl p-8 shadow-sm">
|
||||
<div class="bg-white border border-gray-200 rounded-2xl p-8">
|
||||
<div class="flex items-center justify-between mb-6">
|
||||
<h3 class="text-xl font-bold text-gray-900">Personal Information</h3>
|
||||
<div class="flex gap-2">
|
||||
|
||||
@@ -45,18 +45,18 @@ export default defineConfig({
|
||||
dark: "#14532d",
|
||||
},
|
||||
accent: {
|
||||
DEFAULT: "#6366f1",
|
||||
50: "#eef2ff",
|
||||
100: "#e0e7ff",
|
||||
200: "#c7d2fe",
|
||||
300: "#a5b4fc",
|
||||
400: "#818cf8",
|
||||
500: "#6366f1",
|
||||
600: "#4f46e5",
|
||||
700: "#4338ca",
|
||||
800: "#3730a3",
|
||||
900: "#312e81",
|
||||
950: "#1e1b4b",
|
||||
DEFAULT: "#14a74b",
|
||||
50: "#ecfdf3",
|
||||
100: "#d1fae5",
|
||||
200: "#a7f3d0",
|
||||
300: "#6ee7b7",
|
||||
400: "#34d399",
|
||||
500: "#14a74b",
|
||||
600: "#0f8a3d",
|
||||
700: "#0c6f33",
|
||||
800: "#095a2a",
|
||||
900: "#064622",
|
||||
950: "#032814",
|
||||
},
|
||||
success: {
|
||||
DEFAULT: "#22c55e",
|
||||
|
||||
Reference in New Issue
Block a user