Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions docker/dev/compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: split-pro-dev

services:
postgres:
image: ossapps/postgres:17.7-trixie
image: ossapps/postgres:18.3-trixie
container_name: ${POSTGRES_CONTAINER_NAME:-splitpro-db}
restart: always
environment:
Expand All @@ -11,7 +11,7 @@ services:
- POSTGRES_DB=${POSTGRES_DB:-splitpro}
- POSTGRES_PORT=${POSTGRES_PORT:-5432}
volumes:
- database:/var/lib/postgresql/data
- database:/var/lib/postgresql
command: >
postgres
-c shared_preload_libraries=pg_cron
Expand Down
18 changes: 15 additions & 3 deletions src/components/AddExpense/AddExpensePage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,9 @@ import { UploadFile } from './UploadFile';
import { UserInput } from './UserInput';
import { CurrencyInput } from '../ui/currency-input';
import { CurrencyConversion } from '../Friend/CurrencyConversion';
import { currencyConversion, getRatePrecision } from '~/utils/numbers';
import { CURRENCY_CONVERSION_ICON } from '../ui/categoryIcons';
import { currencyConversion } from '~/utils/numbers';
import { CurrencyConversionIcon } from '../ui/categoryIcons';
import { useSession } from 'next-auth/react';

export const AddOrEditExpensePage: React.FC<{
enableSendingInvites: boolean;
Expand Down Expand Up @@ -73,6 +74,7 @@ export const AddOrEditExpensePage: React.FC<{

const addExpenseMutation = api.expense.addOrEditExpense.useMutation();
const updateProfile = api.user.updateUserDetail.useMutation();
const { update } = useSession();

const onCurrencyPick = useCallback(
(newCurrency: CurrencyCode) => {
Expand Down Expand Up @@ -168,6 +170,15 @@ export const AddOrEditExpensePage: React.FC<{

navPromise()
.then(() => resetState())
.then(() =>
update((session: any) => ({
...session,
user: {
...(session?.user ?? {}),
currency,
},
})),
)
.catch(console.error);
}
}
Expand Down Expand Up @@ -206,6 +217,7 @@ export const AddOrEditExpensePage: React.FC<{
cronExpression,
multipleTransactions,
setSingleTransaction,
update,
]);

const handleDescriptionChange = useCallback(
Expand Down Expand Up @@ -261,7 +273,7 @@ export const AddOrEditExpensePage: React.FC<{
editingTargetCurrency={currency}
>
<Button size="icon" variant="secondary" className="size-8">
<CURRENCY_CONVERSION_ICON className="size-4" />
<CurrencyConversionIcon className="size-4" />
</Button>
</CurrencyConversion>
);
Expand Down
21 changes: 19 additions & 2 deletions src/components/AddExpense/CurrencyPicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
import { useTranslationWithUtils } from '~/hooks/useTranslationWithUtils';
import { GeneralPicker } from '../GeneralPicker';
import { Button } from '../ui/button';
import { useCurrencyPreferenceStore } from '~/store/currencyPreferenceStore';

const FRANKFURTER_FILTERED_CURRENCIES = Object.fromEntries(
Object.entries(CURRENCIES).filter(([code]) => FRANKFURTER_CURRENCIES.includes(code)),
Expand All @@ -27,12 +28,14 @@ function CurrencyPickerInner({
showOnlyFrankfurter?: boolean;
}) {
const { t, getCurrencyName } = useTranslationWithUtils(['currencies']);
const { recentCurrencies, addToRecentCurrencies } = useCurrencyPreferenceStore();

const onSelect = useCallback(
(currentValue: string) => {
onCurrencyPick(parseCurrencyCode(currentValue));
addToRecentCurrencies(parseCurrencyCode(currentValue));
},
[onCurrencyPick],
[onCurrencyPick, addToRecentCurrencies],
);

const trigger = useMemo(
Expand Down Expand Up @@ -62,6 +65,20 @@ function CurrencyPickerInner({
},
[getCurrencyName],
);
const recentCurrencyObjects = useMemo(
() => recentCurrencies.map((code) => CURRENCIES[code]),
[recentCurrencies],
);
const items = useMemo(() => {
const baseItems = showOnlyFrankfurter
? Object.values(FRANKFURTER_FILTERED_CURRENCIES)
: Object.values(CURRENCIES);
const uniqueItems = [
...recentCurrencyObjects,
...baseItems.filter((c) => !recentCurrencies.includes(c.code as CurrencyCode)),
];
return uniqueItems;
}, [showOnlyFrankfurter, recentCurrencyObjects, recentCurrencies]);

return (
<GeneralPicker
Expand All @@ -71,7 +88,7 @@ function CurrencyPickerInner({
placeholderText={t('placeholder')}
noOptionsText={t('no_currency_found')}
onSelect={onSelect}
items={Object.values(showOnlyFrankfurter ? FRANKFURTER_FILTERED_CURRENCIES : CURRENCIES)}
items={items}
extractValue={extractValue}
extractKey={extractKey}
selected={selected}
Expand Down
8 changes: 4 additions & 4 deletions src/components/Expense/BalanceList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { CurrencyConversion } from '../Friend/CurrencyConversion';
import { GroupSettleUp } from '../Friend/GroupSettleup';
import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '../ui/accordion';
import { Button } from '../ui/button';
import { CURRENCY_CONVERSION_ICON, SETTLEUP_ICON } from '../ui/categoryIcons';
import { CurrencyConversionIcon, SettleupIcon } from '../ui/categoryIcons';
import { toast } from 'sonner';

interface UserWithBalance {
Expand Down Expand Up @@ -113,7 +113,7 @@ export const BalanceList: React.FC<{
</AccordionTrigger>
<AccordionContent>
{Object.entries(balances).map(([friendId, perFriendBalances]) => {
const friend = userMap[+friendId]!.user;
const friend = userMap[Number(friendId)]!.user;

return (
<Fragment key={friendId}>
Expand Down Expand Up @@ -180,7 +180,7 @@ export const BalanceList: React.FC<{
groupId={groupBalances[0]!.groupId!}
>
<Button size="icon" variant="secondary" className="size-8">
<SETTLEUP_ICON className="size-4" />
<SettleupIcon className="size-4" />
</Button>
</GroupSettleUp>
<CurrencyConversion
Expand All @@ -189,7 +189,7 @@ export const BalanceList: React.FC<{
currency={currency}
>
<Button size="icon" variant="secondary" className="size-8">
<CURRENCY_CONVERSION_ICON className="size-4" />
<CurrencyConversionIcon className="size-4" />
</Button>
</CurrencyConversion>
</div>
Expand Down
10 changes: 3 additions & 7 deletions src/components/Expense/ExpenseList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,7 @@ import Link from 'next/link';
import { useRouter } from 'next/router';
import React from 'react';
import { toast } from 'sonner';
import {
CURRENCY_CONVERSION_ICON,
CategoryIcon,
SETTLEUP_ICON,
} from '~/components/ui/categoryIcons';
import { CategoryIcon, CurrencyConversionIcon, SettleupIcon } from '~/components/ui/categoryIcons';
import { useTranslationWithUtils } from '~/hooks/useTranslationWithUtils';
import { cn } from '~/lib/utils';
import type { ExpenseRouter } from '~/server/api/routers/expense';
Expand Down Expand Up @@ -155,7 +151,7 @@ const Settlement: ExpenseComponent = ({ e, userId }) => {
<div className="inline-block w-6 text-center text-xs text-gray-500">
{toUIDate(e.expenseDate)}
</div>
<SETTLEUP_ICON className="size-5 shrink-0 text-gray-400" />
<SettleupIcon className="size-5 shrink-0 text-gray-400" />
<div>
<p className="flex text-center text-sm text-gray-400">
{displayName(e.paidByUser, userId)}{' '}
Expand Down Expand Up @@ -186,7 +182,7 @@ const CurrencyConversion: ExpenseComponent = ({ e, userId }) => {
<div className="inline-block w-6 text-center text-xs text-gray-500">
{toUIDate(e.expenseDate)}
</div>
<CURRENCY_CONVERSION_ICON className="size-5 shrink-0 text-gray-400" />
<CurrencyConversionIcon className="size-5 shrink-0 text-gray-400" />
<div>
<p className="max-w-[180px] truncate text-sm lg:max-w-md lg:text-base">
{getCurrencyHelpersCached(e.currency).toUIString(e.amount)} ➡️{' '}
Expand Down
8 changes: 4 additions & 4 deletions src/components/ui/categoryIcons.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,17 +101,17 @@ export const CategoryIcons: Record<CategoryItem, LucideIcon> = {
hotel: Hotel,
};

export const CURRENCY_CONVERSION_ICON = DollarSign;
export const CurrencyConversionIcon = DollarSign;

export const SETTLEUP_ICON = HandCoins;
export const SettleupIcon = HandCoins;

export const DEFAULT_CATEGORY_ICON = CategoryIcons[DEFAULT_CATEGORY];
export const DefaultCategoryIcon = CategoryIcons[DEFAULT_CATEGORY];

export const CategoryIcon: React.FC<{ category?: string; splitType?: SplitType } & LucideProps> = ({
category = DEFAULT_CATEGORY,
...props
}) => {
const Icon = CategoryIcons[category as CategoryItem] ?? DEFAULT_CATEGORY_ICON;
const Icon = CategoryIcons[category as CategoryItem] ?? DefaultCategoryIcon;

return <Icon {...props} />;
};
2 changes: 0 additions & 2 deletions src/pages/_app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,6 @@ const Auth: React.FC<{ Page: NextPageWithUser; pageProps: any }> = ({ Page, page

useEffect(() => {
if ('authenticated' === status && data.user) {
setCurrency(parseCurrencyCode(data.user.currency));

if (!data.user.preferredLanguage) {
// If user has no preferred language, set it to the current locale
const currentLocale = router.locale ?? 'en';
Expand Down
1 change: 1 addition & 0 deletions src/pages/auth/VerificationStep.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ const OTPInput = ({ field }) => (
maxLength={5}
pattern={REGEXP_ONLY_DIGITS_AND_CHARS}
inputMode="text"
autoFocus
{...field}
>
<InputOTPGroup>
Expand Down
12 changes: 11 additions & 1 deletion src/store/currencyPreferenceStore.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ const DEFAULT_KEY = 'global';

export type CurrencyPreference = CurrencyCode | typeof SHOW_ALL_VALUE;

const MAX_RECENT_CURRENCIES = 5;

interface CurrencyPreferenceState {
recentCurrencies: CurrencyCode[];
addToRecentCurrencies: (currency: CurrencyCode) => void;
preferences: Record<string, CurrencyPreference>;
setPreference: (key?: number | string, currency?: string) => void;
getPreference: (key?: number | string) => CurrencyPreference;
Expand All @@ -18,7 +22,13 @@ interface CurrencyPreferenceState {
export const useCurrencyPreferenceStore = create<CurrencyPreferenceState>()(
persist(
(set, get) => ({
recentCurrencies: [],
preferences: {},
addToRecentCurrencies: (currency) =>
set((state) => {
const updatedRecent = [currency, ...state.recentCurrencies.filter((c) => c !== currency)];
return { recentCurrencies: updatedRecent.slice(0, MAX_RECENT_CURRENCIES) };
}),
setPreference: (key = DEFAULT_KEY, currency = SHOW_ALL_VALUE) =>
set((state) => ({
preferences: {
Expand All @@ -34,7 +44,7 @@ export const useCurrencyPreferenceStore = create<CurrencyPreferenceState>()(
}),
}),
{
name: 'currency-preferences', // sessionStorage key
name: 'currency-preferences', // SessionStorage key
storage: createJSONStorage(() => sessionStorage),
},
),
Expand Down
Loading