feat: add shipping line companies management

- Implement ShippingLineCompaniesService for registering and managing shipping line companies.
- Create ResendActivationAction component for resending activation links to shipping lines.
- Develop ShippingLineCompaniesPage for listing and registering shipping lines with validation.
- Introduce shippingLineCompanies.service for API interactions related to shipping lines.
- Define types for shipping line companies, including registration and pagination.
- Add placeholder pages for shipping line portal, including home, bookings, help, invoices, and settings.
This commit is contained in:
marshalyordanos
2026-08-13 08:54:20 +03:00
parent e37f1e0807
commit 9aae132dd4
42 changed files with 2463 additions and 117 deletions

View File

@@ -44,6 +44,12 @@ import type {
PaginatedOfflineUsdInvoices,
} from "@/types/invoice";
import type { IOverviewDashboard, OverviewRange } from "@/types/overview";
import type {
CreateShippingLineCompanyDto,
PaginatedShippingLineCompanies,
RegisterShippingLineCompanyResult,
ShippingLineCompany,
} from "@/types/shippingLineCompany";
import {
RuleEngineListResult,
RuleEngineRecord,
@@ -150,6 +156,7 @@ import {
import { containerTypesService } from "./container-types.service";
import { containerService, type Container } from "./containerService";
import { customersService } from "./customers.service";
import { shippingLineCompaniesService } from "./shippingLineCompanies.service";
import { eimsService } from "./eims.service";
import type { EimsInvoiceStatusView, EimsVerifyResult } from "@/types/eims";
import { invoicesService } from "./invoices.service";
@@ -2763,6 +2770,43 @@ export const api = {
),
},
shippingLineCompanies: {
list: endpoint<{ page: number; limit: number }, PaginatedShippingLineCompanies>(
"shippingLineCompanies",
"list",
({ page, limit }) => shippingLineCompaniesService.list(page, limit),
({ page, limit }) => QUERY_KEYS.SHIPPING_LINE_COMPANIES.list(page, limit),
),
getById: endpoint<{ id: string }, ShippingLineCompany>(
"shippingLineCompanies",
"getById",
({ id }) => shippingLineCompaniesService.getById(id),
({ id }) => QUERY_KEYS.SHIPPING_LINE_COMPANIES.byId(id),
),
register: endpoint<
CreateShippingLineCompanyDto,
RegisterShippingLineCompanyResult
>(
"shippingLineCompanies",
"register",
(dto) => shippingLineCompaniesService.register(dto),
undefined,
() => [QUERY_KEYS.SHIPPING_LINE_COMPANIES.ROOT],
),
resendActivation: endpoint<
{ id: string; channel: ResetChannel },
ResetPasswordResult
>(
"shippingLineCompanies",
"resendActivation",
({ id, channel }) =>
shippingLineCompaniesService.resendActivation(id, channel),
),
},
customers: {
stats: endpoint<Record<string, never>, CompanyStats>(
"customers",

View File

@@ -0,0 +1,54 @@
import { api as apiClient } from "@/auth/http";
import { URL_CONSTANTS } from "@/constants/URLS";
import type {
CreateShippingLineCompanyDto,
PaginatedShippingLineCompanies,
RegisterShippingLineCompanyResult,
ResetChannel,
ResetPasswordResult,
ShippingLineCompany,
} from "@/types/shippingLineCompany";
export const shippingLineCompaniesService = {
list(page = 1, limit = 20): Promise<PaginatedShippingLineCompanies> {
return apiClient
.get<PaginatedShippingLineCompanies>(
URL_CONSTANTS.SHIPPING_LINE_COMPANIES.BASE,
{ params: { page, limit } },
)
.then((r) => r.data);
},
getById(id: string): Promise<ShippingLineCompany> {
return apiClient
.get<ShippingLineCompany>(URL_CONSTANTS.SHIPPING_LINE_COMPANIES.BY_ID(id))
.then((r) => r.data);
},
/**
* Creates the carrier's account and record, then sends an activation link.
* Staff never set or see a password — the line chooses its own from the link.
*/
register(
dto: CreateShippingLineCompanyDto,
): Promise<RegisterShippingLineCompanyResult> {
return apiClient
.post<RegisterShippingLineCompanyResult>(
URL_CONSTANTS.SHIPPING_LINE_COMPANIES.BASE,
dto,
)
.then((r) => r.data);
},
resendActivation(
id: string,
channel: ResetChannel,
): Promise<ResetPasswordResult> {
return apiClient
.post<ResetPasswordResult>(
URL_CONSTANTS.SHIPPING_LINE_COMPANIES.RESEND_ACTIVATION(id),
{ channel },
)
.then((r) => r.data);
},
};