feat(web): real inline-SVG icon set (replace emoji); txn detail loading skeleton
This commit is contained in:
parent
06e74b1668
commit
66d82b8b68
6 changed files with 275 additions and 37 deletions
|
|
@ -1,58 +1,59 @@
|
||||||
|
import type { IconName } from "./icons";
|
||||||
|
|
||||||
// Mongolian display name + icon + color for a backend category. Categories are
|
// Mongolian display name + icon + color for a backend category. Categories are
|
||||||
// stored under English names; this is the single place that maps each to how it
|
// stored under English names; this is the single place that maps each to how it
|
||||||
// reads and looks in the UI. Ported from ios/Mercury/Features/Transactions/
|
// reads and looks in the UI. Ported from ios/Mercury/Features/Transactions/
|
||||||
// CategoryStyle.swift — the web has no Seed multicolor-icon catalog, so each
|
// CategoryStyle.swift.
|
||||||
// icon is an emoji + a soft color tint for the category chip.
|
|
||||||
|
|
||||||
export interface CategoryStyle {
|
export interface CategoryStyle {
|
||||||
name: string; // Mongolian display name
|
name: string; // Mongolian display name
|
||||||
emoji: string;
|
icon: IconName;
|
||||||
tint: string; // chip background (soft)
|
tint: string; // chip background (soft)
|
||||||
fg: string; // chip foreground / accent
|
fg: string; // chip foreground / accent
|
||||||
}
|
}
|
||||||
|
|
||||||
const s = (name: string, emoji: string, tint: string, fg: string): CategoryStyle => ({ name, emoji, tint, fg });
|
const s = (name: string, icon: IconName, tint: string, fg: string): CategoryStyle => ({ name, icon, tint, fg });
|
||||||
|
|
||||||
const TABLE: Record<string, CategoryStyle> = {
|
const TABLE: Record<string, CategoryStyle> = {
|
||||||
// Food & drink
|
// Food & drink
|
||||||
"food & drink": s("Хоол хүнс", "🍴", "#FDE8D7", "#B4530A"),
|
"food & drink": s("Хоол хүнс", "utensils", "#FDE8D7", "#B4530A"),
|
||||||
groceries: s("Хүнсний бараа", "🛒", "#E3F0D8", "#3F7A1E"),
|
groceries: s("Хүнсний бараа", "cart", "#E3F0D8", "#3F7A1E"),
|
||||||
dining: s("Хоолны газар", "🍱", "#FDE8D7", "#B4530A"),
|
dining: s("Хоолны газар", "utensils", "#FDE8D7", "#B4530A"),
|
||||||
dinner: s("Оройн хоол", "🍽️", "#FDE8D7", "#B4530A"),
|
dinner: s("Оройн хоол", "utensils", "#FDE8D7", "#B4530A"),
|
||||||
coffee: s("Кофе", "☕", "#EEE3D7", "#7A5230"),
|
coffee: s("Кофе", "coffee", "#EEE3D7", "#7A5230"),
|
||||||
drink: s("Ундаа", "🥤", "#DDEAF6", "#215C9A"),
|
drink: s("Ундаа", "coffee", "#DDEAF6", "#215C9A"),
|
||||||
// Transport
|
// Transport
|
||||||
transport: s("Тээвэр", "🚗", "#DDE6F6", "#2A4B9A"),
|
transport: s("Тээвэр", "car", "#DDE6F6", "#2A4B9A"),
|
||||||
// Bills & services
|
// Bills & services
|
||||||
"bills & services": s("Төлбөр & үйлчилгээ", "💳", "#E7E3F6", "#5B44B0"),
|
"bills & services": s("Төлбөр & үйлчилгээ", "card", "#E7E3F6", "#5B44B0"),
|
||||||
fees: s("Шимтгэл", "🧾", "#EDEBE7", "#6B6257"),
|
fees: s("Шимтгэл", "receipt", "#EDEBE7", "#6B6257"),
|
||||||
insurance: s("Даатгал", "🛡️", "#DFEFEA", "#1E7A63"),
|
insurance: s("Даатгал", "shield", "#DFEFEA", "#1E7A63"),
|
||||||
phone: s("Утас", "📱", "#E1E5EA", "#42505F"),
|
phone: s("Утас", "phone", "#E1E5EA", "#42505F"),
|
||||||
subscriptions: s("Сабскрипшн", "✨", "#F5E7F0", "#9A2E77"),
|
subscriptions: s("Сабскрипшн", "sparkles", "#F5E7F0", "#9A2E77"),
|
||||||
"үйлчилгээ": s("Үйлчилгээ", "🔧", "#EDEBE7", "#6B6257"),
|
"үйлчилгээ": s("Үйлчилгээ", "wrench", "#EDEBE7", "#6B6257"),
|
||||||
// Debt & loans
|
// Debt & loans
|
||||||
"debt & loans": s("Зээл & өр", "🛡️", "#F6E3E3", "#A83232"),
|
"debt & loans": s("Зээл & өр", "shield", "#F6E3E3", "#A83232"),
|
||||||
debt: s("Өр", "🛡️", "#F6E3E3", "#A83232"),
|
debt: s("Өр", "shield", "#F6E3E3", "#A83232"),
|
||||||
loan: s("Зээл", "💳", "#E7E3F6", "#5B44B0"),
|
loan: s("Зээл", "card", "#E7E3F6", "#5B44B0"),
|
||||||
// Shopping
|
// Shopping
|
||||||
shopping: s("Дэлгүүр", "🛍️", "#F5E7F0", "#9A2E77"),
|
shopping: s("Дэлгүүр", "bag", "#F5E7F0", "#9A2E77"),
|
||||||
electronics: s("Цахилгаан бараа", "🖥️", "#E1E5EA", "#42505F"),
|
electronics: s("Цахилгаан бараа", "monitor", "#E1E5EA", "#42505F"),
|
||||||
// Entertainment
|
// Entertainment
|
||||||
entertainment: s("Зугаа цэнгэл", "🎮", "#E7E3F6", "#5B44B0"),
|
entertainment: s("Зугаа цэнгэл", "gamepad", "#E7E3F6", "#5B44B0"),
|
||||||
anime: s("Аниме", "🎮", "#E7E3F6", "#5B44B0"),
|
anime: s("Аниме", "gamepad", "#E7E3F6", "#5B44B0"),
|
||||||
spotify: s("Spotify", "🎵", "#E3F0D8", "#3F7A1E"),
|
spotify: s("Spotify", "sparkles", "#E3F0D8", "#3F7A1E"),
|
||||||
// Health & care
|
// Health & care
|
||||||
fitness: s("Фитнес", "🏋️", "#DDEAF6", "#215C9A"),
|
fitness: s("Фитнес", "dumbbell", "#DDEAF6", "#215C9A"),
|
||||||
haircut: s("Үс засалт", "✂️", "#F5E7F0", "#9A2E77"),
|
haircut: s("Үс засалт", "scissors", "#F5E7F0", "#9A2E77"),
|
||||||
// Money movement / income
|
// Money movement / income
|
||||||
transfers: s("Шилжүүлэг", "🔁", "#E1E5EA", "#42505F"),
|
transfers: s("Шилжүүлэг", "repeat", "#E1E5EA", "#42505F"),
|
||||||
salary: s("Цалин", "💰", "#E3F0D8", "#3F7A1E"),
|
salary: s("Цалин", "wallet", "#E3F0D8", "#3F7A1E"),
|
||||||
// Synthetic budget line for the loan repayment.
|
// Synthetic budget line for the loan repayment.
|
||||||
"зээлийн төлбөр": s("Зээлийн төлбөр", "🛡️", "#F6E3E3", "#A83232"),
|
"зээлийн төлбөр": s("Зээлийн төлбөр", "shield", "#F6E3E3", "#A83232"),
|
||||||
};
|
};
|
||||||
|
|
||||||
const INCOME_FALLBACK = s("Орлого", "💰", "#E3F0D8", "#3F7A1E");
|
const INCOME_FALLBACK = s("Орлого", "wallet", "#E3F0D8", "#3F7A1E");
|
||||||
const OTHER_FALLBACK = s("Бусад", "🧾", "#EDEBE7", "#6B6257");
|
const OTHER_FALLBACK = s("Бусад", "receipt", "#EDEBE7", "#6B6257");
|
||||||
|
|
||||||
/** Look up the style for a backend category name. `income` decides the fallback
|
/** Look up the style for a backend category name. `income` decides the fallback
|
||||||
* when the category is empty or unknown. Mirrors CategoryStyle.of in iOS. */
|
* when the category is empty or unknown. Mirrors CategoryStyle.of in iOS. */
|
||||||
|
|
|
||||||
211
src/ds/icons.tsx
Normal file
211
src/ds/icons.tsx
Normal file
|
|
@ -0,0 +1,211 @@
|
||||||
|
import type { SVGProps } from "react";
|
||||||
|
|
||||||
|
// Clean line-icon set (stroke, currentColor) — a dependency-free stand-in for
|
||||||
|
// the Seed multicolor catalog, which has no web build. 24x24, 1.75 stroke,
|
||||||
|
// round caps/joins. Color via `color` / currentColor; size via `size`.
|
||||||
|
|
||||||
|
export type IconName =
|
||||||
|
| "utensils"
|
||||||
|
| "cart"
|
||||||
|
| "coffee"
|
||||||
|
| "car"
|
||||||
|
| "card"
|
||||||
|
| "shield"
|
||||||
|
| "phone"
|
||||||
|
| "sparkles"
|
||||||
|
| "bag"
|
||||||
|
| "monitor"
|
||||||
|
| "gamepad"
|
||||||
|
| "dumbbell"
|
||||||
|
| "scissors"
|
||||||
|
| "repeat"
|
||||||
|
| "wallet"
|
||||||
|
| "receipt"
|
||||||
|
| "wrench"
|
||||||
|
| "home"
|
||||||
|
| "list"
|
||||||
|
| "calendar-check"
|
||||||
|
| "layers"
|
||||||
|
| "user"
|
||||||
|
| "plus"
|
||||||
|
| "chevron-right"
|
||||||
|
| "chevron-left"
|
||||||
|
| "eye"
|
||||||
|
| "eye-off"
|
||||||
|
| "arrow-up-right"
|
||||||
|
| "arrow-down-left"
|
||||||
|
| "trending"
|
||||||
|
| "hand-coins"
|
||||||
|
| "bank";
|
||||||
|
|
||||||
|
const PATHS: Record<IconName, React.ReactNode> = {
|
||||||
|
utensils: (
|
||||||
|
<>
|
||||||
|
<path d="M4 3v6a2 2 0 0 0 2 2h0a2 2 0 0 0 2-2V3M6 11v10" />
|
||||||
|
<path d="M17 3c-1.5 0-3 1.5-3 4.5S15.5 12 17 12v9" />
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
cart: (
|
||||||
|
<>
|
||||||
|
<circle cx="9" cy="20" r="1.4" />
|
||||||
|
<circle cx="18" cy="20" r="1.4" />
|
||||||
|
<path d="M2 3h2.2l2 12.4a1.5 1.5 0 0 0 1.5 1.2h9.1a1.5 1.5 0 0 0 1.5-1.2L20.5 7H5.2" />
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
coffee: (
|
||||||
|
<>
|
||||||
|
<path d="M4 8h13v5a5 5 0 0 1-5 5H9a5 5 0 0 1-5-5V8Z" />
|
||||||
|
<path d="M17 9h2.5a2.5 2.5 0 0 1 0 5H17" />
|
||||||
|
<path d="M8 2c-.6.8-.6 1.7 0 2.5M12 2c-.6.8-.6 1.7 0 2.5" />
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
car: (
|
||||||
|
<>
|
||||||
|
<path d="M5 12l1.5-4.5A2 2 0 0 1 8.4 6h7.2a2 2 0 0 1 1.9 1.5L19 12" />
|
||||||
|
<path d="M3 12h18v4a1 1 0 0 1-1 1h-1.5M5.5 17H4a1 1 0 0 1-1-1v-4" />
|
||||||
|
<path d="M6.5 17v1.5M17.5 17v1.5" />
|
||||||
|
<circle cx="7" cy="14.5" r=".6" /><circle cx="17" cy="14.5" r=".6" />
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
card: (
|
||||||
|
<>
|
||||||
|
<rect x="2.5" y="5" width="19" height="14" rx="2.5" />
|
||||||
|
<path d="M2.5 9.5h19" />
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
shield: <path d="M12 3l7 2.5v5.5c0 4.4-3 7.6-7 9-4-1.4-7-4.6-7-9V5.5L12 3Z" />,
|
||||||
|
phone: (
|
||||||
|
<>
|
||||||
|
<rect x="6.5" y="2.5" width="11" height="19" rx="2.5" />
|
||||||
|
<path d="M11 18.5h2" />
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
sparkles: (
|
||||||
|
<>
|
||||||
|
<path d="M12 3l1.6 4.4L18 9l-4.4 1.6L12 15l-1.6-4.4L6 9l4.4-1.6L12 3Z" />
|
||||||
|
<path d="M18 14l.8 2.2L21 17l-2.2.8L18 20l-.8-2.2L15 17l2.2-.8L18 14Z" />
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
bag: (
|
||||||
|
<>
|
||||||
|
<path d="M5.5 8h13l-.9 11a2 2 0 0 1-2 1.8H8.4a2 2 0 0 1-2-1.8L5.5 8Z" />
|
||||||
|
<path d="M9 8V6.5a3 3 0 0 1 6 0V8" />
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
monitor: (
|
||||||
|
<>
|
||||||
|
<rect x="3" y="4" width="18" height="12" rx="2" />
|
||||||
|
<path d="M9 20h6M12 16v4" />
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
gamepad: (
|
||||||
|
<>
|
||||||
|
<path d="M7 9h10a4 4 0 0 1 4 4v.5a3.5 3.5 0 0 1-6.3 2.1L14 15h-4l-.7.6A3.5 3.5 0 0 1 3 13.5V13a4 4 0 0 1 4-4Z" />
|
||||||
|
<path d="M7.5 12v2M6.5 13h2M15.5 12.5h.01M17.5 14.5h.01" />
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
dumbbell: (
|
||||||
|
<>
|
||||||
|
<path d="M3 9v6M6 7v10M18 7v10M21 9v6M6 12h12" />
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
scissors: (
|
||||||
|
<>
|
||||||
|
<circle cx="6" cy="6" r="2.2" /><circle cx="6" cy="18" r="2.2" />
|
||||||
|
<path d="M8 7.5 20 18M8 16.5 20 6" />
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
repeat: (
|
||||||
|
<>
|
||||||
|
<path d="M3 12V9a3 3 0 0 1 3-3h11M14 3l3 3-3 3" />
|
||||||
|
<path d="M21 12v3a3 3 0 0 1-3 3H7M10 21l-3-3 3-3" />
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
wallet: (
|
||||||
|
<>
|
||||||
|
<path d="M3.5 7.5A2 2 0 0 1 5.5 5.5h11a1.5 1.5 0 0 1 0 3H4" />
|
||||||
|
<rect x="3" y="7.5" width="18" height="11.5" rx="2.5" />
|
||||||
|
<circle cx="16.5" cy="13.5" r="1.1" />
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
receipt: (
|
||||||
|
<>
|
||||||
|
<path d="M6 3h12v18l-2-1.3-2 1.3-2-1.3-2 1.3-2-1.3L6 21V3Z" />
|
||||||
|
<path d="M9 8h6M9 12h6" />
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
wrench: <path d="M14.5 6.5a3.5 3.5 0 0 0 4.4 4.4l-8.9 8.9a2 2 0 0 1-2.8-2.8l8.9-8.9a3.5 3.5 0 0 0-1.6-1.6Z" />,
|
||||||
|
home: (
|
||||||
|
<>
|
||||||
|
<path d="M4 11 12 4l8 7" />
|
||||||
|
<path d="M6 10v9a1 1 0 0 0 1 1h10a1 1 0 0 0 1-1v-9" />
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
list: <path d="M4 7h16M4 12h16M4 17h16" />,
|
||||||
|
"calendar-check": (
|
||||||
|
<>
|
||||||
|
<rect x="3.5" y="5" width="17" height="16" rx="2.5" />
|
||||||
|
<path d="M3.5 9.5h17M8 3v4M16 3v4M8.5 15l2.2 2.2L15.5 12" />
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
layers: (
|
||||||
|
<>
|
||||||
|
<path d="M12 3 3 8l9 5 9-5-9-5Z" />
|
||||||
|
<path d="M3 13l9 5 9-5M3 18l9 5 9-5" opacity=".5" />
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
user: (
|
||||||
|
<>
|
||||||
|
<circle cx="12" cy="8" r="3.5" />
|
||||||
|
<path d="M5 20a7 7 0 0 1 14 0" />
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
plus: <path d="M12 5v14M5 12h14" />,
|
||||||
|
"chevron-right": <path d="m9 5 7 7-7 7" />,
|
||||||
|
"chevron-left": <path d="m15 5-7 7 7 7" />,
|
||||||
|
eye: (
|
||||||
|
<>
|
||||||
|
<path d="M2.5 12S6 5.5 12 5.5 21.5 12 21.5 12 18 18.5 12 18.5 2.5 12 2.5 12Z" />
|
||||||
|
<circle cx="12" cy="12" r="2.6" />
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
"eye-off": (
|
||||||
|
<>
|
||||||
|
<path d="M4 4l16 16" />
|
||||||
|
<path d="M9.5 9.6A2.6 2.6 0 0 0 12 14.5a2.6 2.6 0 0 0 2.4-1.6M6.5 6.8C4 8.4 2.5 12 2.5 12s3.5 6.5 9.5 6.5c1.5 0 2.8-.4 4-1M16.5 15.2C19 13.6 21.5 12 21.5 12s-3-5.5-8-6.4" />
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
"arrow-up-right": <path d="M7 17 17 7M9 7h8v8" />,
|
||||||
|
"arrow-down-left": <path d="M17 7 7 17M15 17H7V9" />,
|
||||||
|
trending: <path d="m3 16 5-5 4 4 8-8M15 7h6v6" />,
|
||||||
|
"hand-coins": (
|
||||||
|
<>
|
||||||
|
<circle cx="8" cy="6" r="3" />
|
||||||
|
<path d="M13 9h4.5a2 2 0 0 1 0 4H14M3 20l3-3h6a2 2 0 0 0 2-2" />
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
bank: (
|
||||||
|
<>
|
||||||
|
<path d="M3 9.5 12 4l9 5.5M4.5 9.5V18M19.5 9.5V18M8 10v6M12 10v6M16 10v6M3 20h18" />
|
||||||
|
</>
|
||||||
|
),
|
||||||
|
};
|
||||||
|
|
||||||
|
export function Icon({ name, size = 22, ...rest }: { name: IconName; size?: number } & Omit<SVGProps<SVGSVGElement>, "name">) {
|
||||||
|
return (
|
||||||
|
<svg
|
||||||
|
width={size}
|
||||||
|
height={size}
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
strokeWidth={1.75}
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
aria-hidden
|
||||||
|
{...rest}
|
||||||
|
>
|
||||||
|
{PATHS[name]}
|
||||||
|
</svg>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -16,3 +16,4 @@ export type { NameEditProps } from "./NameEdit";
|
||||||
export { Card } from "./Card";
|
export { Card } from "./Card";
|
||||||
export type { CardProps } from "./Card";
|
export type { CardProps } from "./Card";
|
||||||
export * from "./categoryStyle";
|
export * from "./categoryStyle";
|
||||||
|
export * from "./icons";
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import {
|
||||||
DialogDescription,
|
DialogDescription,
|
||||||
DialogFooter,
|
DialogFooter,
|
||||||
DialogAction,
|
DialogAction,
|
||||||
|
Skeleton,
|
||||||
TextFieldRoot,
|
TextFieldRoot,
|
||||||
TextFieldTextarea,
|
TextFieldTextarea,
|
||||||
} from "@seed-design/react";
|
} from "@seed-design/react";
|
||||||
|
|
@ -100,7 +101,7 @@ function DetailRow({
|
||||||
*/
|
*/
|
||||||
export function TransactionDetail({ id }: TransactionDetailProps) {
|
export function TransactionDetail({ id }: TransactionDetailProps) {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { data: transactions } = useTransactions();
|
const { data: transactions, isLoading } = useTransactions();
|
||||||
const { data: categories = [] } = useCategories();
|
const { data: categories = [] } = useCategories();
|
||||||
const categorize = useCategorize();
|
const categorize = useCategorize();
|
||||||
const renameTxn = useRenameTxn();
|
const renameTxn = useRenameTxn();
|
||||||
|
|
@ -132,6 +133,15 @@ export function TransactionDetail({ id }: TransactionDetailProps) {
|
||||||
setEditingNote(false);
|
setEditingNote(false);
|
||||||
}, [id]);
|
}, [id]);
|
||||||
|
|
||||||
|
if (isLoading && !txn) {
|
||||||
|
return (
|
||||||
|
<div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
|
||||||
|
<BackButton onClick={() => router.push("/accounting")} />
|
||||||
|
<Skeleton style={{ height: 300, width: "100%", borderRadius: "var(--seed-radius-r3)" }} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
if (!txn) {
|
if (!txn) {
|
||||||
return (
|
return (
|
||||||
<div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
|
<div style={{ display: "flex", flexDirection: "column", gap: 16 }}>
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@ import { useTransactions } from "@/api/hooks/reads";
|
||||||
import type { Txn } from "@/api/schemas";
|
import type { Txn } from "@/api/schemas";
|
||||||
import { Card, HideAmountsToggle } from "@/ds";
|
import { Card, HideAmountsToggle } from "@/ds";
|
||||||
import { categoryStyle } from "@/ds/categoryStyle";
|
import { categoryStyle } from "@/ds/categoryStyle";
|
||||||
|
import { Icon } from "@/ds/icons";
|
||||||
import { MASKED, tugrikRaw } from "@/ds/money";
|
import { MASKED, tugrikRaw } from "@/ds/money";
|
||||||
import { accountingStrings as s } from "./strings";
|
import { accountingStrings as s } from "./strings";
|
||||||
import { txnRouteId } from "./txnRoute";
|
import { txnRouteId } from "./txnRoute";
|
||||||
|
|
@ -100,11 +101,11 @@ function TxnRow({ txn, hidden }: { txn: Txn; hidden: boolean }) {
|
||||||
borderRadius: 13,
|
borderRadius: 13,
|
||||||
display: "grid",
|
display: "grid",
|
||||||
placeItems: "center",
|
placeItems: "center",
|
||||||
fontSize: 19,
|
color: isTransfer ? "var(--seed-color-fg-neutral-muted, #6b7280)" : cat.fg,
|
||||||
background: isTransfer ? "var(--seed-color-bg-neutral-subtle, #eef0f2)" : cat.tint,
|
background: isTransfer ? "var(--seed-color-bg-neutral-subtle, #eef0f2)" : cat.tint,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{isTransfer ? "🔁" : cat.emoji}
|
<Icon name={isTransfer ? "repeat" : cat.icon} size={20} />
|
||||||
</span>
|
</span>
|
||||||
<div style={{ display: "flex", flexDirection: "column", gap: 2, minWidth: 0 }}>
|
<div style={{ display: "flex", flexDirection: "column", gap: 2, minWidth: 0 }}>
|
||||||
<span style={{ fontSize: 15, fontWeight: 700, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
|
<span style={{ fontSize: 15, fontWeight: 700, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }}>
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ import {
|
||||||
} from "@seed-design/react";
|
} from "@seed-design/react";
|
||||||
import { Card, MercuryButton, HideAmountsToggle, NameEdit } from "@/ds";
|
import { Card, MercuryButton, HideAmountsToggle, NameEdit } from "@/ds";
|
||||||
import { categoryStyle } from "@/ds/categoryStyle";
|
import { categoryStyle } from "@/ds/categoryStyle";
|
||||||
|
import { Icon } from "@/ds/icons";
|
||||||
import { tugrik, tugrikShort } from "@/ds/money";
|
import { tugrik, tugrikShort } from "@/ds/money";
|
||||||
import { useBudget, useNetWorth } from "@/api/hooks/reads";
|
import { useBudget, useNetWorth } from "@/api/hooks/reads";
|
||||||
import { usePutBudget, useSavingsGoalMutations } from "@/api/hooks/mutations";
|
import { usePutBudget, useSavingsGoalMutations } from "@/api/hooks/mutations";
|
||||||
|
|
@ -479,8 +480,21 @@ function CategoryList({
|
||||||
style={{ color: "inherit", textDecoration: "none" }}
|
style={{ color: "inherit", textDecoration: "none" }}
|
||||||
>
|
>
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<span style={{ display: "inline-flex", alignItems: "center", gap: 8, fontWeight: 700 }}>
|
<span style={{ display: "inline-flex", alignItems: "center", gap: 10, fontWeight: 700 }}>
|
||||||
<span aria-hidden>{categoryStyle(row.category).emoji}</span>
|
<span
|
||||||
|
aria-hidden
|
||||||
|
style={{
|
||||||
|
width: 34,
|
||||||
|
height: 34,
|
||||||
|
borderRadius: 11,
|
||||||
|
display: "grid",
|
||||||
|
placeItems: "center",
|
||||||
|
color: categoryStyle(row.category).fg,
|
||||||
|
background: categoryStyle(row.category).tint,
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Icon name={categoryStyle(row.category).icon} size={18} />
|
||||||
|
</span>
|
||||||
{categoryStyle(row.category).name}
|
{categoryStyle(row.category).name}
|
||||||
</span>
|
</span>
|
||||||
<span style={{ fontWeight: 700, color: over ? "var(--seed-color-fg-critical)" : "var(--seed-color-fg-placeholder)" }}>
|
<span style={{ fontWeight: 700, color: over ? "var(--seed-color-fg-critical)" : "var(--seed-color-fg-placeholder)" }}>
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue