mirror of
https://github.com/seriousm4x/UpSnap.git
synced 2026-07-29 08:52:51 -04:00
add theming
This commit is contained in:
@@ -86,7 +86,8 @@
|
||||
"@fortawesome/free-solid-svg-icons": "^6.4.0",
|
||||
"date-fns": "^2.30.0",
|
||||
"pocketbase": "^0.15.3",
|
||||
"svelte-fa": "^3.0.4"
|
||||
"svelte-fa": "^3.0.4",
|
||||
"theme-change": "^2.5.0"
|
||||
}
|
||||
>>>>>>> 5340d83 (first commit for tailwind rewrite)
|
||||
}
|
||||
|
||||
10
frontend/pnpm-lock.yaml
generated
10
frontend/pnpm-lock.yaml
generated
@@ -37,6 +37,9 @@ dependencies:
|
||||
svelte-fa:
|
||||
specifier: ^3.0.4
|
||||
version: 3.0.4
|
||||
theme-change:
|
||||
specifier: ^2.5.0
|
||||
version: 2.5.0
|
||||
|
||||
devDependencies:
|
||||
'@sveltejs/adapter-static':
|
||||
@@ -3436,6 +3439,13 @@ packages:
|
||||
}
|
||||
dev: true
|
||||
|
||||
/theme-change@2.5.0:
|
||||
resolution:
|
||||
{
|
||||
integrity: sha512-B/UdsgdHAGhSKHTAQnxg/etN0RaMDpehuJmZIjLMDVJ6DGIliRHGD6pODi1CXLQAN9GV0GSyB3G6yCuK05PkPQ==
|
||||
}
|
||||
dev: false
|
||||
|
||||
/thenify-all@1.6.0:
|
||||
resolution:
|
||||
{
|
||||
|
||||
@@ -4,6 +4,25 @@
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
%sveltekit.head%
|
||||
<script>
|
||||
const darkTheme = 'dracula';
|
||||
const lightTheme = 'cupcake';
|
||||
const preferesDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
const theme = localStorage.getItem('theme')
|
||||
? localStorage.getItem('theme')
|
||||
: preferesDark
|
||||
? darkTheme
|
||||
: lightTheme;
|
||||
document.documentElement.setAttribute('data-theme', theme);
|
||||
|
||||
window
|
||||
.matchMedia('(prefers-color-scheme: dark)')
|
||||
.addEventListener('change', ({ matches }) => {
|
||||
matches
|
||||
? document.documentElement.setAttribute('data-theme', darkTheme)
|
||||
: document.documentElement.setAttribute('data-theme', lightTheme);
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
<body data-sveltekit-preload-data="hover">
|
||||
<div style="display: contents">%sveltekit.body%</div>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
import Fa from 'svelte-fa';
|
||||
import type { IconDefinition } from '@fortawesome/free-solid-svg-icons';
|
||||
|
||||
export let color = '';
|
||||
export let color: '' | 'info' | 'success' | 'warning' | 'error' = '';
|
||||
export let message: string;
|
||||
export let icon: IconDefinition;
|
||||
export let customClasses = '';
|
||||
@@ -19,3 +19,15 @@
|
||||
{/if}
|
||||
<span>{message}</span>
|
||||
</div>
|
||||
|
||||
<style global>
|
||||
/* needed, so that svelte includes these classes on build */
|
||||
.alert-info {
|
||||
}
|
||||
.alert-success {
|
||||
}
|
||||
.alert-warning {
|
||||
}
|
||||
.alert-error {
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -196,7 +196,7 @@
|
||||
required
|
||||
/>
|
||||
</div>
|
||||
<span class="text-error me-4 self-center">* required field</span>
|
||||
<span class="badge text-error me-4 self-center">* required field</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,7 +4,55 @@
|
||||
import { pocketbase, backendUrl } from '$lib/stores/pocketbase';
|
||||
import { settingsPub } from '$lib/stores/settings';
|
||||
import Fa from 'svelte-fa';
|
||||
import { faCog, faHome, faPlus, faKey } from '@fortawesome/free-solid-svg-icons';
|
||||
import {
|
||||
faCog,
|
||||
faHome,
|
||||
faPlus,
|
||||
faKey,
|
||||
faSwatchbook,
|
||||
faChevronDown,
|
||||
faCheck
|
||||
} from '@fortawesome/free-solid-svg-icons';
|
||||
import { themeChange } from 'theme-change';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
let availableThemes = [
|
||||
'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'
|
||||
];
|
||||
let activeTheme: string | null = '';
|
||||
|
||||
onMount(() => {
|
||||
themeChange(false);
|
||||
activeTheme = document.documentElement.getAttribute('data-theme');
|
||||
});
|
||||
|
||||
$: avatar = $pocketbase.authStore?.model?.avatar
|
||||
? $pocketbase.authStore?.model.avatar
|
||||
@@ -37,17 +85,27 @@
|
||||
<ul
|
||||
id="mobile-menu"
|
||||
tabindex="-1"
|
||||
class="menu menu-sm dropdown-content mt-3 z-[1] p-2 shadow bg-base-300 rounded-box w-52"
|
||||
class="menu dropdown-content mt-3 z-[1] p-2 gap-1 shadow bg-base-300 rounded-box w-52"
|
||||
>
|
||||
<li><a href="/" class:active={$page.url.pathname === '/'}><Fa icon={faHome} />Home</a></li>
|
||||
<li>
|
||||
<a href="/" class="rounded-lg px-4 py-2" class:active={$page.url.pathname === '/'}
|
||||
><Fa icon={faHome} />Home</a
|
||||
>
|
||||
</li>
|
||||
{#if $pocketbase.authStore.model?.collectionName !== 'users'}
|
||||
<li>
|
||||
<a href="/" class:active={$page.url.pathname.startsWith('/permissions')}
|
||||
<a
|
||||
href="/"
|
||||
class="rounded-lg px-4 py-2"
|
||||
class:active={$page.url.pathname.startsWith('/permissions')}
|
||||
><Fa icon={faKey} />Permissions</a
|
||||
>
|
||||
</li>
|
||||
<li>
|
||||
<a href="/settings/" class:active={$page.url.pathname.startsWith('/settings')}
|
||||
<a
|
||||
href="/settings/"
|
||||
class="rounded-lg px-4 py-2"
|
||||
class:active={$page.url.pathname.startsWith('/settings')}
|
||||
><Fa icon={faCog} />Settings</a
|
||||
>
|
||||
</li>
|
||||
@@ -82,6 +140,45 @@
|
||||
{/if}
|
||||
</ul>
|
||||
</div>
|
||||
<div class="dropdown md:dropdown-end">
|
||||
<div tabindex="-1" class="btn normal-case btn-ghost">
|
||||
<Fa icon={faSwatchbook} />
|
||||
<span class="hidden font-normal md:inline">Theme</span>
|
||||
<Fa icon={faChevronDown} />
|
||||
</div>
|
||||
<div
|
||||
class="dropdown-content bg-base-200 text-base-content rounded-box h-fit max-h-96 w-56 overflow-y-auto shadow mt-3 z-[1]"
|
||||
>
|
||||
<div class="grid grid-cols-1 gap-3 p-3" tabindex="-1">
|
||||
{#each availableThemes as theme}
|
||||
<button
|
||||
class="outline-base-content overflow-hidden rounded-lg text-left"
|
||||
data-set-theme={theme}
|
||||
on:click={() => (activeTheme = theme)}
|
||||
on:keydown={() => (activeTheme = theme)}
|
||||
>
|
||||
<div
|
||||
data-theme={theme}
|
||||
class="bg-base-100 text-base-content w-full cursor-pointer font-sans"
|
||||
>
|
||||
<div class="grid grid-cols-5 grid-rows-3">
|
||||
<div class="col-span-5 row-span-3 row-start-1 flex items-center gap-2 px-4 py-3">
|
||||
<Fa icon={faCheck} class={activeTheme === theme ? 'visible' : 'invisible'} />
|
||||
<div class="flex-grow text-sm">{theme}</div>
|
||||
<div class="flex h-full flex-shrink-0 flex-wrap gap-1">
|
||||
<div class="bg-primary w-2 rounded" />
|
||||
<div class="bg-secondary w-2 rounded" />
|
||||
<div class="bg-accent w-2 rounded" />
|
||||
<div class="bg-neutral w-2 rounded" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</button>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="justify-end ms-auto">
|
||||
{#if $pocketbase.authStore?.model !== null}
|
||||
<a class="btn btn-sm btn-success me-4" href="/device/new">
|
||||
|
||||
@@ -63,7 +63,7 @@
|
||||
</script>
|
||||
|
||||
{#if settingsPubClone === undefined || settingsPrivClone === undefined}
|
||||
<div class="container mx-auto text-center"><span class="loading loading-ring loading-md" /></div>
|
||||
<div class="container mx-auto text-center"><span class="loading loading-dots loading-lg" /></div>
|
||||
{:else}
|
||||
<h1 class="text-3xl font-bold mb-8">Settings</h1>
|
||||
<form on:submit|preventDefault={save}>
|
||||
@@ -148,7 +148,7 @@
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div class="container mx-auto text-center">
|
||||
<div class="container mx-auto text-center mt-6">
|
||||
{#if version === undefined}
|
||||
UpSnap version: (untracked)
|
||||
{:else}
|
||||
|
||||
@@ -15,7 +15,7 @@ const config = {
|
||||
fallback: 'index.html'
|
||||
}),
|
||||
prerender: {
|
||||
entries: ['/', '/login', '/account', '/welcome', '/device/[id]']
|
||||
entries: ['/', '/login', '/account', '/welcome', '/device/[id]', '/device/new', '/settings']
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
export default {
|
||||
content: ['./src/**/*.{html,js,svelte,ts}'],
|
||||
content: ['./src/**/*.{html,js,svelte,ts}', './node_modules/daisyui/**/*.{js,jsx,ts,tsx}'],
|
||||
theme: {
|
||||
extend: {}
|
||||
},
|
||||
plugins: [require('daisyui')],
|
||||
daisyui: {}
|
||||
daisyui: {
|
||||
themes: true,
|
||||
darkTheme: 'dracula'
|
||||
}
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user