Update formatCurrency to use currency code from UserSettings
Changes: - Updated formatCurrency function: - Added currencyCode parameter with EUR default - Implemented Intl.NumberFormat for proper currency formatting - Added fallback for invalid currency codes - Updated component hierarchy to pass currency: - HomePage: Fetch userSettings and pass to MonthLocationList - MonthLocationList: Accept and pass currency to child components - LocationCard: Accept currency prop and use in formatCurrency - MonthCard: Accept currency prop and use in formatCurrency - ViewLocationCard: Pass currency from userSettings to formatCurrency - Removed hardcoded $ symbols, now using proper currency formatting All currency amounts now display with the user's selected currency code from their settings, using locale-appropriate formatting (hr-HR). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,9 +1,21 @@
|
|||||||
export const formatCurrency = (amount:number) => {
|
export const formatCurrency = (amount: number, currencyCode: string = "EUR") => {
|
||||||
// format number wirh 2 decimal places and a thousand separator
|
// format number with 2 decimal places and a thousand separator
|
||||||
// amount is in cents
|
// amount is in cents
|
||||||
const formattedAmount = (amount/100).toFixed(2).replace(/\d(?=(\d{3})+\.)/g, '$&,');
|
const amountInUnits = amount / 100;
|
||||||
return(formattedAmount);
|
|
||||||
|
// Use Intl.NumberFormat for proper currency formatting
|
||||||
|
try {
|
||||||
|
return new Intl.NumberFormat('hr-HR', {
|
||||||
|
style: 'currency',
|
||||||
|
currency: currencyCode,
|
||||||
|
minimumFractionDigits: 2,
|
||||||
|
maximumFractionDigits: 2,
|
||||||
|
}).format(amountInUnits);
|
||||||
|
} catch (e) {
|
||||||
|
// Fallback if invalid currency code
|
||||||
|
console.error(`Invalid currency code: ${currencyCode}`, e);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Formats an IBAN for display with proper spacing
|
* Formats an IBAN for display with proper spacing
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { fetchAllLocations } from '@/app/lib/actions/locationActions';
|
import { fetchAllLocations } from '@/app/lib/actions/locationActions';
|
||||||
import { fetchAvailableYears } from '@/app/lib/actions/monthActions';
|
import { fetchAvailableYears } from '@/app/lib/actions/monthActions';
|
||||||
|
import { getUserSettings } from '@/app/lib/actions/userSettingsActions';
|
||||||
import { BillingLocation, YearMonth } from '@/app/lib/db-types';
|
import { BillingLocation, YearMonth } from '@/app/lib/db-types';
|
||||||
import { FC } from 'react';
|
import { FC } from 'react';
|
||||||
import { MonthLocationList } from '@/app/ui/MonthLocationList';
|
import { MonthLocationList } from '@/app/ui/MonthLocationList';
|
||||||
@@ -35,6 +36,7 @@ export const HomePage:FC<HomePageProps> = async ({ searchParams }) => {
|
|||||||
const currentYear = Number(searchParams?.year) || new Date().getFullYear();
|
const currentYear = Number(searchParams?.year) || new Date().getFullYear();
|
||||||
|
|
||||||
const locations = await fetchAllLocations(currentYear);
|
const locations = await fetchAllLocations(currentYear);
|
||||||
|
const userSettings = await getUserSettings();
|
||||||
|
|
||||||
// group locations by month
|
// group locations by month
|
||||||
const months = locations.reduce((acc, location) => {
|
const months = locations.reduce((acc, location) => {
|
||||||
@@ -69,7 +71,7 @@ export const HomePage:FC<HomePageProps> = async ({ searchParams }) => {
|
|||||||
} });
|
} });
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MonthLocationList availableYears={availableYears} months={months} />
|
<MonthLocationList availableYears={availableYears} months={months} userSettings={userSettings} />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,10 +11,11 @@ import { useLocale, useTranslations } from "next-intl";
|
|||||||
import { toast } from "react-toastify";
|
import { toast } from "react-toastify";
|
||||||
|
|
||||||
export interface LocationCardProps {
|
export interface LocationCardProps {
|
||||||
location: BillingLocation
|
location: BillingLocation;
|
||||||
|
currency?: string | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const LocationCard:FC<LocationCardProps> = ({location}) => {
|
export const LocationCard:FC<LocationCardProps> = ({location, currency}) => {
|
||||||
const { _id, name, yearMonth, bills, seenByTenant } = location;
|
const { _id, name, yearMonth, bills, seenByTenant } = location;
|
||||||
|
|
||||||
console.log("seenByTenant:", seenByTenant);
|
console.log("seenByTenant:", seenByTenant);
|
||||||
@@ -59,7 +60,7 @@ export const LocationCard:FC<LocationCardProps> = ({location}) => {
|
|||||||
monthlyExpense > 0 ?
|
monthlyExpense > 0 ?
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<BanknotesIcon className="h-5 w-5" />
|
<BanknotesIcon className="h-5 w-5" />
|
||||||
{ t("payed-total-label") } <strong>${formatCurrency(monthlyExpense)}</strong>
|
{ t("payed-total-label") } <strong>{formatCurrency(monthlyExpense, currency ?? "EUR")}</strong>
|
||||||
</div>
|
</div>
|
||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,11 +10,12 @@ export interface MonthCardProps {
|
|||||||
yearMonth: YearMonth,
|
yearMonth: YearMonth,
|
||||||
children?: React.ReactNode,
|
children?: React.ReactNode,
|
||||||
monthlyExpense:number,
|
monthlyExpense:number,
|
||||||
|
currency?: string | null,
|
||||||
expanded?:boolean,
|
expanded?:boolean,
|
||||||
onToggle: (yearMonth:YearMonth) => void
|
onToggle: (yearMonth:YearMonth) => void
|
||||||
}
|
}
|
||||||
|
|
||||||
export const MonthCard:FC<MonthCardProps> = ({ yearMonth, children, monthlyExpense, expanded, onToggle }) => {
|
export const MonthCard:FC<MonthCardProps> = ({ yearMonth, children, monthlyExpense, currency, expanded, onToggle }) => {
|
||||||
|
|
||||||
const elRef = useRef<HTMLDivElement>(null);
|
const elRef = useRef<HTMLDivElement>(null);
|
||||||
const t = useTranslations("home-page.month-card");
|
const t = useTranslations("home-page.month-card");
|
||||||
@@ -38,7 +39,7 @@ export const MonthCard:FC<MonthCardProps> = ({ yearMonth, children, monthlyExpen
|
|||||||
{
|
{
|
||||||
monthlyExpense>0 ?
|
monthlyExpense>0 ?
|
||||||
<p className="text-xs font-medium">
|
<p className="text-xs font-medium">
|
||||||
{t("payed-total-label")} <strong>{ formatCurrency(monthlyExpense) }</strong>
|
{t("payed-total-label")} <strong>{ formatCurrency(monthlyExpense, currency ?? "EUR") }</strong>
|
||||||
</p> : null
|
</p> : null
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import { MonthCard } from "./MonthCard";
|
|||||||
import Pagination from "./Pagination";
|
import Pagination from "./Pagination";
|
||||||
import { LocationCard } from "./LocationCard";
|
import { LocationCard } from "./LocationCard";
|
||||||
import { PrintButton } from "./PrintButton";
|
import { PrintButton } from "./PrintButton";
|
||||||
import { BillingLocation, YearMonth } from "../lib/db-types";
|
import { BillingLocation, UserSettings, YearMonth } from "../lib/db-types";
|
||||||
import { useRouter, useSearchParams } from "next/navigation";
|
import { useRouter, useSearchParams } from "next/navigation";
|
||||||
import { ToastContainer, toast } from 'react-toastify';
|
import { ToastContainer, toast } from 'react-toastify';
|
||||||
import 'react-toastify/dist/ReactToastify.css';
|
import 'react-toastify/dist/ReactToastify.css';
|
||||||
@@ -30,11 +30,13 @@ export interface MonthLocationListProps {
|
|||||||
monthlyExpense: number;
|
monthlyExpense: number;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
userSettings?: UserSettings | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const MonthLocationList:React.FC<MonthLocationListProps > = ({
|
export const MonthLocationList:React.FC<MonthLocationListProps > = ({
|
||||||
availableYears,
|
availableYears,
|
||||||
months,
|
months,
|
||||||
|
userSettings,
|
||||||
}) => {
|
}) => {
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@@ -97,7 +99,7 @@ export const MonthLocationList:React.FC<MonthLocationListProps > = ({
|
|||||||
|
|
||||||
return(
|
return(
|
||||||
<>
|
<>
|
||||||
<MonthCard yearMonth={currentYearMonth} key={`month-${currentYearMonth}`} monthlyExpense={0} onToggle={() => {}} expanded={true} >
|
<MonthCard yearMonth={currentYearMonth} key={`month-${currentYearMonth}`} monthlyExpense={0} currency={userSettings?.currency} onToggle={() => {}} expanded={true} >
|
||||||
<AddLocationButton yearMonth={currentYearMonth} />
|
<AddLocationButton yearMonth={currentYearMonth} />
|
||||||
</MonthCard>
|
</MonthCard>
|
||||||
</>)
|
</>)
|
||||||
@@ -122,10 +124,10 @@ export const MonthLocationList:React.FC<MonthLocationListProps > = ({
|
|||||||
<AddMonthButton yearMonth={getNextYearMonth(monthsArray[0][1].locations[0].yearMonth)} />
|
<AddMonthButton yearMonth={getNextYearMonth(monthsArray[0][1].locations[0].yearMonth)} />
|
||||||
{
|
{
|
||||||
monthsArray.map(([monthKey, { yearMonth, locations, monthlyExpense }], monthIx) =>
|
monthsArray.map(([monthKey, { yearMonth, locations, monthlyExpense }], monthIx) =>
|
||||||
<MonthCard yearMonth={yearMonth} key={`month-${monthKey}`} monthlyExpense={monthlyExpense} expanded={ yearMonth.month === expandedMonth } onToggle={handleMonthToggle} >
|
<MonthCard yearMonth={yearMonth} key={`month-${monthKey}`} monthlyExpense={monthlyExpense} currency={userSettings?.currency} expanded={ yearMonth.month === expandedMonth } onToggle={handleMonthToggle} >
|
||||||
{
|
{
|
||||||
yearMonth.month === expandedMonth ?
|
yearMonth.month === expandedMonth ?
|
||||||
locations.map((location, ix) => <LocationCard key={`location-${location._id}`} location={location} />)
|
locations.map((location, ix) => <LocationCard key={`location-${location._id}`} location={location} currency={userSettings?.currency} />)
|
||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
<div className="flex gap-2 justify-center">
|
<div className="flex gap-2 justify-center">
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ export const ViewLocationCard:FC<ViewLocationCardProps> = ({location, userSettin
|
|||||||
{
|
{
|
||||||
monthlyExpense > 0 ?
|
monthlyExpense > 0 ?
|
||||||
<p className="text-[1.2rem]">
|
<p className="text-[1.2rem]">
|
||||||
{ t("payed-total-label") } <strong>${formatCurrency(monthlyExpense)}</strong>
|
{ t("payed-total-label") } <strong>{formatCurrency(monthlyExpense, userSettings?.currency)}</strong>
|
||||||
</p>
|
</p>
|
||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user