From 5e907d7e53a24f67567d393fc5a3dc708f1ecad3 Mon Sep 17 00:00:00 2001 From: ValdiANS Date: Wed, 15 Apr 2026 16:35:35 +0700 Subject: [PATCH 1/3] feat: create expense navigation helper function --- src/lib/expense-list-navigation.ts | 39 ++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 src/lib/expense-list-navigation.ts diff --git a/src/lib/expense-list-navigation.ts b/src/lib/expense-list-navigation.ts new file mode 100644 index 00000000..a9f24539 --- /dev/null +++ b/src/lib/expense-list-navigation.ts @@ -0,0 +1,39 @@ +type SearchParamsLike = { + get: (name: string) => string | null; +}; + +const EXPENSE_LIST_PATH = '/expense'; + +export const getExpenseListReturnTo = (searchParams: SearchParamsLike) => { + const existingReturnTo = searchParams.get('returnTo'); + + if (existingReturnTo?.startsWith(EXPENSE_LIST_PATH)) { + return existingReturnTo; + } + + const params = new URLSearchParams(); + const page = searchParams.get('page'); + const limit = searchParams.get('limit'); + + if (page) params.set('page', page); + if (limit) params.set('limit', limit); + + const queryString = params.toString(); + + return queryString + ? `${EXPENSE_LIST_PATH}?${queryString}` + : EXPENSE_LIST_PATH; +}; + +export const buildExpenseActionHref = ( + path: string, + expenseId: number | string, + searchParams: SearchParamsLike +) => { + const params = new URLSearchParams({ + expenseId: String(expenseId), + returnTo: getExpenseListReturnTo(searchParams), + }); + + return `${path}?${params.toString()}`; +}; From 7a5ee2aca1f4c6c31811c29a9b04715bb3f8ef11 Mon Sep 17 00:00:00 2001 From: ValdiANS Date: Wed, 15 Apr 2026 16:38:56 +0700 Subject: [PATCH 2/3] feat: implement return to url query param --- .../pages/expense/ExpenseDetail.tsx | 6 +- .../expense/ExpenseRealizationContent.tsx | 12 +- .../pages/expense/ExpenseRequestContent.tsx | 28 +++-- .../pages/expense/ExpensesTable.tsx | 108 +++++++++++++++--- .../expense/form/ExpenseRealizationForm.tsx | 15 ++- 5 files changed, 140 insertions(+), 29 deletions(-) diff --git a/src/components/pages/expense/ExpenseDetail.tsx b/src/components/pages/expense/ExpenseDetail.tsx index 1f43eae1..c09b168a 100644 --- a/src/components/pages/expense/ExpenseDetail.tsx +++ b/src/components/pages/expense/ExpenseDetail.tsx @@ -1,6 +1,7 @@ 'use client'; import { useMemo, useState } from 'react'; +import { useSearchParams } from 'next/navigation'; import { Icon } from '@iconify/react'; import Button from '@/components/Button'; @@ -9,6 +10,7 @@ import ExpenseRequestContent from '@/components/pages/expense/ExpenseRequestCont import ExpenseRealizationContent from '@/components/pages/expense/ExpenseRealizationContent'; import { Expense } from '@/types/api/expense'; +import { getExpenseListReturnTo } from '@/lib/expense-list-navigation'; interface ExpenseDetailProps { initialValues?: Expense; @@ -16,6 +18,8 @@ interface ExpenseDetailProps { const ExpenseDetail: React.FC = ({ initialValues }) => { const [activeTab, setActiveTab] = useState('request'); + const searchParams = useSearchParams(); + const returnTo = getExpenseListReturnTo(searchParams); const expenseDetailTabs = useMemo(() => { const validTabs = [ @@ -46,7 +50,7 @@ const ExpenseDetail: React.FC = ({ initialValues }) => {