"Icon Style" preference (account settings)

This commit is contained in:
Oliver Bryan
2026-01-17 22:08:11 +00:00
parent 4de913999e
commit 20f755ef71
2 changed files with 40 additions and 1 deletions

View File

@@ -1,3 +1,4 @@
import type { IconStyle } from "@sprint/shared";
import type { ReactNode } from "react"; import type { ReactNode } from "react";
import { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { toast } from "sonner"; import { toast } from "sonner";
@@ -5,7 +6,9 @@ import { useAuthenticatedSession } from "@/components/session-provider";
import { Button } from "@/components/ui/button"; import { Button } from "@/components/ui/button";
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"; import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog";
import { Field } from "@/components/ui/field"; import { Field } from "@/components/ui/field";
import Icon from "@/components/ui/icon";
import { Label } from "@/components/ui/label"; import { Label } from "@/components/ui/label";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { UploadAvatar } from "@/components/upload-avatar"; import { UploadAvatar } from "@/components/upload-avatar";
import { parseError, user } from "@/lib/server"; import { parseError, user } from "@/lib/server";
@@ -17,6 +20,7 @@ function AccountDialog({ trigger }: { trigger?: ReactNode }) {
const [username, setUsername] = useState(""); const [username, setUsername] = useState("");
const [password, setPassword] = useState(""); const [password, setPassword] = useState("");
const [avatarURL, setAvatarUrl] = useState<string | null>(null); const [avatarURL, setAvatarUrl] = useState<string | null>(null);
const [iconPreference, setIconPreference] = useState<IconStyle>("lucide");
const [error, setError] = useState(""); const [error, setError] = useState("");
const [submitAttempted, setSubmitAttempted] = useState(false); const [submitAttempted, setSubmitAttempted] = useState(false);
@@ -26,6 +30,7 @@ function AccountDialog({ trigger }: { trigger?: ReactNode }) {
setName(currentUser.name); setName(currentUser.name);
setUsername(currentUser.username); setUsername(currentUser.username);
setAvatarUrl(currentUser.avatarURL || null); setAvatarUrl(currentUser.avatarURL || null);
setIconPreference((currentUser.iconPreference as IconStyle) ?? "lucide");
setPassword(""); setPassword("");
setError(""); setError("");
@@ -44,6 +49,7 @@ function AccountDialog({ trigger }: { trigger?: ReactNode }) {
name: name.trim(), name: name.trim(),
password: password.trim() || undefined, password: password.trim() || undefined,
avatarURL, avatarURL,
iconPreference,
onSuccess: (data) => { onSuccess: (data) => {
setError(""); setError("");
setUser(data); setUser(data);
@@ -113,6 +119,39 @@ function AccountDialog({ trigger }: { trigger?: ReactNode }) {
placeholder="Leave empty to keep current password" placeholder="Leave empty to keep current password"
hidden={true} hidden={true}
/> />
<Label className="text-lg -mt-2">Preferences</Label>
<div className="flex flex-col gap-1 w-min">
<Label className="text-sm">Icon Style</Label>
<Select
value={iconPreference}
onValueChange={(v) => setIconPreference(v as IconStyle)}
>
<SelectTrigger className="w-full">
<SelectValue />
</SelectTrigger>
<SelectContent position="popper" side="bottom" align="start">
<SelectItem value="lucide">
<div className="flex items-center gap-2">
<Icon icon="sun" iconStyle="lucide" size={16} />
Lucide
</div>
</SelectItem>
<SelectItem value="pixel">
<div className="flex items-center gap-2">
<Icon icon="sun" iconStyle="pixel" size={16} />
Pixel
</div>
</SelectItem>
<SelectItem value="phosphor">
<div className="flex items-center gap-2">
<Icon icon="sun" iconStyle="phosphor" size={16} />
Phosphor
</div>
</SelectItem>
</SelectContent>
</Select>
</div>
{error !== "" && <Label className="text-destructive text-sm">{error}</Label>} {error !== "" && <Label className="text-destructive text-sm">{error}</Label>}

View File

@@ -41,7 +41,7 @@ export function Field({
return ( return (
<div className="flex flex-col gap-1 w-full"> <div className="flex flex-col gap-1 w-full">
<div className="flex items-end justify-between w-full text-xs"> <div className="flex items-end justify-between w-full">
<Label htmlFor={label} className="flex items-center text-sm"> <Label htmlFor={label} className="flex items-center text-sm">
{label} {label}
</Label> </Label>