add user profiles and theme selectors

This commit is contained in:
Hayden 2022-10-01 12:13:53 -08:00
parent 1ca430af21
commit 72324b8439
14 changed files with 466 additions and 186 deletions

View file

@ -1,6 +1,10 @@
<template> <template>
<NuxtLayout> <NuxtLayout>
<Html lang="en" data-theme="garden" /> <Html lang="en" :data-theme="theme" />
<NuxtPage /> <NuxtPage />
</NuxtLayout> </NuxtLayout>
</template> </template>
<script lang="ts" setup>
const { theme } = useTheme();
</script>

View file

@ -29,8 +29,9 @@
/> />
<path d="M5443.74 520.879v4149.79" style="fill: none; stroke: #000; stroke-width: 153.5px" /> <path d="M5443.74 520.879v4149.79" style="fill: none; stroke: #000; stroke-width: 153.5px" />
<path <path
class="bg-primary"
d="M8951.41 4102.72c0-41.65-22.221-80.136-58.291-100.961-36.069-20.825-80.51-20.825-116.58 0l-2439.92 1408.69c-36.07 20.825-58.29 59.311-58.29 100.961V7058c0 41.65 22.22 80.136 58.29 100.961 36.07 20.825 80.51 20.825 116.58 0l2439.92-1408.69c36.07-20.825 58.291-59.312 58.291-100.962v-1546.59Z" d="M8951.41 4102.72c0-41.65-22.221-80.136-58.291-100.961-36.069-20.825-80.51-20.825-116.58 0l-2439.92 1408.69c-36.07 20.825-58.29 59.311-58.29 100.961V7058c0 41.65 22.22 80.136 58.29 100.961 36.07 20.825 80.51 20.825 116.58 0l2439.92-1408.69c36.07-20.825 58.291-59.312 58.291-100.962v-1546.59Z"
style="fill: #567f67" style="fill: hsl(var(--p) / var(--tw-bg-opacity))"
/> />
<path <path
d="M8951.41 4102.72c0-41.65-22.221-80.136-58.291-100.961-36.069-20.825-80.51-20.825-116.58 0l-2439.92 1408.69c-36.07 20.825-58.29 59.311-58.29 100.961V7058c0 41.65 22.22 80.136 58.29 100.961 36.07 20.825 80.51 20.825 116.58 0l2439.92-1408.69c36.07-20.825 58.291-59.312 58.291-100.962v-1546.59ZM6463.98 5551.29v1387.06l2301.77-1328.92V4222.37L6463.98 5551.29Z" d="M8951.41 4102.72c0-41.65-22.221-80.136-58.291-100.961-36.069-20.825-80.51-20.825-116.58 0l-2439.92 1408.69c-36.07 20.825-58.29 59.311-58.29 100.961V7058c0 41.65 22.22 80.136 58.29 100.961 36.07 20.825 80.51 20.825 116.58 0l2439.92-1408.69c36.07-20.825 58.291-59.312 58.291-100.962v-1546.59ZM6463.98 5551.29v1387.06l2301.77-1328.92V4222.37L6463.98 5551.29Z"

View file

@ -1,44 +0,0 @@
<template>
<div class="overflow-hidden card bg-base-100 shadow-xl sm:rounded-lg">
<div class="px-4 py-5 sm:px-6">
<h3 class="text-lg font-medium leading-6">
<slot name="title"></slot>
</h3>
<p v-if="$slots.subtitle" class="mt-1 max-w-2xl text-sm text-gray-500">
<slot name="subtitle"></slot>
</p>
</div>
<div class="border-t border-gray-300 px-4 py-5 sm:p-0">
<dl class="sm:divide-y sm:divide-gray-300">
<div v-for="(dValue, dKey) in details" :key="dKey" class="py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt class="text-sm font-medium text-gray-500">
{{ dKey }}
</dt>
<dd class="mt-1 text-sm text-gray-900 sm:col-span-2 sm:mt-0">
<slot :name="rmSpace(dKey)" v-bind="{ key: dKey, value: dValue }">
{{ dValue }}
</slot>
</dd>
</div>
</dl>
</div>
</div>
</template>
<script setup lang="ts">
type StringLike = string | number | boolean;
function rmSpace(str: string) {
return str.replace(" ", "");
}
defineProps({
details: {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type: Object as () => Record<string, StringLike | any>,
required: true,
},
});
</script>
<style scoped></style>

