mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
Build issues resolution
This commit is contained in:
@@ -53,13 +53,17 @@ export default function AgentsPage() {
|
|||||||
const actions = [
|
const actions = [
|
||||||
{
|
{
|
||||||
label: 'View Shifts',
|
label: 'View Shifts',
|
||||||
onClick: (agent: any) => window.location.href = `/agents/${agent.id}/shifts`,
|
onClick: (agent: any) => {
|
||||||
|
window.location.href = `/agents/${agent.id}/shifts`;
|
||||||
|
},
|
||||||
variant: 'secondary' as const,
|
variant: 'secondary' as const,
|
||||||
icon: Clock,
|
icon: Clock,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: 'View Commissions',
|
label: 'View Commissions',
|
||||||
onClick: (agent: any) => window.location.href = `/agents/${agent.id}/commissions`,
|
onClick: (agent: any) => {
|
||||||
|
window.location.href = `/agents/${agent.id}/commissions`;
|
||||||
|
},
|
||||||
variant: 'secondary' as const,
|
variant: 'secondary' as const,
|
||||||
icon: DollarSign,
|
icon: DollarSign,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -58,7 +58,9 @@ export default function AuditLogsPage() {
|
|||||||
const actions = [
|
const actions = [
|
||||||
{
|
{
|
||||||
label: 'View Details',
|
label: 'View Details',
|
||||||
onClick: (log: any) => window.location.href = `/audit/${log.id}`,
|
onClick: (log: any) => {
|
||||||
|
window.location.href = `/audit/${log.id}`;
|
||||||
|
},
|
||||||
variant: 'secondary' as const,
|
variant: 'secondary' as const,
|
||||||
icon: Eye,
|
icon: Eye,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -193,7 +193,7 @@ export default function CoachesPage() {
|
|||||||
columns={columns}
|
columns={columns}
|
||||||
data={coaches}
|
data={coaches}
|
||||||
actions={actions}
|
actions={actions}
|
||||||
isLoading={isLoading}
|
loading={isLoading}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ export default function LoyaltyPage() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<DataTable
|
<DataTable
|
||||||
data={data?.items || data || []}
|
data={Array.isArray(data) ? data : (data?.items || [])}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
loading={isLoading}
|
loading={isLoading}
|
||||||
emptyMessage="No loyalty program found"
|
emptyMessage="No loyalty program found"
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ export default function PassengersPage() {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
const actions = [
|
const actions: any[] = [
|
||||||
// TODO: Create passenger detail page
|
// TODO: Create passenger detail page
|
||||||
// {
|
// {
|
||||||
// label: 'View Details',
|
// label: 'View Details',
|
||||||
|
|||||||
@@ -26,6 +26,8 @@ export default function PaymentsPage() {
|
|||||||
{ key: 'createdAt', label: 'Created', render: (payment: any) => formatDateTime(payment.createdAt) },
|
{ key: 'createdAt', label: 'Created', render: (payment: any) => formatDateTime(payment.createdAt) },
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const actions: any[] = [];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
@@ -57,8 +59,9 @@ export default function PaymentsPage() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<DataTable
|
<DataTable
|
||||||
data={data?.items || data || []}
|
data={(data as any)?.items || (Array.isArray(data) ? data : [])}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
|
actions={actions}
|
||||||
loading={isLoading}
|
loading={isLoading}
|
||||||
emptyMessage="No payments found"
|
emptyMessage="No payments found"
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -239,7 +239,7 @@ export default function RoutesPage() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<DataTable
|
<DataTable
|
||||||
data={routes?.items || routes || []}
|
data={(routes as any)?.items || (Array.isArray(routes) ? routes : [])}
|
||||||
columns={routeColumns}
|
columns={routeColumns}
|
||||||
actions={routeActions}
|
actions={routeActions}
|
||||||
loading={routesLoading}
|
loading={routesLoading}
|
||||||
|
|||||||
@@ -264,7 +264,7 @@ export default function SchedulesPage() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<DataTable
|
<DataTable
|
||||||
data={data?.items || data || []}
|
data={(data as any)?.items || (Array.isArray(data) ? data : [])}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
actions={actions}
|
actions={actions}
|
||||||
loading={isLoading}
|
loading={isLoading}
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ export default function SeatClassesPage() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<DataTable
|
<DataTable
|
||||||
data={data?.items || data || []}
|
data={(data as any)?.items || (Array.isArray(data) ? data : [])}
|
||||||
columns={columns}
|
columns={columns}
|
||||||
actions={actions}
|
actions={actions}
|
||||||
loading={isLoading}
|
loading={isLoading}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ export const bookingsApi = {
|
|||||||
getAll: async (params?: any) => {
|
getAll: async (params?: any) => {
|
||||||
const cleanParams = Object.fromEntries(
|
const cleanParams = Object.fromEntries(
|
||||||
Object.entries(params || {}).filter(([_, value]) => value !== '' && value !== undefined && value !== null)
|
Object.entries(params || {}).filter(([_, value]) => value !== '' && value !== undefined && value !== null)
|
||||||
);
|
) as Record<string, string>;
|
||||||
const query = new URLSearchParams(cleanParams).toString();
|
const query = new URLSearchParams(cleanParams).toString();
|
||||||
const response = await apiClient.get<any>(`/bookings${query ? `?${query}` : ''}`);
|
const response = await apiClient.get<any>(`/bookings${query ? `?${query}` : ''}`);
|
||||||
if (response?.data) {
|
if (response?.data) {
|
||||||
@@ -24,7 +24,7 @@ export const passengersApi = {
|
|||||||
getAll: async (params?: any) => {
|
getAll: async (params?: any) => {
|
||||||
const cleanParams = Object.fromEntries(
|
const cleanParams = Object.fromEntries(
|
||||||
Object.entries(params || {}).filter(([_, value]) => value !== '' && value !== undefined && value !== null)
|
Object.entries(params || {}).filter(([_, value]) => value !== '' && value !== undefined && value !== null)
|
||||||
);
|
) as Record<string, string>;
|
||||||
const query = new URLSearchParams(cleanParams).toString();
|
const query = new URLSearchParams(cleanParams).toString();
|
||||||
const response = await apiClient.get<any>(`/passengers${query ? `?${query}` : ''}`);
|
const response = await apiClient.get<any>(`/passengers${query ? `?${query}` : ''}`);
|
||||||
if (response?.data) {
|
if (response?.data) {
|
||||||
@@ -40,7 +40,7 @@ export const stationsApi = {
|
|||||||
getAll: async (params?: any) => {
|
getAll: async (params?: any) => {
|
||||||
const cleanParams = Object.fromEntries(
|
const cleanParams = Object.fromEntries(
|
||||||
Object.entries(params || {}).filter(([_, value]) => value !== '' && value !== undefined && value !== null)
|
Object.entries(params || {}).filter(([_, value]) => value !== '' && value !== undefined && value !== null)
|
||||||
);
|
) as Record<string, string>;
|
||||||
const query = new URLSearchParams(cleanParams).toString();
|
const query = new URLSearchParams(cleanParams).toString();
|
||||||
const response = await apiClient.get<any>(`/stations${query ? `?${query}` : ''}`);
|
const response = await apiClient.get<any>(`/stations${query ? `?${query}` : ''}`);
|
||||||
// Handle wrapped response: { success, data: [...], timestamp }
|
// Handle wrapped response: { success, data: [...], timestamp }
|
||||||
@@ -60,7 +60,7 @@ export const fleetApi = {
|
|||||||
getTrains: async (params?: any) => {
|
getTrains: async (params?: any) => {
|
||||||
const cleanParams = Object.fromEntries(
|
const cleanParams = Object.fromEntries(
|
||||||
Object.entries(params || {}).filter(([_, value]) => value !== '' && value !== undefined && value !== null)
|
Object.entries(params || {}).filter(([_, value]) => value !== '' && value !== undefined && value !== null)
|
||||||
);
|
) as Record<string, string>;
|
||||||
const query = new URLSearchParams(cleanParams).toString();
|
const query = new URLSearchParams(cleanParams).toString();
|
||||||
const response = await apiClient.get<any>(`/fleet/trains${query ? `?${query}` : ''}`);
|
const response = await apiClient.get<any>(`/fleet/trains${query ? `?${query}` : ''}`);
|
||||||
if (response?.data) {
|
if (response?.data) {
|
||||||
@@ -71,7 +71,7 @@ export const fleetApi = {
|
|||||||
getCoaches: async (params?: any) => {
|
getCoaches: async (params?: any) => {
|
||||||
const cleanParams = Object.fromEntries(
|
const cleanParams = Object.fromEntries(
|
||||||
Object.entries(params || {}).filter(([_, value]) => value !== '' && value !== undefined && value !== null)
|
Object.entries(params || {}).filter(([_, value]) => value !== '' && value !== undefined && value !== null)
|
||||||
);
|
) as Record<string, string>;
|
||||||
const query = new URLSearchParams(cleanParams).toString();
|
const query = new URLSearchParams(cleanParams).toString();
|
||||||
const response = await apiClient.get<any>(`/fleet/coaches${query ? `?${query}` : ''}`);
|
const response = await apiClient.get<any>(`/fleet/coaches${query ? `?${query}` : ''}`);
|
||||||
if (response?.data) {
|
if (response?.data) {
|
||||||
@@ -90,7 +90,7 @@ export const fleetApi = {
|
|||||||
// Schedules API
|
// Schedules API
|
||||||
export const schedulesApi = {
|
export const schedulesApi = {
|
||||||
getAll: async (params?: any) => {
|
getAll: async (params?: any) => {
|
||||||
const query = new URLSearchParams(params).toString();
|
const query = new URLSearchParams(params as Record<string, string>).toString();
|
||||||
const response = await apiClient.get<any>(`/schedules${query ? `?${query}` : ''}`);
|
const response = await apiClient.get<any>(`/schedules${query ? `?${query}` : ''}`);
|
||||||
if (response?.data) {
|
if (response?.data) {
|
||||||
return Array.isArray(response.data) ? { items: response.data } : response;
|
return Array.isArray(response.data) ? { items: response.data } : response;
|
||||||
@@ -125,7 +125,7 @@ export const seatsApi = {
|
|||||||
// Payments API
|
// Payments API
|
||||||
export const paymentsApi = {
|
export const paymentsApi = {
|
||||||
getAll: async (params?: any) => {
|
getAll: async (params?: any) => {
|
||||||
const query = new URLSearchParams(params).toString();
|
const query = new URLSearchParams(params as Record<string, string>).toString();
|
||||||
const response = await apiClient.get<any>(`/payments${query ? `?${query}` : ''}`);
|
const response = await apiClient.get<any>(`/payments${query ? `?${query}` : ''}`);
|
||||||
if (response?.data) {
|
if (response?.data) {
|
||||||
return Array.isArray(response.data) ? { items: response.data } : response;
|
return Array.isArray(response.data) ? { items: response.data } : response;
|
||||||
@@ -140,7 +140,7 @@ export const paymentsApi = {
|
|||||||
// Tickets API
|
// Tickets API
|
||||||
export const ticketsApi = {
|
export const ticketsApi = {
|
||||||
getAll: async (params?: any) => {
|
getAll: async (params?: any) => {
|
||||||
const query = new URLSearchParams(params).toString();
|
const query = new URLSearchParams(params as Record<string, string>).toString();
|
||||||
const response = await apiClient.get<any>(`/tickets${query ? `?${query}` : ''}`);
|
const response = await apiClient.get<any>(`/tickets${query ? `?${query}` : ''}`);
|
||||||
if (response?.data) {
|
if (response?.data) {
|
||||||
return Array.isArray(response.data) ? { items: response.data } : response;
|
return Array.isArray(response.data) ? { items: response.data } : response;
|
||||||
@@ -155,7 +155,7 @@ export const ticketsApi = {
|
|||||||
// Agents API
|
// Agents API
|
||||||
export const agentsApi = {
|
export const agentsApi = {
|
||||||
getAll: async (params?: any) => {
|
getAll: async (params?: any) => {
|
||||||
const query = new URLSearchParams(params).toString();
|
const query = new URLSearchParams(params as Record<string, string>).toString();
|
||||||
const response = await apiClient.get<any>(`/agents${query ? `?${query}` : ''}`);
|
const response = await apiClient.get<any>(`/agents${query ? `?${query}` : ''}`);
|
||||||
if (response?.data) {
|
if (response?.data) {
|
||||||
return Array.isArray(response.data) ? { items: response.data } : response;
|
return Array.isArray(response.data) ? { items: response.data } : response;
|
||||||
@@ -174,7 +174,7 @@ export const agentsApi = {
|
|||||||
// Loyalty API
|
// Loyalty API
|
||||||
export const loyaltyApi = {
|
export const loyaltyApi = {
|
||||||
getAccounts: async (params?: any) => {
|
getAccounts: async (params?: any) => {
|
||||||
const query = new URLSearchParams(params).toString();
|
const query = new URLSearchParams(params as Record<string, string>).toString();
|
||||||
const response = await apiClient.get<any>(`/loyalty/accounts${query ? `?${query}` : ''}`);
|
const response = await apiClient.get<any>(`/loyalty/accounts${query ? `?${query}` : ''}`);
|
||||||
if (response?.data) {
|
if (response?.data) {
|
||||||
return Array.isArray(response.data) ? { items: response.data } : response;
|
return Array.isArray(response.data) ? { items: response.data } : response;
|
||||||
@@ -190,7 +190,7 @@ export const loyaltyApi = {
|
|||||||
// Wallet API
|
// Wallet API
|
||||||
export const walletApi = {
|
export const walletApi = {
|
||||||
getAccounts: async (params?: any) => {
|
getAccounts: async (params?: any) => {
|
||||||
const query = new URLSearchParams(params).toString();
|
const query = new URLSearchParams(params as Record<string, string>).toString();
|
||||||
const response = await apiClient.get<any>(`/wallet/accounts${query ? `?${query}` : ''}`);
|
const response = await apiClient.get<any>(`/wallet/accounts${query ? `?${query}` : ''}`);
|
||||||
if (response?.data) {
|
if (response?.data) {
|
||||||
return Array.isArray(response.data) ? { items: response.data } : response;
|
return Array.isArray(response.data) ? { items: response.data } : response;
|
||||||
@@ -205,7 +205,7 @@ export const walletApi = {
|
|||||||
// Promotions API
|
// Promotions API
|
||||||
export const promotionsApi = {
|
export const promotionsApi = {
|
||||||
getAll: async (params?: any) => {
|
getAll: async (params?: any) => {
|
||||||
const query = new URLSearchParams(params).toString();
|
const query = new URLSearchParams(params as Record<string, string>).toString();
|
||||||
const response = await apiClient.get<any>(`/promos${query ? `?${query}` : ''}`);
|
const response = await apiClient.get<any>(`/promos${query ? `?${query}` : ''}`);
|
||||||
if (response?.data) {
|
if (response?.data) {
|
||||||
return Array.isArray(response.data) ? { items: response.data } : response;
|
return Array.isArray(response.data) ? { items: response.data } : response;
|
||||||
@@ -221,7 +221,7 @@ export const promotionsApi = {
|
|||||||
// Support API
|
// Support API
|
||||||
export const supportApi = {
|
export const supportApi = {
|
||||||
getConversations: async (params?: any) => {
|
getConversations: async (params?: any) => {
|
||||||
const query = new URLSearchParams(params).toString();
|
const query = new URLSearchParams(params as Record<string, string>).toString();
|
||||||
const response = await apiClient.get<any>(`/support/conversations${query ? `?${query}` : ''}`);
|
const response = await apiClient.get<any>(`/support/conversations${query ? `?${query}` : ''}`);
|
||||||
if (response?.data) {
|
if (response?.data) {
|
||||||
return Array.isArray(response.data) ? { items: response.data } : response;
|
return Array.isArray(response.data) ? { items: response.data } : response;
|
||||||
@@ -242,7 +242,7 @@ export const notificationsApi = {
|
|||||||
updateTemplate: (id: string, data: any) => apiClient.patch<any>(`/notifications/templates/${id}`, data),
|
updateTemplate: (id: string, data: any) => apiClient.patch<any>(`/notifications/templates/${id}`, data),
|
||||||
send: (data: any) => apiClient.post<any>('/notifications/send', data),
|
send: (data: any) => apiClient.post<any>('/notifications/send', data),
|
||||||
getHistory: async (params?: any) => {
|
getHistory: async (params?: any) => {
|
||||||
const query = new URLSearchParams(params).toString();
|
const query = new URLSearchParams(params as Record<string, string>).toString();
|
||||||
const response = await apiClient.get<any>(`/notifications/history${query ? `?${query}` : ''}`);
|
const response = await apiClient.get<any>(`/notifications/history${query ? `?${query}` : ''}`);
|
||||||
if (response?.data) {
|
if (response?.data) {
|
||||||
return Array.isArray(response.data) ? { items: response.data } : response;
|
return Array.isArray(response.data) ? { items: response.data } : response;
|
||||||
@@ -254,7 +254,7 @@ export const notificationsApi = {
|
|||||||
// Fraud API
|
// Fraud API
|
||||||
export const fraudApi = {
|
export const fraudApi = {
|
||||||
getAlerts: async (params?: any) => {
|
getAlerts: async (params?: any) => {
|
||||||
const query = new URLSearchParams(params).toString();
|
const query = new URLSearchParams(params as Record<string, string>).toString();
|
||||||
const response = await apiClient.get<any>(`/fraud/alerts${query ? `?${query}` : ''}`);
|
const response = await apiClient.get<any>(`/fraud/alerts${query ? `?${query}` : ''}`);
|
||||||
if (response?.data) {
|
if (response?.data) {
|
||||||
return Array.isArray(response.data) ? { items: response.data } : response;
|
return Array.isArray(response.data) ? { items: response.data } : response;
|
||||||
@@ -270,7 +270,7 @@ export const fraudApi = {
|
|||||||
// Verifayda API
|
// Verifayda API
|
||||||
export const verifaydaApi = {
|
export const verifaydaApi = {
|
||||||
getVerifications: async (params?: any) => {
|
getVerifications: async (params?: any) => {
|
||||||
const query = new URLSearchParams(params).toString();
|
const query = new URLSearchParams(params as Record<string, string>).toString();
|
||||||
const response = await apiClient.get<any>(`/passengers/verifications${query ? `?${query}` : ''}`);
|
const response = await apiClient.get<any>(`/passengers/verifications${query ? `?${query}` : ''}`);
|
||||||
if (response?.data) {
|
if (response?.data) {
|
||||||
return Array.isArray(response.data) ? { items: response.data } : response;
|
return Array.isArray(response.data) ? { items: response.data } : response;
|
||||||
@@ -284,7 +284,7 @@ export const verifaydaApi = {
|
|||||||
// Audit API
|
// Audit API
|
||||||
export const auditApi = {
|
export const auditApi = {
|
||||||
getLogs: async (params?: any) => {
|
getLogs: async (params?: any) => {
|
||||||
const query = new URLSearchParams(params).toString();
|
const query = new URLSearchParams(params as Record<string, string>).toString();
|
||||||
const response = await apiClient.get<any>(`/audit/logs${query ? `?${query}` : ''}`);
|
const response = await apiClient.get<any>(`/audit/logs${query ? `?${query}` : ''}`);
|
||||||
if (response?.data) {
|
if (response?.data) {
|
||||||
return Array.isArray(response.data) ? { items: response.data } : response;
|
return Array.isArray(response.data) ? { items: response.data } : response;
|
||||||
@@ -316,7 +316,7 @@ export const foodApi = {
|
|||||||
getCategories: () => apiClient.get<any[]>('/food/categories'),
|
getCategories: () => apiClient.get<any[]>('/food/categories'),
|
||||||
getMenuItems: (scheduleId: string) => apiClient.get<any[]>(`/food/menu/${scheduleId}`),
|
getMenuItems: (scheduleId: string) => apiClient.get<any[]>(`/food/menu/${scheduleId}`),
|
||||||
getOrders: async (params?: any) => {
|
getOrders: async (params?: any) => {
|
||||||
const query = new URLSearchParams(params).toString();
|
const query = new URLSearchParams(params as Record<string, string>).toString();
|
||||||
const response = await apiClient.get<any>(`/food/orders${query ? `?${query}` : ''}`);
|
const response = await apiClient.get<any>(`/food/orders${query ? `?${query}` : ''}`);
|
||||||
if (response?.data) {
|
if (response?.data) {
|
||||||
return Array.isArray(response.data) ? { items: response.data } : response;
|
return Array.isArray(response.data) ? { items: response.data } : response;
|
||||||
@@ -330,7 +330,7 @@ export const foodApi = {
|
|||||||
// Reports API
|
// Reports API
|
||||||
export const reportsApi = {
|
export const reportsApi = {
|
||||||
getOperationalReports: async (params?: any) => {
|
getOperationalReports: async (params?: any) => {
|
||||||
const query = new URLSearchParams(params).toString();
|
const query = new URLSearchParams(params as Record<string, string>).toString();
|
||||||
const response = await apiClient.get<any>(`/reports/operational${query ? `?${query}` : ''}`);
|
const response = await apiClient.get<any>(`/reports/operational${query ? `?${query}` : ''}`);
|
||||||
if (response?.data) {
|
if (response?.data) {
|
||||||
return Array.isArray(response.data) ? { items: response.data } : response;
|
return Array.isArray(response.data) ? { items: response.data } : response;
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
|
export const dynamic = 'force-dynamic';
|
||||||
|
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
import { useBookingStore } from '@/lib/booking-store';
|
import { useBookingStore } from '@/lib/booking-store';
|
||||||
import { useMutation, useQuery } from '@tanstack/react-query';
|
import { useMutation, useQuery } from '@tanstack/react-query';
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
|
export const dynamic = 'force-dynamic';
|
||||||
|
|
||||||
import { useForm, useFieldArray } from 'react-hook-form';
|
import { useForm, useFieldArray } from 'react-hook-form';
|
||||||
import { zodResolver } from '@hookform/resolvers/zod';
|
import { zodResolver } from '@hookform/resolvers/zod';
|
||||||
import { z } from 'zod';
|
import { z } from 'zod';
|
||||||
@@ -110,6 +112,8 @@ export default function PassengersPage() {
|
|||||||
}, [isAuthenticated, user, searchCriteria, setValue]);
|
}, [isAuthenticated, user, searchCriteria, setValue]);
|
||||||
|
|
||||||
const openFaydaVerification = async (index: number) => {
|
const openFaydaVerification = async (index: number) => {
|
||||||
|
if (typeof window === 'undefined') return; // Guard for SSR
|
||||||
|
|
||||||
const faydaUrl = process.env.NEXT_PUBLIC_FAYDA_URL || 'https://fayda.gov.et/verify';
|
const faydaUrl = process.env.NEXT_PUBLIC_FAYDA_URL || 'https://fayda.gov.et/verify';
|
||||||
const callbackUrl = `${window.location.origin}/booking/passengers?faydaCallback=${index}`;
|
const callbackUrl = `${window.location.origin}/booking/passengers?faydaCallback=${index}`;
|
||||||
const width = 600;
|
const width = 600;
|
||||||
@@ -185,10 +189,14 @@ export default function PassengersPage() {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
// Save passenger details to database before proceeding
|
// Save passenger details to database before proceeding
|
||||||
|
const deviceId = typeof window !== 'undefined'
|
||||||
|
? (localStorage.getItem('deviceId') || crypto.randomUUID())
|
||||||
|
: crypto.randomUUID();
|
||||||
|
|
||||||
await apiClient.post('/passengers/save-details', {
|
await apiClient.post('/passengers/save-details', {
|
||||||
passengers: passengerDetails,
|
passengers: passengerDetails,
|
||||||
userId: user?.id,
|
userId: user?.id,
|
||||||
deviceId: localStorage.getItem('deviceId') || crypto.randomUUID(),
|
deviceId,
|
||||||
});
|
});
|
||||||
|
|
||||||
setPassengers(passengerDetails);
|
setPassengers(passengerDetails);
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import { Suspense } from 'react';
|
||||||
|
|
||||||
|
export default function ResultsLayout({ children }: { children: React.ReactNode }) {
|
||||||
|
return <Suspense fallback={<div className="min-h-screen bg-gray-50 dark:bg-gray-900 flex items-center justify-center"><p className="text-gray-600 dark:text-gray-400">Loading...</p></div>}>{children}</Suspense>;
|
||||||
|
}
|
||||||
@@ -174,8 +174,8 @@ export default function ReviewPage() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Save deviceId for future use
|
// Save deviceId for future use
|
||||||
if (typeof window !== 'undefined' && !localStorage.getItem('deviceId')) {
|
if (typeof window !== 'undefined' && bookingData.deviceId && !localStorage.getItem('deviceId')) {
|
||||||
localStorage.setItem('deviceId', bookingData.deviceId!);
|
localStorage.setItem('deviceId', bookingData.deviceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('Creating booking with payload:', bookingData);
|
console.log('Creating booking with payload:', bookingData);
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
import { Suspense } from 'react';
|
||||||
|
|
||||||
|
export default function SearchLayout({ children }: { children: React.ReactNode }) {
|
||||||
|
return <Suspense fallback={<div className="min-h-screen bg-gray-50 dark:bg-gray-900 flex items-center justify-center"><p className="text-gray-600 dark:text-gray-400">Loading...</p></div>}>{children}</Suspense>;
|
||||||
|
}
|
||||||
@@ -1,5 +1,7 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
|
export const dynamic = 'force-dynamic';
|
||||||
|
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
import { useBookingStore } from '@/lib/booking-store';
|
import { useBookingStore } from '@/lib/booking-store';
|
||||||
import { useQuery, useMutation } from '@tanstack/react-query';
|
import { useQuery, useMutation } from '@tanstack/react-query';
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import { z } from 'zod';
|
|||||||
import { useRouter, useSearchParams } from 'next/navigation';
|
import { useRouter, useSearchParams } from 'next/navigation';
|
||||||
import { useAuthStore } from '@/lib/auth-store';
|
import { useAuthStore } from '@/lib/auth-store';
|
||||||
import { useBookingStore } from '@/lib/booking-store';
|
import { useBookingStore } from '@/lib/booking-store';
|
||||||
import { useState } from 'react';
|
import { useState, Suspense } from 'react';
|
||||||
import { Train } from 'lucide-react';
|
import { Train } from 'lucide-react';
|
||||||
|
|
||||||
const loginSchema = z.object({
|
const loginSchema = z.object({
|
||||||
@@ -16,7 +16,7 @@ const loginSchema = z.object({
|
|||||||
|
|
||||||
type LoginForm = z.infer<typeof loginSchema>;
|
type LoginForm = z.infer<typeof loginSchema>;
|
||||||
|
|
||||||
export default function LoginPage() {
|
function LoginContent() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const searchParams = useSearchParams();
|
const searchParams = useSearchParams();
|
||||||
const login = useAuthStore((s) => s.login);
|
const login = useAuthStore((s) => s.login);
|
||||||
@@ -110,3 +110,18 @@ export default function LoginPage() {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export default function LoginPage() {
|
||||||
|
return (
|
||||||
|
<Suspense fallback={
|
||||||
|
<div className="min-h-screen bg-gradient-to-br from-primary-50 to-primary-100 dark:from-gray-900 dark:to-gray-800 flex items-center justify-center">
|
||||||
|
<div className="text-center">
|
||||||
|
<Train className="w-12 h-12 text-primary animate-pulse mx-auto mb-4" />
|
||||||
|
<p className="text-gray-600 dark:text-gray-400">Loading...</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}>
|
||||||
|
<LoginContent />
|
||||||
|
</Suspense>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ export const useAuthStore = create<AuthState>((set, get) => ({
|
|||||||
},
|
},
|
||||||
|
|
||||||
fetchProfile: async () => {
|
fetchProfile: async () => {
|
||||||
|
if (typeof window === 'undefined') return;
|
||||||
const token = localStorage.getItem('auth_token');
|
const token = localStorage.getItem('auth_token');
|
||||||
if (!token) return;
|
if (!token) return;
|
||||||
|
|
||||||
@@ -76,13 +77,17 @@ export const useAuthStore = create<AuthState>((set, get) => ({
|
|||||||
});
|
});
|
||||||
const userData = response.data || response;
|
const userData = response.data || response;
|
||||||
|
|
||||||
localStorage.setItem('auth_user', JSON.stringify(userData));
|
if (typeof window !== 'undefined') {
|
||||||
|
localStorage.setItem('auth_user', JSON.stringify(userData));
|
||||||
|
}
|
||||||
set({ user: userData });
|
set({ user: userData });
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
// If 401, token is invalid - logout
|
// If 401, token is invalid - logout
|
||||||
if (error.response?.status === 401) {
|
if (error.response?.status === 401) {
|
||||||
localStorage.removeItem('auth_token');
|
if (typeof window !== 'undefined') {
|
||||||
localStorage.removeItem('auth_user');
|
localStorage.removeItem('auth_token');
|
||||||
|
localStorage.removeItem('auth_user');
|
||||||
|
}
|
||||||
set({ user: null, token: null, isAuthenticated: false });
|
set({ user: null, token: null, isAuthenticated: false });
|
||||||
}
|
}
|
||||||
throw error;
|
throw error;
|
||||||
@@ -93,8 +98,10 @@ export const useAuthStore = create<AuthState>((set, get) => ({
|
|||||||
const response: any = await apiClient.post('/auth/login', { email, password });
|
const response: any = await apiClient.post('/auth/login', { email, password });
|
||||||
const { token, user } = response.data || response;
|
const { token, user } = response.data || response;
|
||||||
|
|
||||||
localStorage.setItem('auth_token', token);
|
if (typeof window !== 'undefined') {
|
||||||
localStorage.setItem('auth_user', JSON.stringify(user));
|
localStorage.setItem('auth_token', token);
|
||||||
|
localStorage.setItem('auth_user', JSON.stringify(user));
|
||||||
|
}
|
||||||
|
|
||||||
set({ user, token, isAuthenticated: true });
|
set({ user, token, isAuthenticated: true });
|
||||||
},
|
},
|
||||||
@@ -103,15 +110,17 @@ export const useAuthStore = create<AuthState>((set, get) => ({
|
|||||||
const response: any = await apiClient.post('/auth/register', data);
|
const response: any = await apiClient.post('/auth/register', data);
|
||||||
const { token, user } = response.data || response;
|
const { token, user } = response.data || response;
|
||||||
|
|
||||||
localStorage.setItem('auth_token', token);
|
if (typeof window !== 'undefined') {
|
||||||
localStorage.setItem('auth_user', JSON.stringify(user));
|
localStorage.setItem('auth_token', token);
|
||||||
|
localStorage.setItem('auth_user', JSON.stringify(user));
|
||||||
|
}
|
||||||
|
|
||||||
set({ user, token, isAuthenticated: true });
|
set({ user, token, isAuthenticated: true });
|
||||||
},
|
},
|
||||||
|
|
||||||
logout: async () => {
|
logout: async () => {
|
||||||
try {
|
try {
|
||||||
const token = localStorage.getItem('auth_token');
|
const token = typeof window !== 'undefined' ? localStorage.getItem('auth_token') : null;
|
||||||
if (token) {
|
if (token) {
|
||||||
// Call logout endpoint to invalidate session on backend
|
// Call logout endpoint to invalidate session on backend
|
||||||
await apiClient.post('/auth/logout', {}, {
|
await apiClient.post('/auth/logout', {}, {
|
||||||
@@ -126,8 +135,10 @@ export const useAuthStore = create<AuthState>((set, get) => ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Clear local storage and state
|
// Clear local storage and state
|
||||||
localStorage.removeItem('auth_token');
|
if (typeof window !== 'undefined') {
|
||||||
localStorage.removeItem('auth_user');
|
localStorage.removeItem('auth_token');
|
||||||
|
localStorage.removeItem('auth_user');
|
||||||
|
}
|
||||||
set({ user: null, token: null, isAuthenticated: false });
|
set({ user: null, token: null, isAuthenticated: false });
|
||||||
|
|
||||||
// Redirect to home page after state is updated
|
// Redirect to home page after state is updated
|
||||||
@@ -139,16 +150,20 @@ export const useAuthStore = create<AuthState>((set, get) => ({
|
|||||||
},
|
},
|
||||||
|
|
||||||
setUser: (user: User, token: string) => {
|
setUser: (user: User, token: string) => {
|
||||||
localStorage.setItem('auth_token', token);
|
if (typeof window !== 'undefined') {
|
||||||
localStorage.setItem('auth_user', JSON.stringify(user));
|
localStorage.setItem('auth_token', token);
|
||||||
|
localStorage.setItem('auth_user', JSON.stringify(user));
|
||||||
|
}
|
||||||
set({ user, token, isAuthenticated: true });
|
set({ user, token, isAuthenticated: true });
|
||||||
},
|
},
|
||||||
|
|
||||||
updateUser: (userData: Partial<User>) => {
|
updateUser: (userData: Partial<User>) => {
|
||||||
const currentUser = JSON.parse(localStorage.getItem('auth_user') || '{}');
|
if (typeof window !== 'undefined') {
|
||||||
const updatedUser = { ...currentUser, ...userData };
|
const currentUser = JSON.parse(localStorage.getItem('auth_user') || '{}');
|
||||||
localStorage.setItem('auth_user', JSON.stringify(updatedUser));
|
const updatedUser = { ...currentUser, ...userData };
|
||||||
set({ user: updatedUser });
|
localStorage.setItem('auth_user', JSON.stringify(updatedUser));
|
||||||
|
set({ user: updatedUser });
|
||||||
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -102,6 +102,15 @@ export const useBookingStore = create<BookingState>()(persist(
|
|||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
name: 'booking-storage',
|
name: 'booking-storage',
|
||||||
storage: createJSONStorage(() => localStorage),
|
storage: createJSONStorage(() => {
|
||||||
|
if (typeof window !== 'undefined') {
|
||||||
|
return localStorage;
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
getItem: () => null,
|
||||||
|
setItem: () => {},
|
||||||
|
removeItem: () => {},
|
||||||
|
};
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
));
|
));
|
||||||
|
|||||||
@@ -61,6 +61,8 @@ services:
|
|||||||
TURBO_FILTER: "@edr/passenger-portal"
|
TURBO_FILTER: "@edr/passenger-portal"
|
||||||
APP_PATH: apps/edr-passenger-web/portal
|
APP_PATH: apps/edr-passenger-web/portal
|
||||||
VITE_API_URL: ${PASSENGER_VITE_API_URL:-http://localhost:4000}
|
VITE_API_URL: ${PASSENGER_VITE_API_URL:-http://localhost:4000}
|
||||||
|
secrets:
|
||||||
|
- npmrc
|
||||||
ports:
|
ports:
|
||||||
- "${PASSENGER_PORTAL_PORT:-5174}:80"
|
- "${PASSENGER_PORTAL_PORT:-5174}:80"
|
||||||
|
|
||||||
@@ -72,6 +74,8 @@ services:
|
|||||||
TURBO_FILTER: "@edr/passenger-backoffice"
|
TURBO_FILTER: "@edr/passenger-backoffice"
|
||||||
APP_PATH: apps/edr-passenger-web/backoffice
|
APP_PATH: apps/edr-passenger-web/backoffice
|
||||||
VITE_API_URL: ${PASSENGER_VITE_API_URL:-http://localhost:4000}
|
VITE_API_URL: ${PASSENGER_VITE_API_URL:-http://localhost:4000}
|
||||||
|
secrets:
|
||||||
|
- npmrc
|
||||||
ports:
|
ports:
|
||||||
- "${PASSENGER_BACKOFFICE_PORT:-5184}:80"
|
- "${PASSENGER_BACKOFFICE_PORT:-5184}:80"
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user