diff --git a/messages/de-DE.json b/messages/de-DE.json index 7557e8d4..c3929531 100644 --- a/messages/de-DE.json +++ b/messages/de-DE.json @@ -189,6 +189,8 @@ "notesField": { "label": "Notizen" }, + "copy": "Kopie", + "duplicate": "Ausgabe duplizieren", "selectNone": "Keine auswählen", "selectAll": "Alle auswählen", "shares": "Anteil(e)", diff --git a/messages/en-US.json b/messages/en-US.json index daaa5be9..753755db 100644 --- a/messages/en-US.json +++ b/messages/en-US.json @@ -190,6 +190,8 @@ "notesField": { "label": "Notes" }, + "copy": "Copy", + "duplicate": "Duplicate expense", "selectNone": "Select none", "selectAll": "Select all", "shares": "share(s)", diff --git a/messages/fr-FR.json b/messages/fr-FR.json index 20bcc34f..fe84179a 100644 --- a/messages/fr-FR.json +++ b/messages/fr-FR.json @@ -189,6 +189,8 @@ "notesField": { "label": "Notes" }, + "copy": "Copie", + "duplicate": "Dupliquer la dépense", "selectNone": "Tout désélectionner", "selectAll": "Tout sélectionner", "shares": "part(s)", diff --git a/messages/pt-BR.json b/messages/pt-BR.json index 326ffc89..2652d2f0 100644 --- a/messages/pt-BR.json +++ b/messages/pt-BR.json @@ -20,6 +20,7 @@ "create": "Criar despesa", "createFirst": "Crie a primeira", "noExpenses": "Seu grupo ainda não contém nenhuma despesa.", + "export": "Exportar", "exportJson": "Exportar para JSON", "exportCsv": "Exportar para CSV", "searchPlaceholder": "Pesquisar por uma despesa…", @@ -161,6 +162,15 @@ "label": "Pago por", "description": "Selecione o participante que pagou a despesa." }, + "recurrenceRule": { + "label": "Recorrência da despesa", + "description": "Selecione a frequência de repetição da despesa.", + + "none": "Nenhuma", + "daily": "Diariamente", + "weekly": "Semanalmente", + "monthly": "Mensalmente" + }, "paidFor": { "title": "Pago para", "description": "Selecione para quem a despesa foi paga." @@ -180,6 +190,8 @@ "notesField": { "label": "Notas" }, + "copy": "Copiar", + "duplicate": "Duplicar", "selectNone": "Remover seleção", "selectAll": "Selecionar todos(as)", "shares": "parte(s)", @@ -357,6 +369,7 @@ "heading": "Vida", "Childcare": "Cuidados infantis", "Clothing": "Roupas", + "Donation": "Doação", "Education": "Educação", "Gifts": "Presentes", "Insurance": "Seguro", diff --git a/src/app/groups/[groupId]/expenses/edit-expense-form.tsx b/src/app/groups/[groupId]/expenses/edit-expense-form.tsx index d762ec44..05e9c97a 100644 --- a/src/app/groups/[groupId]/expenses/edit-expense-form.tsx +++ b/src/app/groups/[groupId]/expenses/edit-expense-form.tsx @@ -1,7 +1,7 @@ 'use client' import { RuntimeFeatureFlags } from '@/lib/featureFlags' import { trpc } from '@/trpc/client' -import { useRouter } from 'next/navigation' +import { useRouter, useSearchParams } from 'next/navigation' import { ExpenseForm } from './expense-form' export function EditExpenseForm({ @@ -25,10 +25,15 @@ export function EditExpenseForm({ }) const expense = expenseData?.expense + const searchParams = useSearchParams() + const isDuplicate = searchParams.get('duplicate') === 'true' + const { mutateAsync: updateExpenseMutateAsync } = trpc.groups.expenses.update.useMutation() const { mutateAsync: deleteExpenseMutateAsync } = trpc.groups.expenses.delete.useMutation() + const { mutateAsync: createExpenseMutateAsync } = + trpc.groups.expenses.create.useMutation() const utils = trpc.useUtils() const router = useRouter() @@ -40,6 +45,7 @@ export function EditExpenseForm({ group={group} expense={expense} categories={categories} + isDuplicate={isDuplicate} onSubmit={async (expenseFormValues, participantId) => { await updateExpenseMutateAsync({ expenseId, @@ -59,6 +65,17 @@ export function EditExpenseForm({ utils.groups.expenses.invalidate() router.push(`/groups/${group.id}`) }} + onDuplicate={async (expenseFormValues, participantId) => { + const newExpense = await createExpenseMutateAsync({ + groupId, + expenseFormValues, + participantId, + }) + utils.groups.expenses.invalidate() + router.push( + `/groups/${group.id}/expenses/${newExpense.expenseId}/edit?duplicate=true`, + ) + }} runtimeFeatureFlags={runtimeFeatureFlags} /> ) diff --git a/src/app/groups/[groupId]/expenses/expense-card.tsx b/src/app/groups/[groupId]/expenses/expense-card.tsx index 0e89c378..1c798ece 100644 --- a/src/app/groups/[groupId]/expenses/expense-card.tsx +++ b/src/app/groups/[groupId]/expenses/expense-card.tsx @@ -80,7 +80,7 @@ export function ExpenseCard({ expense, currency, groupId }: Props) {
- {formatDate(expense.expenseDate, locale, { dateStyle: 'medium' })} + {formatDate(expense.expenseDate, locale, { dateStyle: 'medium', timeZone: 'UTC' })}
+ )} {!isCreate && onDelete && ( onDelete(activeUserId ?? undefined)} > )} - + {!isDuplicate && ( + + )} diff --git a/src/lib/utils.ts b/src/lib/utils.ts index f9493222..4037fbc5 100644 --- a/src/lib/utils.ts +++ b/src/lib/utils.ts @@ -16,7 +16,7 @@ export type DateTimeStyle = NonNullable< export function formatDate( date: Date, locale: string, - options: { dateStyle?: DateTimeStyle; timeStyle?: DateTimeStyle } = {}, + options: { dateStyle?: DateTimeStyle; timeStyle?: DateTimeStyle; timeZone?: string } = {}, ) { return date.toLocaleString(locale, { ...options,