View file

@ -9,7 +9,7 @@
> >
<slot /> <slot />
</h3> </h3>
<p v-if="$slots.description" class="mt-2 max-w-4xl text-sm text-gray-500"> <p v-if="$slots.description" class="mt-2 max-w-4xl text-sm text-base-content">
<slot name="description" /> <slot name="description" />
</p> </p>
<div v-if="$slots.after"> <div v-if="$slots.after">

View file

@ -1,5 +1,5 @@
<template> <template>
<div ref="label" class="dropdown dropdown-end w-full"> <div ref="label" class="dropdown dropdown-end dropdown-top w-full">
<FormTextField v-model="dateText" tabindex="0" label="Date" :inline="inline" readonly /> <FormTextField v-model="dateText" tabindex="0" label="Date" :inline="inline" readonly />
<div tabindex="0" class="mt-1 card compact dropdown-content shadow bg-base-100 rounded-box w-64" @blur="resetTime"> <div tabindex="0" class="mt-1 card compact dropdown-content shadow bg-base-100 rounded-box w-64" @blur="resetTime">
<div class="card-body"> <div class="card-body">

View file

@ -2,10 +2,10 @@
<div class="border-t border-gray-300 px-4 py-5 sm:p-0"> <div class="border-t border-gray-300 px-4 py-5 sm:p-0">
<dl class="sm:divide-y sm:divide-gray-300"> <dl class="sm:divide-y sm:divide-gray-300">
<div v-for="(detail, i) in details" :key="i" class="py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6"> <div v-for="(detail, i) in details" :key="i" class="py-4 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt class="text-sm font-medium text-gray-500"> <dt class="text-sm font-medium text-base-content">
{{ detail.name }} {{ detail.name }}
</dt> </dt>
<dd class="mt-1 text-sm text-gray-900 sm:col-span-2 sm:mt-0"> <dd class="mt-1 text-sm text-base-content sm:col-span-2 sm:mt-0">
<slot :name="detail.slot || detail.name" v-bind="{ detail }"> <slot :name="detail.slot || detail.name" v-bind="{ detail }">
<template v-if="detail.type == 'date'"> <template v-if="detail.type == 'date'">
<DateTime :date="detail.text" /> <DateTime :date="detail.text" />

View file

