aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdam Soltys <[email protected]>2024-11-03 20:48:42 -0800
committerAdam Soltys <[email protected]>2024-11-03 20:48:42 -0800
commit769f9b34781f010db426fef1af7d85e6fcb9a291 (patch)
tree8cf18059bc730dc005a69ff66f96b53f80fa1f01
parentd792236a58a932181cbc2e13ba5c3609b91e0164 (diff)
downloadcoinos-ui-769f9b34781f010db426fef1af7d85e6fcb9a291.tar.gz
coinos-ui-769f9b34781f010db426fef1af7d85e6fcb9a291.zip
dark mode
-rwxr-xr-xbun.lockbbin161054 -> 162583 bytes
-rw-r--r--package.json1
-rw-r--r--src/app.css6
-rw-r--r--src/components/AppHeader.svelte34
-rw-r--r--src/components/Avatar.svelte2
-rw-r--r--src/components/LandingHeader.svelte2
-rw-r--r--src/lib/store.ts3
-rw-r--r--src/locales/en.json1
-rw-r--r--src/routes/(app)/+layout.svelte3
-rw-r--r--src/routes/(app)/[username]/(profile)/+page.svelte4
-rw-r--r--src/routes/(app)/send/[...text]/+page.svelte2
-rw-r--r--src/routes/(app)/settings/[...tab]/+page.svelte2
-rw-r--r--src/routes/(app)/settings/[...tab]/_security.svelte16
-rw-r--r--src/routes/(static)/+layout.svelte6
-rw-r--r--static/icons/lock.svg2
-rw-r--r--static/icons/moon.svg4
-rw-r--r--tailwind.config.cjs57
-rw-r--r--vite.config.js35
18 files changed, 109 insertions, 71 deletions
diff --git a/bun.lockb b/bun.lockb
index 08745e27..e0742e80 100755
--- a/bun.lockb
+++ b/bun.lockb
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;