diff options
| author | Adam Soltys <[email protected]> | 2024-11-03 20:48:42 -0800 |
|---|---|---|
| committer | Adam Soltys <[email protected]> | 2024-11-03 20:48:42 -0800 |
| commit | 769f9b34781f010db426fef1af7d85e6fcb9a291 (patch) | |
| tree | 8cf18059bc730dc005a69ff66f96b53f80fa1f01 | |
| parent | d792236a58a932181cbc2e13ba5c3609b91e0164 (diff) | |
| download | coinos-ui-769f9b34781f010db426fef1af7d85e6fcb9a291.tar.gz coinos-ui-769f9b34781f010db426fef1af7d85e6fcb9a291.zip | |
dark mode
| -rwxr-xr-x | bun.lockb | bin | 161054 -> 162583 bytes | |||
| -rw-r--r-- | package.json | 1 | ||||
| -rw-r--r-- | src/app.css | 6 | ||||
| -rw-r--r-- | src/components/AppHeader.svelte | 34 | ||||
| -rw-r--r-- | src/components/Avatar.svelte | 2 | ||||
| -rw-r--r-- | src/components/LandingHeader.svelte | 2 | ||||
| -rw-r--r-- | src/lib/store.ts | 3 | ||||
| -rw-r--r-- | src/locales/en.json | 1 | ||||
| -rw-r--r-- | src/routes/(app)/+layout.svelte | 3 | ||||
| -rw-r--r-- | src/routes/(app)/[username]/(profile)/+page.svelte | 4 | ||||
| -rw-r--r-- | src/routes/(app)/send/[...text]/+page.svelte | 2 | ||||
| -rw-r--r-- | src/routes/(app)/settings/[...tab]/+page.svelte | 2 | ||||
| -rw-r--r-- | src/routes/(app)/settings/[...tab]/_security.svelte | 16 | ||||
| -rw-r--r-- | src/routes/(static)/+layout.svelte | 6 | ||||
| -rw-r--r-- | static/icons/lock.svg | 2 | ||||
| -rw-r--r-- | static/icons/moon.svg | 4 | ||||
| -rw-r--r-- | tailwind.config.cjs | 57 | ||||
| -rw-r--r-- | vite.config.js | 35 |
18 files changed, 109 insertions, 71 deletions
| Binary files differ diff --git a/package.json b/package.json index a0f20656..1c0c1b84 100644 --- a/package.json +++ b/package.json @@ -21,6 +21,7 @@ "bip21": "^2.0.3", "bitcoin-address-validation": "^2.2.1", "buffer": "^6.0.3", + "daisyui": "^4.12.14", "date-fns": "^2.29.3", "html5-qrcode": "^2.3.8", "leaflet": "^1.9.3", diff --git a/src/app.css b/src/app.css index ba1db128..ca2ed53d 100644 --- a/src/app.css +++ b/src/app.css @@ -23,11 +23,7 @@ html { input, textarea { - @apply block border rounded-2xl px-5 py-4 w-full; -} - -button.primary { - @apply rounded-full border py-2 font-bold my-4 flex px-4 bg-white mx-auto hover:opacity-80; + @apply input input-bordered input-primary w-full } .select-styles { diff --git a/src/components/AppHeader.svelte b/src/components/AppHeader.svelte index 9dd37d7e..8ec0b5ed 100644 --- a/src/components/AppHeader.svelte +++ b/src/components/AppHeader.svelte @@ -1,6 +1,6 @@ <script> import OutClick from "svelte-outclick"; - import { banner, newPayment } from "$lib/store"; + import { banner, theme, newPayment } from "$lib/store"; import { goto } from "$app/navigation"; import Avatar from "$comp/Avatar.svelte"; import Icon from "$comp/Icon.svelte"; @@ -14,19 +14,11 @@ let menuButtons; $: if (user) menuButtons = [ - { - key: "nav.settings", - icon: "settings", - href: `/settings`, - }, + { key: "nav.settings", icon: "settings", href: `/settings` }, { key: "nav.support", icon: "support", href: `/support` }, { key: "nav.map", icon: "map", href: `/map` }, - // { - // key: "nav.messages", - // icon: "message", - // href: `/messages`, - // }, { key: "nav.merch", icon: "shop", href: `https://coinosmerch.com` }, + { key: "nav.dark", icon: "moon", href: `/dark` }, { key: "nav.signOut", icon: "logout", href: `/logout` }, ]; @@ -42,18 +34,20 @@ : undefined; $: $page && (showMenu = false); + + let dark = () => ($theme = $theme === "dark" ? "light" : "dark"); </script> {#if !$loading} <header - class="bg-gradient-to-r from-primary to-gradient h-[175px] w-full relative bg-cover mb-20" + class="bg-gradient-to-r from-primary to-gradient h-[175px] w-full relative bg-cover mb-20 text-secondary" style:background-image={bg} > <nav class="flex justify-end items-center space-x-4 p-5"> {#if user} <a href={`/${user.username}`} data-sveltekit-preload-code="eager"> <button - class="bg-white p-2 rounded-full w-12 h-12 sm:w-16 sm:h-16 drop-shadow-xl border border-black/10 {$page + class="bg-base p-2 rounded-full w-12 h-12 sm:w-16 sm:h-16 drop-shadow-xl border border-black/10 {$page .url.pathname === `/${user.username}` ? 'opacity-100' : 'opacity-70 hover:opacity-80'}" @@ -117,17 +111,25 @@ <div class="{showMenu ? 'block' - : 'hidden'} absolute top-14 right-0 bg-white rounded-3xl p-8 shadow-xl z-50" + : 'hidden'} absolute top-14 right-0 bg-base-100 rounded-3xl p-8 shadow-xl z-50" > <ul class="space-y-5 w-48"> {#each menuButtons as { href, icon, key }} <li> - <a {href} data-sveltekit-preload-code="eager"> + {#if key.includes("dark")} <button class="flex justify-center items-center font-semibold hover:opacity-80" + on:click={dark} ><Icon {icon} style="mr-2 w-6 sm:w-8" /> {$t(key)} </button> - </a> + {:else} + <a {href} data-sveltekit-preload-code="eager"> + <button + class="flex justify-center items-center font-semibold hover:opacity-80" + ><Icon {icon} style="mr-2 w-6 sm:w-8" /> {$t(key)} + </button> + </a> + {/if} </li> {/each} </ul> diff --git a/src/components/Avatar.svelte b/src/components/Avatar.svelte index e91285da..a088c4ee 100644 --- a/src/components/Avatar.svelte +++ b/src/components/Avatar.svelte @@ -21,7 +21,7 @@ <a href={link} class:pointer-events-none={disabled}> <div - class="w-{s} h-{s} rounded-full border-4 border-white overflow-hidden bg-gradient-to-r from-primary to-gradient flex justify-center items-center" + class="w-{s} h-{s} rounded-full border-4 border-base-100 overflow-hidden bg-gradient-to-r from-primary to-gradient flex justify-center items-center" > <img {src} diff --git a/src/components/LandingHeader.svelte b/src/components/LandingHeader.svelte index 72913999..232e53eb 100644 --- a/src/components/LandingHeader.svelte +++ b/src/components/LandingHeader.svelte @@ -19,7 +19,7 @@ </script> <header - class="w-full lg:w-5/6 py-5 mx-auto fixed sticky z-10 top-0 bg-white/90" + class="w-full lg:w-5/6 py-5 mx-auto fixed sticky z-10 top-0" bind:this={header} > <nav class="block lg:flex justify-between items-center"> diff --git a/src/lib/store.ts b/src/lib/store.ts index 3156d0e2..c72472a4 100644 --- a/src/lib/store.ts +++ b/src/lib/store.ts @@ -1,5 +1,5 @@ -import { writable } from "svelte/store"; import { browser } from "$app/environment"; +import { writable } from "svelte/store"; const persistSession = (key, defaultValue = undefined) => { const s = writable( @@ -57,6 +57,7 @@ export const pin = persistLocal("pin"); export const rate = writable(); export const request = writable(); export const requestRedirect = writable(); +export const theme = persistLocal("light"); export const token = persistSession("token"); export const ndef = writable(); export const showQr = persistLocal("showQr", true); diff --git a/src/locales/en.json b/src/locales/en.json index 64fa3d51..7a0ad3a6 100644 --- a/src/locales/en.json +++ b/src/locales/en.json @@ -165,6 +165,7 @@ "failed": "Login failed" }, "nav": { + "dark": "Dark", "about": "About", "docs": "Docs", "messages": "Messages", diff --git a/src/routes/(app)/+layout.svelte b/src/routes/(app)/+layout.svelte index ca0b5f90..4316c2bb 100644 --- a/src/routes/(app)/+layout.svelte +++ b/src/routes/(app)/+layout.svelte @@ -10,6 +10,7 @@ passwordPrompt, password, pin, + theme, } from "$lib/store"; import { page } from "$app/stores"; import { browser } from "$app/environment"; @@ -112,7 +113,7 @@ <SvelteToast options={{ reversed: true, intro: { y: 192 } }} /> -<main class="pb-20"> +<main class="pb-20 min-h-screen" data-theme={$theme}> <AppHeader {user} {subject} /> {#if !$loading} <slot /> diff --git a/src/routes/(app)/[username]/(profile)/+page.svelte b/src/routes/(app)/[username]/(profile)/+page.svelte index 7de6ec37..527c814b 100644 --- a/src/routes/(app)/[username]/(profile)/+page.svelte +++ b/src/routes/(app)/[username]/(profile)/+page.svelte @@ -41,9 +41,7 @@ </div> <a href={`/account/savings`} class="contents"> - <button - class="rounded-2xl py-5 px-6 hover:opacity-80 flex w-full justify-center bg-primary" - > + <button class="btn btn-primary"> <div class="mx-auto flex gap-2"> <Icon icon="plus" style="w-8 mx-auto" /> <div class="my-auto text-xl whitespace-nowrap"> diff --git a/src/routes/(app)/send/[...text]/+page.svelte b/src/routes/(app)/send/[...text]/+page.svelte index d27df639..519e9547 100644 --- a/src/routes/(app)/send/[...text]/+page.svelte +++ b/src/routes/(app)/send/[...text]/+page.svelte @@ -113,7 +113,7 @@ {#each contacts as c} <a href={`/pay/${c.username}`}> <div - class="border-b p-2 last:border-b-0 hover:bg-gray-100 rounded-2xl" + class="border-b p-2 last:border-b-0 hover:bg-base-200 rounded-2xl" > <div class="flex"> <div> diff --git a/src/routes/(app)/settings/[...tab]/+page.svelte b/src/routes/(app)/settings/[...tab]/+page.svelte index 0a3a6ddf..27e4e9b9 100644 --- a/src/routes/(app)/settings/[...tab]/+page.svelte +++ b/src/routes/(app)/settings/[...tab]/+page.svelte @@ -220,7 +220,7 @@ <button type="button" class="hover:opacity-80" - class:text-black={tab === name || + class:text-primary={tab === name || (tab === "shopify" && name === "pos")} >{$t(`user.settings.${key}`)}</button > diff --git a/src/routes/(app)/settings/[...tab]/_security.svelte b/src/routes/(app)/settings/[...tab]/_security.svelte index 6b44f830..eec178ad 100644 --- a/src/routes/(app)/settings/[...tab]/_security.svelte +++ b/src/routes/(app)/settings/[...tab]/_security.svelte @@ -200,7 +200,7 @@ notify={false} /> {:else} - <button type="button" class="primary" on:click={togglePin} + <button type="button" class="btn btn-primary" on:click={togglePin} ><Icon icon="lock" style="mr-1" /> {user.haspin ? $t("user.settings.disablePIN") @@ -225,17 +225,17 @@ <b>{otp.secret}</b> </div> - <button type="button" class="primary" on:click={startConfirming2fa}> + <button type="button" class="btn btn-primary" on:click={startConfirming2fa}> <Icon icon="numpad" style="w-8 mr-1" /> <div class="my-auto">Confirm</div> </button> {:else if user.twofa} - <button type="button" class="primary" on:click={startDisabling2fa}> + <button type="button" class="btn btn-primary" on:click={startDisabling2fa}> <Icon icon="mobile" style="w-8 mr-1" /> <div class="my-auto">{$t("user.settings.twofaDisable")}</div> </button> {:else} - <button type="button" class="primary" on:click={startEnabling2fa}> + <button type="button" class="btn btn-primary" on:click={startEnabling2fa}> <Icon icon="mobile" style="w-8 mr-1" /> <div class="my-auto">{$t("user.settings.twofaSetup")}</div> </button> @@ -287,8 +287,8 @@ {$t("user.settings.nostrDescription")} </p> - <div class="flex"> - <button type="button" class="primary" on:click={toggleNsec}> + <div class="flex gap-2"> + <button type="button" class="btn btn-primary" on:click={toggleNsec}> {#if revealNsec} <Icon icon="eye-off" style="mr-1 w-6 my-auto" /> {$t("user.settings.hideNsec")} @@ -298,7 +298,7 @@ {/if} </button> - <button type="button" class="primary" on:click={toggleImporting}> + <button type="button" class="btn btn-primary" on:click={toggleImporting}> <Icon icon="save" style="mr-1 w-6 my-auto" /> {$t("user.settings.import")} </button> @@ -313,7 +313,7 @@ {nsec} </div> - <button type="button" class="primary" on:click={() => copy(nsec)}> + <button type="button" class="btn btn-primary" on:click={() => copy(nsec)}> <Icon icon="copy" style="mr-1 w-6 my-auto" /> Copy </button> diff --git a/src/routes/(static)/+layout.svelte b/src/routes/(static)/+layout.svelte index 8b14fd38..f09852fb 100644 --- a/src/routes/(static)/+layout.svelte +++ b/src/routes/(static)/+layout.svelte @@ -1,6 +1,7 @@ <script> import { SvelteToast } from "@zerodevx/svelte-toast"; import Footer from "$comp/Footer.svelte"; + import { theme } from "$lib/store"; import LandingHeader from "$comp/LandingHeader.svelte"; export let data; @@ -9,7 +10,10 @@ <SvelteToast options={{ reversed: true, intro: { y: 192 } }} /> <LandingHeader {user} /> -<main class="container flex px-4 md:px-40 mx-auto min-h-[600px]"> +<main + class="container flex px-4 md:px-40 mx-auto min-h-[600px]" + data-theme={$theme} +> <slot /> </main> <Footer /> diff --git a/static/icons/lock.svg b/static/icons/lock.svg index adbf200e..e865b5d0 100644 --- a/static/icons/lock.svg +++ b/static/icons/lock.svg @@ -1,3 +1,3 @@ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> -<path d="M12 15V17M6 21H18C19.1046 21 20 20.1046 20 19V13C20 11.8954 19.1046 11 18 11H6C4.89543 11 4 11.8954 4 13V19C4 20.1046 4.89543 21 6 21ZM16 11V7C16 4.79086 14.2091 3 12 3C9.79086 3 8 4.79086 8 7V11H16Z" stroke="black" stroke-width="2" stroke-linecap="round"/> +<path d="M12 15V17M6 21H18C19.1046 21 20 20.1046 20 19V13C20 11.8954 19.1046 11 18 11H6C4.89543 11 4 11.8954 4 13V19C4 20.1046 4.89543 21 6 21ZM16 11V7C16 4.79086 14.2091 3 12 3C9.79086 3 8 4.79086 8 7V11H16Z" stroke="currentColor" stroke-width="2" stroke-linecap="round"/> </svg> diff --git a/static/icons/moon.svg b/static/icons/moon.svg new file mode 100644 index 00000000..02d66b43 --- /dev/null +++ b/static/icons/moon.svg @@ -0,0 +1,4 @@ +<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools --> +<svg width="800px" height="800px" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> +<path d="M13 6V3M18.5 12V7M14.5 4.5H11.5M21 9.5H16M15.5548 16.8151C16.7829 16.8151 17.9493 16.5506 19 16.0754C17.6867 18.9794 14.7642 21 11.3698 21C6.74731 21 3 17.2527 3 12.6302C3 9.23576 5.02061 6.31331 7.92462 5C7.44944 6.05072 7.18492 7.21708 7.18492 8.44523C7.18492 13.0678 10.9322 16.8151 15.5548 16.8151Z" stroke="#000000" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> +</svg>
\ No newline at end of file diff --git a/tailwind.config.cjs b/tailwind.config.cjs index 746f4ca6..31724909 100644 --- a/tailwind.config.cjs +++ b/tailwind.config.cjs @@ -1,17 +1,46 @@ /** @type {import('tailwindcss').Config} */ module.exports = { - content: ["./src/**/*.{html,js,svelte}"], - theme: { - extend: { - colors: { - primary: "#F5F7FA", - secondary: "#70757E", - gradient: "#C3CFE2", - lightgrey: "#EAECEF", - grey: "#70757E", - }, - }, - }, - plugins: [require("tailwind-scrollbar")], - safelist: ["w-16", "h-16", "w-20", "h-20", "w-24", "h-24"], + content: ["./src/**/*.{html,js,svelte}"], + theme: { + extend: { + colors: { + primary: "#F5F7FA", + secondary: "#70757E", + gradient: "#C3CFE2", + lightgrey: "#EAECEF", + grey: "#70757E", + }, + }, + }, + plugins: [require("tailwind-scrollbar"), require("daisyui")], + daisyui: { + themes: [ + { + light: { + ...require("daisyui/src/theming/themes").lofi, + primary: "#F5F7FA", + secondary: "#70757E", + gradient: "#C3CFE2", + lightgrey: "#EAECEF", + grey: "#70757E", + }, + }, + { + dark: { + ...require("daisyui/src/theming/themes").black, + gradient: "#C3CFE2", + lightgrey: "#EAECEF", + grey: "#70757E", + }, + }, + ], // false: only light + dark | true: all themes | array: specific themes like this ["light", "dark", "cupcake"] + darkTheme: "dark", // name of one of the included themes for dark mode + base: true, // applies background color and foreground color for root element by default + styled: true, // include daisyUI colors and design decisions for all components + utils: true, // adds responsive and modifier utility classes + prefix: "", // prefix for daisyUI classnames (components, modifiers and responsive class names. Not colors) + logs: false, // Shows info about daisyUI version and used config in the console when building your CSS + themeRoot: ":root", // The element that receives theme color CSS variables + }, + safelist: ["w-16", "h-16", "w-20", "h-20", "w-24", "h-24"], }; diff --git a/vite.config.js b/vite.config.js index 2898d0ad..e0f3671f 100644 --- a/vite.config.js +++ b/vite.config.js @@ -1,26 +1,27 @@ import { sveltekit } from "@sveltejs/kit/vite"; +import Icons from "unplugin-icons/vite"; import path from "path"; /** @type {import('vite').UserConfig} */ const config = { - plugins: [sveltekit()], - resolve: { - alias: { - $comp: path.resolve("src/components"), - }, - }, - server: { - proxy: - process.env.NODE_ENV === "development" - ? { - "/api/": { - target: "http://localhost:3119", - rewrite: (path) => path.replace(/^\/api\//, ""), - }, - } - : undefined, - }, + plugins: [sveltekit(), Icons({ compiler: "svelte" })], + resolve: { + alias: { + $comp: path.resolve("src/components"), + }, + }, + server: { + proxy: + process.env.NODE_ENV === "development" + ? { + "/api/": { + target: "http://localhost:3119", + rewrite: (path) => path.replace(/^\/api\//, ""), + }, + } + : undefined, + }, }; export default config; |