@ -1,9 +1,41 @@
import { Ref } from "vue"; import { Ref } from "vue";
export type DaisyTheme =
| "light"
| "dark"
| "cupcake"
| "bumblebee"
| "emerald"
| "corporate"
| "synthwave"
| "retro"
| "cyberpunk"
| "valentine"
| "halloween"
| "garden"
| "forest"
| "aqua"
| "lofi"
| "pastel"
| "fantasy"
| "wireframe"
| "black"
| "luxury"
| "dracula"
| "cmyk"
| "autumn"
| "business"
| "acid"
| "lemonade"
| "night"
| "coffee"
| "winter";
export type LocationViewPreferences = { export type LocationViewPreferences = {
showDetails: boolean; showDetails: boolean;
showEmpty: boolean; showEmpty: boolean;
editorSimpleView: boolean; editorSimpleView: boolean;
theme: DaisyTheme;
}; };
/** /**
@ -17,6 +49,7 @@ export function useViewPreferences(): Ref<LocationViewPreferences> {
showDetails: true, showDetails: true,
showEmpty: true, showEmpty: true,
editorSimpleView: true, editorSimpleView: true,
theme: "garden",
}, },
{ mergeDefaults: true } { mergeDefaults: true }
); );

View file

@ -0,0 +1,42 @@
import { ComputedRef } from "vue";
import { DaisyTheme } from "./use-preferences";
export interface UseTheme {
theme: ComputedRef<DaisyTheme>;
setTheme: (theme: DaisyTheme) => void;
}
const themeRef = ref<DaisyTheme>("garden");
export function useTheme(): UseTheme {
const preferences = useViewPreferences();
themeRef.value = preferences.value.theme;
const setTheme = (newTheme: DaisyTheme) => {
preferences.value.theme = newTheme;
if (htmlEl) {
htmlEl.value.setAttribute("data-theme", newTheme);
}
themeRef.value = newTheme;
};
const htmlEl = ref<HTMLElement>(null);
onMounted(() => {
if (htmlEl.value) {
return;
}
htmlEl.value = document.querySelector("html");
console.log(htmlEl.value);
});
const theme = computed(() => {
console.log(themeRef.value);
return themeRef.value;
});
return { theme, setTheme };
}

View file

@ -140,7 +140,7 @@
Import Import
</button> </button>
</div> </div>
<BaseButton type="button" size="sm"> <BaseButton type="button" size="sm" to="/profile">
<Icon class="h-5 w-5 mr-2" name="mdi-person" /> <Icon class="h-5 w-5 mr-2" name="mdi-person" />
Profile Profile
</BaseButton> </BaseButton>
@ -148,12 +148,12 @@
</template> </template>
<div <div
class="grid grid-cols-1 divide-y divide-gray-300 border-t border-gray-300 sm:grid-cols-3 sm:divide-y-0 sm:divide-x" class="grid grid-cols-1 divide-y divide-base-300 border-t border-base-300 sm:grid-cols-3 sm:divide-y-0 sm:divide-x"
> >
<div v-for="stat in stats" :key="stat.label" class="px-6 py-5 text-center text-sm font-medium"> <div v-for="stat in stats" :key="stat.label" class="px-6 py-5 text-center text-sm font-medium">
<span class="text-gray-900">{{ stat.value.value }}</span> <span class="text-base-900 font-bold">{{ stat.value.value }}</span>
{{ " " }} {{ " " }}
<span class="text-gray-600">{{ stat.label }}</span> <span class="text-base-600">{{ stat.label }}</span>
</div> </div>
</div> </div>
</BaseCard> </BaseCard>

View file

@ -283,13 +283,13 @@
<section class="px-3"> <section class="px-3">
<div class="space-y-4"> <div class="space-y-4">
<div class="overflow-hidden card bg-base-100 shadow-xl sm:rounded-lg"> <div class="card bg-base-100 shadow-xl sm:rounded-lg overflow-visible">
<BaseSectionHeader v-if="item" class="p-5"> <BaseSectionHeader v-if="item" class="p-5">
<Icon name="mdi-package-variant" class="-mt-1 mr-2 text-gray-600" /> <Icon name="mdi-package-variant" class="-mt-1 mr-2 text-base-content" />
<span class="text-gray-600"> <span class="text-base-content">
{{ item.name }} {{ item.name }}
</span> </span>
<p class="text-sm text-gray-600 font-bold pb-0 mb-0">Quantity {{ item.quantity }}</p> <p class="text-sm text-base-content font-bold pb-0 mb-0">Quantity {{ item.quantity }}</p>
<template #after> <template #after>
<div class="modal-action mt-3"> <div class="modal-action mt-3">
<div class="mr-auto tooltip" data-tip="Hide the cruft! "> <div class="mr-auto tooltip" data-tip="Hide the cruft! ">

View file

@ -1,4 +1,5 @@
<script setup lang="ts"> <script setup lang="ts">
import { DateDetail, Detail } from "~~/components/global/DetailsSection/types";
import { ItemAttachment } from "~~/lib/api/types/data-contracts"; import { ItemAttachment } from "~~/lib/api/types/data-contracts";
definePageMeta({ definePageMeta({
@ -64,15 +65,33 @@
); );
}); });
const itemSummary = computed(() => { const itemDetails = computed(() => {
return { return [
Description: item.value?.description || "", {
"Serial Number": item.value?.serialNumber || "", name: "Description",
"Model Number": item.value?.modelNumber || "", text: item.value?.description,
Manufacturer: item.value?.manufacturer || "", },
Notes: item.value?.notes || "", {
Insured: item.value?.insured ? "Yes" : "No", name: "Serial Number",
}; text: item.value?.serialNumber,
},
{
name: "Mode Number",
text: item.value?.modelNumber,
},
{
name: "Manufacturer",
text: item.value?.manufacturer,
},
{
name: "Insured",
text: item.value?.insured ? "Yes" : "No",
},
{
name: "Notes",
text: item.value?.notes,
},
];
}); });
const showAttachments = computed(() => { const showAttachments = computed(() => {
@ -88,35 +107,34 @@
); );
}); });
const itemAttachments = computed(() => { const attachmentDetails = computed(() => {
const val: Record<string, string> = {}; const details: Detail[] = [];
if (preferences.value.showEmpty) { const push = (name: string) => {
return { details.push({
Photos: "", name,
Manuals: "", text: "",
Warranty: "", slot: name.toLowerCase(),
Attachments: "", });
}; };
}
if (attachments.value.photos.length > 0) { if (attachments.value.photos.length > 0) {
val.Photos = ""; push("Photos");
}
if (attachments.value.manuals.length > 0) {
val.Manuals = "";
}
if (attachments.value.warranty.length > 0) {
val.Warranty = "";
} }
if (attachments.value.attachments.length > 0) { if (attachments.value.attachments.length > 0) {
val.Attachments = ""; push("Attachments");
} }
return val; if (attachments.value.warranty.length > 0) {
push("Warranty");
}
if (attachments.value.manuals.length > 0) {
push("Manuals");
}
return details;
}); });
const showWarranty = computed(() => { const showWarranty = computed(() => {
@ -127,17 +145,32 @@
}); });
const warrantyDetails = computed(() => { const warrantyDetails = computed(() => {
const payload = { const details: (Detail | DateDetail)[] = [
"Lifetime Warranty": item.value?.lifetimeWarranty ? "Yes" : "No", {
}; name: "Lifetime Warranty",
text: item.value?.lifetimeWarranty ? "Yes" : "No",
},
];
if (showWarranty.value) { if (item.value?.lifetimeWarranty) {
payload["Warranty Expires"] = item.value?.warrantyExpires || ""; details.push({
name: "Warranty Expires",
text: "N/A",
});
} else {
details.push({
name: "Warranty Expires",
text: item.value?.warrantyExpires,
type: "date",
});
} }
payload["Warranty Details"] = item.value?.warrantyDetails || ""; details.push({
name: "Warranty Details",
text: item.value?.warrantyDetails || "",
});
return payload; return details;
}); });
const showPurchase = computed(() => { const showPurchase = computed(() => {
@ -147,28 +180,45 @@
return item.value?.purchaseFrom || item.value?.purchasePrice; return item.value?.purchaseFrom || item.value?.purchasePrice;
}); });
const purchaseDetails = computed(() => { const purchaseDetails = computed<(Detail | DateDetail)[]>(() => {
return { return [
"Purchased From": item.value?.purchaseFrom || "", {
"Purchased Price": item.value?.purchasePrice ? fmtCurrency(item.value.purchasePrice) : "", name: "Purchase From",
"Purchased At": item.value?.purchaseTime || "", label: item.value?.purchaseFrom || "",
}; },
{
name: "Purchase Price",
text: item.value?.purchasePrice ? fmtCurrency(item.value.purchasePrice) : "",
},
{
name: "Purchase Date",
text: item.value.purchaseTime,
},
] as (Detail | DateDetail)[];
}); });
const showSold = computed(() => { const showSold = computed(() => {
if (preferences.value.showEmpty) { if (preferences.value.showEmpty) {
return true; return true;
} }
return item.value?.soldTo || item.value?.soldPrice; return item.value?.soldTo || item.value?.soldPrice;
}); });
const soldDetails = computed(() => { const soldDetails = computed<Array<Detail>>(() => {
return { return [
"Sold To": item.value?.soldTo || "", {
"Sold Price": item.value?.soldPrice ? fmtCurrency(item.value.soldPrice) : "", name: "Sold To",
"Sold At": item.value?.soldTime || "", text: item.value?.soldTo || "",
}; },
{
name: "Sold Price",
text: item.value?.soldPrice ? fmtCurrency(item.value.soldPrice) : "",
},
{
name: "Sold At",
text: item.value?.soldTime || "",
},
] as Detail[];
}); });
const confirm = useConfirm(); const confirm = useConfirm();
@ -197,91 +247,95 @@
<div class="form-control"></div> <div class="form-control"></div>
</div> </div>
<div class="grid grid-cols-1 gap-3"> <div class="grid grid-cols-1 gap-3">
<BaseDetails :details="itemSummary"> <BaseCard>
<template #title> <template #title>
<BaseSectionHeader v-if="item" class="pb-0"> <BaseSectionHeader>
<Icon name="mdi-package-variant" class="mr-2 text-gray-600" /> <Icon name="mdi-package-variant" class="mr-2 -mt-1 text-base-content" />
<span class="text-gray-600"> <span class="text-base-content">
{{ item.name }} {{ item ? item.name : "" }}
</span> </span>
<p class="text-sm text-gray-600 font-bold pb-0 mb-0"> <template #description>
{{ item.location.name }} - Quantity {{ item.quantity }} <p class="text-sm text-base-content font-bold pb-0 mb-0">
</p> {{ item.location.name }} - Quantity {{ item.quantity }}
<template #after> </p>
<div v-if="item.labels && item.labels.length > 0" class="flex flex-wrap gap-3 mt-3"> <div v-if="item.labels && item.labels.length > 0" class="flex flex-wrap gap-3 mt-3">
<LabelChip v-for="label in item.labels" :key="label.id" class="badge-primary" :label="label" /> <LabelChip v-for="label in item.labels" :key="label.id" class="badge-primary" :label="label" />
</div> </div>
<div class="modal-action mt-3">
<label class="label cursor-pointer mr-auto">
<input v-model="preferences.showEmpty" type="checkbox" class="toggle toggle-primary" />
<span class="label-text ml-4"> Show Empty </span>
</label>
<BaseButton size="sm" :to="`/item/${itemId}/edit`">
<template #icon>
<Icon name="mdi-pencil" />
</template>
Edit
</BaseButton>
<BaseButton size="sm" @click="deleteItem">
<template #icon>
<Icon name="mdi-delete" />
</template>
Delete
</BaseButton>
</div>
</template> </template>
</BaseSectionHeader> </BaseSectionHeader>
</template> </template>
</BaseDetails> <template #title-actions>
<BaseDetails v-if="showAttachments" :details="itemAttachments"> <div class="modal-action mt-0">
<label class="label cursor-pointer mr-auto">
<input v-model="preferences.showEmpty" type="checkbox" class="toggle toggle-primary" />
<span class="label-text ml-4"> Show Empty </span>
</label>
<BaseButton size="sm" :to="`/item/${itemId}/edit`">
<template #icon>
<Icon name="mdi-pencil" />
</template>
Edit
</BaseButton>
<BaseButton size="sm" @click="deleteItem">
<template #icon>
<Icon name="mdi-delete" />
</template>
Delete
</BaseButton>
</div>
</template>
<DetailsSection :details="itemDetails" />
</BaseCard>
<BaseCard v-if="showAttachments">
<template #title> Attachments </template> <template #title> Attachments </template>
<template #Manuals> <DetailsSection :details="attachmentDetails">
<ItemAttachmentsList <template #manuals>
v-if="attachments.manuals.length > 0" <ItemAttachmentsList
:attachments="attachments.manuals" v-if="attachments.manuals.length > 0"
:item-id="item.id" :attachments="attachments.manuals"
/> :item-id="item.id"
</template> />
<template #Attachments> </template>
<ItemAttachmentsList <template #attachments>
v-if="attachments.attachments.length > 0" <ItemAttachmentsList
:attachments="attachments.attachments" v-if="attachments.attachments.length > 0"
:item-id="item.id" :attachments="attachments.attachments"
/> :item-id="item.id"
</template> />
<template #Warranty> </template>
<ItemAttachmentsList <template #warranty>
v-if="attachments.warranty.length > 0" <ItemAttachmentsList
:attachments="attachments.warranty" v-if="attachments.warranty.length > 0"
:item-id="item.id" :attachments="attachments.warranty"
/> :item-id="item.id"
</template> />
<template #Photos> </template>
<ItemAttachmentsList <template #photos>
v-if="attachments.photos.length > 0" <ItemAttachmentsList
:attachments="attachments.photos" v-if="attachments.photos.length > 0"
:item-id="item.id" :attachments="attachments.photos"
/> :item-id="item.id"
</template> />
</BaseDetails> </template>
<BaseDetails v-if="showPurchase" :details="purchaseDetails"> </DetailsSection>
<template #title> Purchase Details </template> </BaseCard>
<template #PurchasedAt>
<DateTime :date="item.purchaseTime" /> <BaseCard v-if="showPurchase">
</template> <template #title> Purchase </template>
</BaseDetails> <DetailsSection :details="purchaseDetails" />
<BaseDetails v-if="showWarranty" :details="warrantyDetails"> </BaseCard>
<BaseCard v-if="showWarranty">
<template #title> Warranty </template> <template #title> Warranty </template>
<template #WarrantyExpires> <DetailsSection :details="warrantyDetails" />
<DateTime :date="item.warrantyExpires" /> </BaseCard>
</template>
</BaseDetails> <BaseCard v-if="showSold">
<BaseDetails v-if="showSold" :details="soldDetails">
<template #title> Sold </template> <template #title> Sold </template>
<template #SoldAt> <DetailsSection :details="soldDetails" />
<DateTime :date="item.soldTime" /> </BaseCard>
</template>
</BaseDetails>
</div> </div>
</section> </section>
</BaseContainer> </BaseContainer>

View file

@ -125,8 +125,8 @@
<BaseCard class="mb-16"> <BaseCard class="mb-16">
<template #title> <template #title>
<BaseSectionHeader> <BaseSectionHeader>
<Icon name="mdi-tag" class="mr-2 text-gray-600" /> <Icon name="mdi-tag" class="mr-2 -mt-1 text-base-content" />
<span class="text-gray-600"> <span class="text-base-content">
{{ label ? label.name : "" }} {{ label ? label.name : "" }}
</span> </span>
</BaseSectionHeader> </BaseSectionHeader>

View file

@ -123,8 +123,8 @@
<BaseCard class="mb-16"> <BaseCard class="mb-16">
<template #title> <template #title>
<BaseSectionHeader> <BaseSectionHeader>
<Icon name="mdi-map-marker" class="mr-2 text-gray-600" /> <Icon name="mdi-map-marker" class="mr-2 -mt-1 text-base-content" />
<span class="text-gray-600"> <span class="text-base-content">
{{ location ? location.name : "" }} {{ location ? location.name : "" }}
</span> </span>
</BaseSectionHeader> </BaseSectionHeader>

190
frontend/pages/profile.vue Normal file
View file

@ -0,0 +1,190 @@
<script setup lang="ts">
import { DaisyTheme } from "~~/composables/use-preferences";
definePageMeta({
layout: "home",
});
useHead({
title: "Homebox | Profile",
});
const { setTheme } = useTheme();
type ThemeOption = {
label: string;
value: DaisyTheme;
};
const themes: ThemeOption[] = [
{
label: "Garden",
value: "garden",
},
{
label: "Light",
value: "light",
},
{
label: "Cupcake",
value: "cupcake",
},
{
label: "Bumblebee",
value: "bumblebee",
},
{
label: "Emerald",
value: "emerald",
},
{
label: "Corporate",
value: "corporate",
},
{
label: "Synthwave",
value: "synthwave",
},
{
label: "Retro",
value: "retro",
},
{
label: "Cyberpunk",
value: "cyberpunk",
},
{
label: "Valentine",
value: "valentine",
},
{
label: "Halloween",
value: "halloween",
},
{
label: "Forest",
value: "forest",
},
{
label: "Aqua",
value: "aqua",
},
{
label: "Lofi",
value: "lofi",
},
{
label: "Pastel",
value: "pastel",
},
{
label: "Fantasy",
value: "fantasy",
},
{
label: "Wireframe",
value: "wireframe",
},
{
label: "Black",
value: "black",
},
{
label: "Luxury",
value: "luxury",
},
{
label: "Dracula",
value: "dracula",
},
{
label: "Cmyk",
value: "cmyk",
},
{
label: "Autumn",
value: "autumn",
},
{
label: "Business",
value: "business",
},
{
label: "Acid",
value: "acid",
},
{
label: "Lemonade",
value: "lemonade",
},
{
label: "Night",
value: "night",
},
{
label: "Coffee",
value: "coffee",
},
{
label: "Winter",
value: "winter",
},
];
</script>
<template>
<BaseContainer>
<BaseCard>
<template #title>
<BaseSectionHeader>
<Icon name="mdi-fill" class="mr-2 text-base-600" />
<span class="text-base-600"> Theme Selector </span>
<template #description>
Theme settings are stored in your browser's local storage. You can change the theme at any time. If you're
having trouble setting your theme try refreshing your browser.
</template>
</BaseSectionHeader>
</template>
<div class="px-4 pb-4">
<div class="rounded-box grid grid-cols-2 gap-4 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5">
<div
v-for="theme in themes"
:key="theme.value"
class="border-base-content/20 hover:border-base-content/40 outline-base-content overflow-hidden rounded-lg border outline-2 outline-offset-2"
:data-theme="theme.value"
:data-set-theme="theme.value"
data-act-class="outline"
@click="setTheme(theme.value)"
>
<div :data-theme="theme.value" class="bg-base-100 text-base-content w-full cursor-pointer font-sans">
<div class="grid grid-cols-5 grid-rows-3">
<div class="bg-base-200 col-start-1 row-span-2 row-start-1"></div>
<div class="bg-base-300 col-start-1 row-start-3"></div>
<div class="bg-base-100 col-span-4 col-start-2 row-span-3 row-start-1 flex flex-col gap-1 p-2">
<div class="font-bold">{{ theme.label }}</div>
<div class="flex flex-wrap gap-1">
<div class="bg-primary flex aspect-square w-5 items-center justify-center rounded lg:w-6">
<div class="text-primary-content text-sm font-bold">A</div>
</div>
<div class="bg-secondary flex aspect-square w-5 items-center justify-center rounded lg:w-6">
<div class="text-secondary-content text-sm font-bold">A</div>
</div>
<div class="bg-accent flex aspect-square w-5 items-center justify-center rounded lg:w-6">
<div class="text-accent-content text-sm font-bold">A</div>
</div>
<div class="bg-neutral flex aspect-square w-5 items-center justify-center rounded lg:w-6">
<div class="text-neutral-content text-sm font-bold">A</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</BaseCard>
</BaseContainer>
</template>
<style scoped></style>