feat(submissions): Implement submissions page with paginated table

This commit introduces a new page for users to view their submissions in a structured and paginated table. This allows users to easily track their submission history and access key details.

The main changes include:
- A new page at `/submissions` to display the submissions list.
- A `SubmissionsTable` component to render submission data, including title, country, status, and a link to the submission URL.
- Integration of `react-paginate` to handle navigation through large sets of data.
- A new `useSubmissions` custom hook using TanStack Query for efficient, paginated data fetching from the API.
- Addition of the `currency-symbol-map` dependency to display prices with the correct currency symbol.
This commit is contained in:
AmirReza Jamali
2025-09-18 16:52:46 +03:30
parent 2f2114eba9
commit e1898bf259
24 changed files with 411 additions and 86 deletions
+1
View File
@@ -1,4 +1,5 @@
export const API_ENDPOINTS = {
FLAGS: (countryCode: string) => `flags/${countryCode}`,
POSTS: {
READ_ALL: "posts ",
},
+5 -1
View File
@@ -1,13 +1,17 @@
import api from "../axios";
import { API_ENDPOINTS } from "../endpoints";
import { ApiResponse } from "../types";
import {
CreateCustomerCredentials,
CustomerListResponseSchema,
TAssignCustomerToCompanyCredentials,
TCustomersListResponse,
} from "../types/Customers";
export const customersService = {
getCustomers: async (params?: Record<string, any>) => {
getCustomers: async (
params?: Record<string, any>,
): Promise<ApiResponse<TCustomersListResponse>> => {
try {
const response = await api.get(API_ENDPOINTS.CUSTOMERS.READ_ALL, {
params,
+15
View File
@@ -0,0 +1,15 @@
import api from "../axios";
import { API_ENDPOINTS } from "../endpoints";
export const flagsService = {
getCountryFlag: async (countryCode: string) => {
try {
const response = await api.get(API_ENDPOINTS.FLAGS(countryCode));
return response.data;
} catch (error) {
console.error("ERROR caught in Flags Service", error);
throw error;
}
},
};
+12 -1
View File
@@ -1,7 +1,7 @@
import api from "../axios";
import { API_ENDPOINTS } from "../endpoints";
import { ApiResponse } from "../types";
import { TTenderResponse } from "../types/Tenders";
import { TTenderDetails, TTenderResponse } from "../types/Tenders";
export const tendersService = {
tendersList: async (
@@ -14,4 +14,15 @@ export const tendersService = {
throw error;
}
},
tenderDetails: async (id: string): Promise<ApiResponse<TTenderDetails>> => {
try {
return (await api.get(API_ENDPOINTS.TENDERS.DETAILS(id))).data;
} catch (error) {
console.error(
"ERROR caught in Tender Service => tender details: ",
error,
);
throw error;
}
},
};
+2
View File
@@ -2,6 +2,7 @@ import { z } from "zod";
import { createApiResponseSchema } from "./Factory";
const customersSchema = z.object({
role: z.enum(["admin", "analyst"]).optional(),
companies: z
.array(
z.object({
@@ -75,6 +76,7 @@ const createCustomerCredentials = z.object({
])
.optional(),
email: z.string().email(),
role: z.enum(["admin", "analyst"]),
employee_count: z.number().int().min(1).max(100000).optional(),
first_name: z.string().min(2).max(50).optional(),
founded_year: z.number().int().min(1800).max(2100).optional(),
+1
View File
@@ -27,3 +27,4 @@ export const TendersResponse = z.object({
tenders: z.array(TenderSchema).or(z.null()),
});
export type TTenderResponse = z.infer<typeof TendersResponse>;
export type TTenderDetails = z.infer<typeof TenderSchema>;