refactor(web): enhance ui visual polish and ux

- Replace native selects with Shadcn UI Select in Settings
- Increase ActivityChart height for better visibility
- specific Economy Overview card height to fill column
- Add hover/active scale animations to sidebar items
This commit is contained in:
syntaxbullet
2026-01-08 23:10:14 +01:00
parent 713ea07040
commit 238d9a8803
5 changed files with 227 additions and 29 deletions

View File

@@ -5,6 +5,13 @@ import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Card, CardContent } from "@/components/ui/card";
import { Switch } from "@/components/ui/switch";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@/components/ui/select";
// Types matching the backend response
interface RoleOption { id: string; name: string; color: string; }
@@ -358,20 +365,28 @@ export function Settings() {
})}
</div>
<div className="mt-2">
<select
className="w-full bg-black/20 border border-white/10 rounded-md p-2 text-sm text-white mt-2"
onChange={(e) => {
if (e.target.value && !(config?.colorRoles || []).includes(e.target.value)) {
updateConfig("colorRoles", [...(config?.colorRoles || []), e.target.value]);
<Select
value=""
onValueChange={(value) => {
if (value && !(config?.colorRoles || []).includes(value)) {
updateConfig("colorRoles", [...(config?.colorRoles || []), value]);
}
e.target.value = "";
}}
>
<option value="">+ Add Color Role</option>
{meta.roles.map(r => (
<option key={r.id} value={r.id} style={{ color: r.color }}>{r.name}</option>
))}
</select>
<SelectTrigger className="w-full bg-black/20 border-white/10 text-white/50 h-9">
<SelectValue placeholder="+ Add Color Role" />
</SelectTrigger>
<SelectContent>
{meta.roles.map((r) => (
<SelectItem key={r.id} value={r.id}>
<span className="flex items-center gap-2">
<span className="w-2 h-2 rounded-full" style={{ backgroundColor: r.color || '#999' }} />
{r.name}
</span>
</SelectItem>
))}
</SelectContent>
</Select>
</div>
</div>
</div>
@@ -477,23 +492,18 @@ function SelectField({ label, value, options, onChange }: { label: string, value
return (
<div className="space-y-1.5">
<label className="text-xs font-medium text-white/60 ml-1">{label}</label>
<div className="relative">
<select
value={value || ""}
onChange={(e) => onChange(e.target.value)}
className="flex h-10 w-full rounded-md border border-white/10 bg-black/20 px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 text-white appearance-none"
>
<option value="" className="bg-zinc-900 text-white/50">Select...</option>
<Select value={value || ""} onValueChange={onChange}>
<SelectTrigger className="w-full bg-black/20 border-white/10 text-white">
<SelectValue placeholder="Select..." />
</SelectTrigger>
<SelectContent>
{options.map((opt) => (
<option key={opt.id} value={opt.id} className="bg-zinc-900">
<SelectItem key={opt.id} value={opt.id}>
{opt.name}
</option>
</SelectItem>
))}
</select>
<div className="pointer-events-none absolute inset-y-0 right-0 flex items-center px-2 text-white/50">
<svg className="h-4 w-4 fill-current" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20"><path d="M9.293 12.95l.707.707L15.657 8l-1.414-1.414L10 10.828 5.757 6.586 4.343 8z" /></svg>
</div>
</div>
</SelectContent>
</Select>
</div>
);
}