- Timestamp:
- 02/27/25 00:42:38 (5 weeks ago)
- Branches:
- main
- Children:
- 32e9876
- Parents:
- 3c5302a
- Location:
- src
- Files:
-
- 5 added
- 22 edited
- 8 moved
Legend:
- Unmodified
- Added
- Removed
-
src/api/invoice.ts
r3c5302a r87c9f1e 81 81 // Add this interface for the create invoice payload 82 82 interface CreateInvoicePayload { 83 createDate: Date;83 issueDate: Date; 84 84 dueDate: Date; 85 85 items: any[]; -
src/app/api/customers/route.ts
r3c5302a r87c9f1e 3 3 import prisma from 'src/lib/prisma'; 4 4 import { authenticateRequest } from 'src/lib/auth-middleware'; 5 import { CustomerStatus } from '@prisma/client'; 6 import { Prisma } from '@prisma/client'; 5 import { Prisma, ClientStatus } from '@prisma/client'; 7 6 8 7 export async function GET(request: NextRequest) { … … 25 24 const validatedFilters = customerTableFiltersSchema.parse(filters); 26 25 27 // Replace Prisma query with raw SQL 28 const customers = await prisma.$queryRaw` 29 SELECT * FROM "Client" 30 WHERE "tenantId" = ${tenantId} 31 AND LOWER(name) LIKE LOWER(${`%${validatedFilters.name}%`}) 32 ${ 33 validatedFilters.status 34 ? Prisma.sql`AND status = ${validatedFilters.status}::"CustomerStatus"` 35 : Prisma.sql`AND TRUE` 36 } 37 `; 26 // const customers = await prisma.$queryRaw` 27 // SELECT * FROM "Client" 28 // WHERE "tenant_id" = ${tenantId} 29 // AND LOWER(name) LIKE LOWER(${`%${validatedFilters.name}%`}) 30 // ${ 31 // validatedFilters.status 32 // ? Prisma.sql`AND status = ${validatedFilters.status}::"CustomerStatus"` 33 // : Prisma.sql`AND TRUE` 34 // } 35 // `; 36 37 const customers = await prisma.client.findMany({ 38 where: { 39 tenantId, 40 name: { 41 contains: validatedFilters.name, 42 mode: 'insensitive', 43 }, 44 ...(validatedFilters.status && { 45 status: validatedFilters.status as ClientStatus, 46 }), 47 }, 48 }); 38 49 39 50 return NextResponse.json(customers); … … 60 71 data: { 61 72 ...validatedData, 62 // userId,63 73 tenantId, 64 74 }, -
src/app/api/invoices/[id]/route.ts
r3c5302a r87c9f1e 100 100 data: { 101 101 invoiceNumber: validation.data.invoiceNumber, 102 createDate: validation.data.createDate,102 issueDate: validation.data.issueDate, 103 103 dueDate: validation.data.dueDate, 104 104 status: validation.data.status, -
src/app/api/invoices/route.ts
r3c5302a r87c9f1e 45 45 ? { equals: validatedFilters.status as InvoiceStatus } 46 46 : undefined, 47 createDate: {47 issueDate: { 48 48 ...(validatedFilters.startDate && { gte: validatedFilters.startDate }), 49 49 ...(validatedFilters.endDate && { lte: validatedFilters.endDate }), … … 108 108 quantityType: validatedData.quantityType, 109 109 subTotal: validatedData.subTotal, 110 createDate: validatedData.createDate,110 issueDate: validatedData.issueDate, 111 111 month: validatedData.month, 112 112 discount: validatedData.discount, -
src/app/api/invoices/totals/route.ts
r3c5302a r87c9f1e 20 20 const searchParams = request.nextUrl.searchParams; 21 21 const startDate = searchParams.get('startDate') 22 ? new Date(searchParams.get(' startDate')!)22 ? new Date(searchParams.get('issueDate')!) 23 23 : null; 24 24 … … 32 32 status, 33 33 currency, 34 SUM("total Amount") as total34 SUM("total_amount") as total 35 35 FROM "Invoice" 36 WHERE " createDate" >= ${startDate}37 AND " invoiceFromId" = ${tenantId}36 WHERE "issue_date" >= ${startDate} 37 AND "tenant_id" = ${tenantId} 38 38 GROUP BY status, currency 39 39 `; -
src/app/dashboard/customer/list/page.tsx
r3c5302a r87c9f1e 1 1 // sections 2 import { CustomerListView } from 'src/sections/ user/view';2 import { CustomerListView } from 'src/sections/client/view'; 3 3 4 4 // ---------------------------------------------------------------------- -
src/app/dashboard/customer/new/page.tsx
r3c5302a r87c9f1e 1 1 // sections 2 import { CustomerCreateView } from 'src/sections/ user/view';2 import { CustomerCreateView } from 'src/sections/client/view'; 3 3 4 4 // ---------------------------------------------------------------------- -
src/app/loading.tsx
r3c5302a r87c9f1e 7 7 8 8 export default function Loading() { 9 return <SplashScreen />; 9 return ( 10 <div className="flex min-h-screen items-center justify-center"> 11 <div className="animate-spin rounded-full h-32 w-32 border-t-2 border-b-2 border-blue-500"></div> 12 </div> 13 ); 10 14 } -
src/app/not-found.tsx
r3c5302a r87c9f1e 1 1 // sections 2 2 import { NotFoundView } from 'src/sections/error'; 3 import Link from 'next/link'; 3 4 4 5 // ---------------------------------------------------------------------- … … 8 9 }; 9 10 10 export default function NotFoundPage() { 11 return <NotFoundView />; 11 export default function NotFound() { 12 return ( 13 <div className="flex min-h-screen flex-col items-center justify-center"> 14 <h2 className="text-2xl font-bold mb-4">Page Not Found</h2> 15 <p className="mb-4">Could not find requested resource</p> 16 <Link href="/" className="px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600"> 17 Return Home 18 </Link> 19 </div> 20 ); 12 21 } -
src/auth/context/firebase/auth-provider.tsx
r3c5302a r87c9f1e 21 21 import { AuthContext } from './auth-context'; 22 22 import { ActionMapType, AuthStateType, AuthUserType } from '../../types'; 23 import { getUser } from 'src/api/user'; 23 24 24 25 // ---------------------------------------------------------------------- … … 71 72 if (user) { 72 73 if (user.emailVerified) { 73 const userProfile = doc(db, collections.administrator, user.uid); 74 75 const docSnap = await getDoc(userProfile); 76 77 const profile = docSnap.data(); 78 79 dispatch({ 80 type: Types.INITIAL, 81 payload: { 82 user: { 83 ...user, 84 ...profile, 85 id: user.uid, 74 try { 75 const profile = await getUser(); 76 console.log('profile', profile); 77 78 dispatch({ 79 type: Types.INITIAL, 80 payload: { 81 user: { ...profile, emailVerified: user.emailVerified }, 86 82 }, 87 }, 88 }); 83 }); 84 } catch (error) { 85 console.error('Failed to fetch user profile:', error); 86 dispatch({ 87 type: Types.INITIAL, 88 payload: { 89 user: null, 90 }, 91 }); 92 } 89 93 } else { 90 94 dispatch({ … … 145 149 const register = useCallback( 146 150 async (email: string, password: string, firstName: string, lastName: string) => { 147 const newUser = await createUserWithEmailAndPassword(auth, email, password); 148 149 await sendEmailVerification(newUser.user); 150 151 const userProfile = doc(collection(db, collections.administrator), newUser.user?.uid); 152 153 await setDoc(userProfile, { 154 uid: newUser.user?.uid, 155 email, 156 displayName: `${firstName} ${lastName}`, 157 }); 151 // const newUser = await createUserWithEmailAndPassword(auth, email, password); 152 // await sendEmailVerification(newUser.user); 153 // const userProfile = doc(collection(db, collections.administrator), newUser.user?.uid); 154 // await setDoc(userProfile, { 155 // uid: newUser.user?.uid, 156 // email, 157 // displayName: `${firstName} ${lastName}`, 158 // }); 158 159 }, 159 160 [] -
src/layouts/dashboard/nav-horizontal.tsx
r3c5302a r87c9f1e 41 41 data={navData} 42 42 config={{ 43 currentRole: user?.role || ' admin',43 currentRole: user?.role || 'ADMIN', 44 44 }} 45 45 /> -
src/layouts/dashboard/nav-mini.tsx
r3c5302a r87c9f1e 51 51 data={navData} 52 52 config={{ 53 currentRole: user?.role || ' admin',53 currentRole: user?.role || 'ADMIN', 54 54 }} 55 55 /> -
src/layouts/dashboard/nav-vertical.tsx
r3c5302a r87c9f1e 58 58 data={navData} 59 59 config={{ 60 currentRole: user?.role || ' admin',60 currentRole: user?.role || 'ADMIN', 61 61 }} 62 62 /> -
src/lib/auth-middleware.ts
r3c5302a r87c9f1e 21 21 try { 22 22 // Verify the token 23 // const decodedToken = await auth.verifyIdToken(token); 24 // const userId = decodedToken.uid; 25 // const tenantId = decodedToken.customClaims?.tenantId || 'cm7lxc3p00000pb7kmdrxsfod'; 23 const decodedToken = await auth.verifyIdToken(token); 24 const userId = decodedToken.uid; 26 25 27 // if (!userId || !tenantId) { 28 // return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); 29 // } 26 const tenantId = decodedToken.customClaims?.tenantId || 'cm7lxc3p00000pb7kmdrxsfod'; 30 27 31 return { userId: 'nlswimR6mMQtirTNlMeqhqcSZeD3', tenantId: 'cm7lxc3p00000pb7kmdrxsfod' }; 28 if (!userId || !tenantId) { 29 return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); 30 } 31 32 return { userId, tenantId: 'cm7lxc3p00000pb7kmdrxsfod' }; 32 33 } catch (error) { 34 console.error('Error verifying token:', error); 33 35 return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); 34 36 } -
src/schemas/invoice.ts
r3c5302a r87c9f1e 67 67 ]), 68 68 subTotal: z.number(), 69 createDate: z.coerce.date(),69 issueDate: z.coerce.date(), 70 70 month: monthSchema, 71 71 discount: z.number().optional(), -
src/sections/invoice/invoice-details.tsx
r3c5302a r87c9f1e 261 261 Date Issued 262 262 </Typography> 263 {fDate(invoice. createDate)}263 {fDate(invoice.issueDate)} 264 264 </Stack> 265 265 -
src/sections/invoice/invoice-ee-pdf.tsx
r3c5302a r87c9f1e 129 129 discount, 130 130 invoiceTo, 131 createDate,131 issueDate, 132 132 totalAmount, 133 133 invoiceFrom, … … 229 229 <View style={styles.col6}> 230 230 <Text style={[styles.subtitle1, styles.mb4]}>Date Issued</Text> 231 <Text style={styles.body2}>{fDate( createDate)}</Text>231 <Text style={styles.body2}>{fDate(issueDate)}</Text> 232 232 </View> 233 233 <View style={styles.col6}> -
src/sections/invoice/invoice-mk-pdf.tsx
r3c5302a r87c9f1e 113 113 discount, 114 114 invoiceTo, 115 createDate,115 issueDate, 116 116 totalAmount, 117 117 invoiceFrom, … … 179 179 <View style={styles.col6}> 180 180 <Text style={[styles.subtitle1, styles.mb4]}>Date Issued</Text> 181 <Text style={styles.body2}>{fDate( createDate)}</Text>181 <Text style={styles.body2}>{fDate(issueDate)}</Text> 182 182 </View> 183 183 <View style={styles.col6}> -
src/sections/invoice/invoice-new-edit-form.tsx
r3c5302a r87c9f1e 81 81 const NewInvoiceSchema = Yup.object().shape({ 82 82 invoiceNumber: Yup.string().nullable().required('Invoice number is required'), 83 createDate: Yup.mixed<any>().nullable().required('Create date is required'),83 issueDate: Yup.mixed<any>().nullable().required('Create date is required'), 84 84 dueDate: Yup.mixed<any>() 85 85 .required('Due date is required') … … 87 87 'date-min', 88 88 'Due date must be later than create date', 89 (value, { parent }) => value.getTime() > parent. createDate.getTime()89 (value, { parent }) => value.getTime() > parent.issueDate.getTime() 90 90 ), 91 91 invoiceFrom: Yup.mixed<any>().nullable().required('Invoice from is required'), … … 117 117 ? currentInvoice?.invoiceNumber 118 118 : incrementInvoiceNumber(tenant?.lastInvoiceNumber), 119 createDate: currentInvoice?.createDate ? new Date(currentInvoice.createDate) : new Date(),119 issueDate: currentInvoice?.issueDate ? new Date(currentInvoice.issueDate) : new Date(), 120 120 dueDate: currentInvoice?.dueDate 121 121 ? new Date(currentInvoice.dueDate) … … 175 175 176 176 // Ensure dates are valid Date objects 177 const createDate = 178 data.createDate instanceof Date ? data.createDate : new Date(data.createDate); 177 const issueDate = data.issueDate instanceof Date ? data.issueDate : new Date(data.issueDate); 179 178 const dueDate = data.dueDate instanceof Date ? data.dueDate : new Date(data.dueDate); 180 179 181 180 const currentTime = new Date(); 182 createDate.setHours(181 issueDate.setHours( 183 182 currentTime.getHours(), 184 183 currentTime.getMinutes(), … … 197 196 invoiceNumber: incrementInvoiceNumber(tenant?.lastInvoiceNumber), 198 197 status: 'draft', 199 createDate,198 issueDate, 200 199 dueDate, 201 200 items: items.filter((item) => item.service !== null) as CreateInvoice['items'], … … 246 245 if (currentInvoice) { 247 246 // Ensure dates are valid Date objects 248 const createDate =249 data. createDate instanceof Date ? data.createDate : new Date(data.createDate);247 const issueDate = 248 data.issueDate instanceof Date ? data.issueDate : new Date(data.issueDate); 250 249 const dueDate = data.dueDate instanceof Date ? data.dueDate : new Date(data.dueDate); 251 250 … … 259 258 const writeData = { 260 259 ...data, 261 createDate,260 issueDate, 262 261 dueDate, 263 262 items, … … 312 311 313 312 // Ensure dates are valid Date objects 314 const createDate =315 data. createDate instanceof Date ? data.createDate : new Date(data.createDate);313 const issueDate = 314 data.issueDate instanceof Date ? data.issueDate : new Date(data.issueDate); 316 315 const dueDate = data.dueDate instanceof Date ? data.dueDate : new Date(data.dueDate); 317 316 … … 325 324 const writeData = { 326 325 ...data, 327 createDate,326 issueDate, 328 327 dueDate, 329 328 items, -
src/sections/invoice/invoice-new-edit-status-date.tsx
r3c5302a r87c9f1e 109 109 110 110 <Controller 111 name=" createDate"111 name="issueDate" 112 112 control={control} 113 113 render={({ field, fieldState: { error } }) => ( -
src/sections/invoice/invoice-table-row.tsx
r3c5302a r87c9f1e 51 51 sent, 52 52 invoiceNumber, 53 createDate,53 issueDate, 54 54 dueDate, 55 55 status, … … 60 60 } = row; 61 61 62 console.log( createDate);62 console.log(issueDate); 63 63 64 64 const confirmSend = useBoolean(); … … 107 107 <TableCell> 108 108 <ListItemText 109 primary={format(new Date( createDate), 'dd MMM yyyy')}110 secondary={format(new Date( createDate), 'p')}109 primary={format(new Date(issueDate), 'dd MMM yyyy')} 110 secondary={format(new Date(issueDate), 'p')} 111 111 primaryTypographyProps={{ typography: 'body2', noWrap: true }} 112 112 secondaryTypographyProps={{ -
src/sections/invoice/view/invoice-list-view.tsx
r3c5302a r87c9f1e 59 59 { id: 'currency', label: 'Currency' }, 60 60 { id: 'invoicePeriod', label: 'Invoice Period' }, 61 { id: ' createDate', label: 'Create' },61 { id: 'issueDate', label: 'Create' }, 62 62 { id: 'dueDate', label: 'Due' }, 63 63 { id: 'sent', label: 'Sent', align: 'center' }, … … 152 152 153 153 const table = useTable({ 154 defaultOrderBy: ' createDate',154 defaultOrderBy: 'issueDate', 155 155 defaultOrder: 'desc', 156 156 defaultDense: true, … … 166 166 collections.invoice, 167 167 JSON.stringify({ 168 where: [[' createDate', '>=', filters.startDate]],169 orderBy: ' createDate',168 where: [['issueDate', '>=', filters.startDate]], 169 orderBy: 'issueDate', 170 170 direction: 'desc', 171 171 }), … … 275 275 async (invoice: Invoice) => { 276 276 const serializedParams = JSON.stringify({ 277 where: [[' createDate', '>=', filters.startDate]],278 orderBy: ' createDate',277 where: [['issueDate', '>=', filters.startDate]], 278 orderBy: 'issueDate', 279 279 direction: 'desc', 280 280 }); … … 671 671 inputData = inputData.filter( 672 672 (invoice) => 673 fTimestamp(invoice. createDate.getTime()) >= fTimestamp(startDate.getTime()) &&674 fTimestamp(invoice. createDate.getTime()) <= fTimestamp(endDate.getTime())673 fTimestamp(invoice.issueDate.getTime()) >= fTimestamp(startDate.getTime()) && 674 fTimestamp(invoice.issueDate.getTime()) <= fTimestamp(endDate.getTime()) 675 675 ); 676 676 }
Note:
See TracChangeset
for help on using the changeset viewer.