fix: price labels use user's selected currency instead of hardcoded $
All checks were successful
CI / ci (push) Successful in 1m21s
CI / e2e (push) Has been skipped
CI / deploy (push) Successful in 15s

Replaced hardcoded "Price ($)" labels across 6 components and 2 locale
files to display the user's selected currency (EUR, GBP, USD, etc.).
AddToCollectionModal also updated to show correct currency.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-13 21:33:32 +02:00
parent 23027551b4
commit c4ddc573d4
9 changed files with 23 additions and 9 deletions

View File

@@ -1,6 +1,7 @@
import { useEffect, useState } from "react";
import { toast } from "sonner";
import { useCategories } from "../hooks/useCategories";
import { useCurrency } from "../hooks/useCurrency";
import { useCreateItem } from "../hooks/useItems";
import { useUIStore } from "../stores/uiStore";
import { CategoryPicker } from "./CategoryPicker";
@@ -12,6 +13,7 @@ export function AddToCollectionModal() {
const closeAddToCollection = useUIStore((s) => s.closeAddToCollection);
const { data: categories } = useCategories();
const { currency } = useCurrency();
const createItem = useCreateItem();
const [categoryId, setCategoryId] = useState<number | null>(null);
@@ -127,7 +129,7 @@ export function AddToCollectionModal() {
htmlFor="collection-price"
className="block text-sm font-medium text-gray-700 mb-1"
>
Purchase Price ($)
Purchase Price ({currency})
</label>
<input
id="collection-price"

View File

@@ -1,5 +1,6 @@
import { useEffect, useState } from "react";
import { useCreateCandidate, useUpdateCandidate } from "../hooks/useCandidates";
import { useCurrency } from "../hooks/useCurrency";
import { useThread } from "../hooks/useThreads";
import { CategoryPicker } from "./CategoryPicker";
import { ImageUpload } from "./ImageUpload";
@@ -42,6 +43,7 @@ export function CandidateForm({
onClose,
}: CandidateFormProps) {
const { data: thread } = useThread(threadId);
const { currency } = useCurrency();
const createCandidate = useCreateCandidate(threadId);
const updateCandidate = useUpdateCandidate(threadId);
@@ -204,7 +206,7 @@ export function CandidateForm({
htmlFor="candidate-price"
className="block text-sm font-medium text-gray-700 mb-1"
>
Price ($)
{`Price (${currency})`}
</label>
<input
id="candidate-price"

View File

@@ -1,4 +1,5 @@
import { useEffect, useState } from "react";
import { useCurrency } from "../hooks/useCurrency";
import { useCreateItem, useItems, useUpdateItem } from "../hooks/useItems";
import { useUIStore } from "../stores/uiStore";
import { CategoryPicker } from "./CategoryPicker";
@@ -34,6 +35,7 @@ const INITIAL_FORM: FormData = {
export function ItemForm({ mode, itemId, onClose }: ItemFormProps) {
const { data: items } = useItems();
const { currency } = useCurrency();
const createItem = useCreateItem();
const updateItem = useUpdateItem();
const openConfirmDelete = useUIStore((s) => s.openConfirmDelete);
@@ -192,7 +194,7 @@ export function ItemForm({ mode, itemId, onClose }: ItemFormProps) {
htmlFor="item-price"
className="block text-sm font-medium text-gray-700 mb-1"
>
Price ($)
{`Price (${currency})`}
</label>
<input
id="item-price"

View File

@@ -1,5 +1,6 @@
import { useEffect, useState } from "react";
import { useCategories } from "../hooks/useCategories";
import { useCurrency } from "../hooks/useCurrency";
import { useCreateItem } from "../hooks/useItems";
import { CategoryPicker } from "./CategoryPicker";
import { ImageUpload } from "./ImageUpload";
@@ -14,6 +15,7 @@ export function ManualEntryForm({
onSuccess,
}: ManualEntryFormProps) {
const { data: categories } = useCategories();
const { currency } = useCurrency();
const createItem = useCreateItem();
const [name, setName] = useState(initialName ?? "");
@@ -160,7 +162,7 @@ export function ManualEntryForm({
htmlFor="manual-purchase-price"
className="block text-sm font-medium text-gray-700 mb-1"
>
Purchase Price ($)
{`Purchase Price (${currency})`}
</label>
<input
id="manual-purchase-price"

View File

@@ -13,7 +13,7 @@
"namePlaceholder": "z.B. Osprey Talon 22",
"weight": "Gewicht (g)",
"weightPlaceholder": "z.B. 680",
"price": "Preis ($)",
"price": "Preis",
"pricePlaceholder": "z.B. 129,99",
"quantity": "Menge",
"category": "Kategorie",

View File

@@ -13,7 +13,7 @@
"namePlaceholder": "e.g. Osprey Talon 22",
"weight": "Weight (g)",
"weightPlaceholder": "e.g. 680",
"price": "Price ($)",
"price": "Price",
"pricePlaceholder": "e.g. 129.99",
"quantity": "Quantity",
"category": "Category",

View File

@@ -6,6 +6,7 @@ import { GearImage, imageContainerBg } from "../../components/GearImage";
import { ImageCropEditor } from "../../components/ImageCropEditor";
import { ImageUpload } from "../../components/ImageUpload";
import { useAuth } from "../../hooks/useAuth";
import { useCurrency } from "../../hooks/useCurrency";
import { useFormatters } from "../../hooks/useFormatters";
import { useDuplicateItem, useItem, useUpdateItem } from "../../hooks/useItems";
import { usePublicSetupItem, useSharedSetupItem } from "../../hooks/useSetups";
@@ -39,6 +40,7 @@ function ItemDetail() {
const { setup: setupId, share: shareToken } = Route.useSearch();
const navigate = useNavigate();
const { data: auth } = useAuth();
const { currency } = useCurrency();
const isAuthenticated = !!auth?.user;
// Determine access mode: shared (token), public (setup context, no auth), or owner
@@ -500,7 +502,7 @@ function ItemDetail() {
</div>
<div>
<label className="block text-xs font-medium text-gray-500 mb-1">
Price ($)
{`Price (${currency})`}
</label>
<input
type="number"

View File

@@ -6,6 +6,7 @@ import { ImageCropEditor } from "../../../../components/ImageCropEditor";
import { ImageUpload } from "../../../../components/ImageUpload";
import { StatusBadge } from "../../../../components/StatusBadge";
import { useUpdateCandidate } from "../../../../hooks/useCandidates";
import { useCurrency } from "../../../../hooks/useCurrency";
import { useFormatters } from "../../../../hooks/useFormatters";
import { useThread } from "../../../../hooks/useThreads";
import { LucideIcon } from "../../../../lib/iconData";
@@ -37,6 +38,7 @@ function CandidateDetailPage() {
const { data: thread, isLoading, isError } = useThread(threadId);
const updateCandidate = useUpdateCandidate(threadId);
const { weight, price } = useFormatters();
const { currency } = useCurrency();
const openResolveDialog = useUIStore((s) => s.openResolveDialog);
const openConfirmDeleteCandidate = useUIStore(
(s) => s.openConfirmDeleteCandidate,
@@ -330,7 +332,7 @@ function CandidateDetailPage() {
</div>
<div className="flex items-center gap-2">
<label className="text-xs font-medium text-gray-500">
Price ($)
{`Price (${currency})`}
</label>
<input
type="number"

View File

@@ -12,6 +12,7 @@ import {
useReorderCandidates,
useUpdateCandidate,
} from "../../../hooks/useCandidates";
import { useCurrency } from "../../../hooks/useCurrency";
import { useImpactDeltas } from "../../../hooks/useImpactDeltas";
import { useSetup } from "../../../hooks/useSetups";
import { useThread } from "../../../hooks/useThreads";
@@ -340,6 +341,7 @@ const INITIAL_MODAL_FORM: ModalFormData = {
function AddCandidateModal({ threadId, onClose }: AddCandidateModalProps) {
const createCandidate = useCreateCandidate(threadId);
const { currency } = useCurrency();
const [form, setForm] = useState<ModalFormData>(INITIAL_MODAL_FORM);
const [errors, setErrors] = useState<Record<string, string>>({});
@@ -490,7 +492,7 @@ function AddCandidateModal({ threadId, onClose }: AddCandidateModalProps) {
htmlFor="modal-candidate-price"
className="block text-sm font-medium text-gray-700 mb-1"
>
Price ($)
{`Price (${currency})`}
</label>
<input
id="modal-candidate-price"