Merge pull request #1192 from Tria-plc/freight/nati-2

Freight/nati 2
This commit is contained in:
Nathnael Wondisha
2026-08-08 20:38:37 +03:00
committed by GitHub
31 changed files with 1395 additions and 3009 deletions

View File

@@ -32,8 +32,6 @@ import { formatDate, humanize } from "./format";
/** Friendly labels for the proposed-change snapshot keys (UpdateProfileDto). */
export const FIELD_LABELS: Record<string, string> = {
companyName: "Company name",
companyEmail: "Company email",
companyPhone: "Company phone",
companyLocation: "Location",
companyAddress: "Address",
tin: "TIN",
@@ -73,8 +71,6 @@ export function currentValue(company: Company, key: string): string {
const attrs = (company.attributes ?? {}) as Record<string, unknown>;
const map: Record<string, unknown> = {
companyName: c.name,
companyEmail: c.email,
companyPhone: c.phone,
companyLocation: c.country,
companyAddress: c.address,
tin: c.tin,
@@ -118,7 +114,8 @@ function FaydaIdentityDiff({
if (!subject) return null;
const current =
subject === "owner" ? company.identity?.owner : company.identity?.poa;
const read = (key: string) => snapshot[`${subject}${key}`] as string | undefined;
const read = (key: string) =>
snapshot[`${subject}${key}`] as string | undefined;
const verifiedAt = read("FaydaVerifiedAt");
const fields: { label: string; from?: string | null; to?: string }[] = [
{ label: "Name", from: current?.name, to: read("Name") },
@@ -131,7 +128,9 @@ function FaydaIdentityDiff({
<Stack gap={8}>
<Group gap={8}>
<Text size="sm" fw={600} c="edr-text">
{subject === "owner" ? "Owner re-verification" : "PoA re-verification"}
{subject === "owner"
? "Owner re-verification"
: "PoA re-verification"}
</Text>
{verifiedAt && (
<Text size="xs" c="dimmed">
@@ -283,8 +282,8 @@ export function ChangeRequestReview({ company }: { company: Company }) {
icon={<AlertTriangle size={16} />}
>
Changes were requested on an earlier round of this same
submission: <strong>{pending.note}</strong> check whether
this resubmission actually addresses it before approving.
submission: <strong>{pending.note}</strong> check whether this
resubmission actually addresses it before approving.
</Alert>
)}
@@ -297,8 +296,8 @@ export function ChangeRequestReview({ company }: { company: Company }) {
from={currentValue(company, key)}
to={
pending.snapshot[key] === null ||
pending.snapshot[key] === undefined ||
pending.snapshot[key] === ""
pending.snapshot[key] === undefined ||
pending.snapshot[key] === ""
? "—"
: String(pending.snapshot[key])
}
@@ -312,7 +311,10 @@ export function ChangeRequestReview({ company }: { company: Company }) {
) : null}
{faydaIdentitySnapshot && (
<FaydaIdentityDiff company={company} snapshot={faydaIdentitySnapshot} />
<FaydaIdentityDiff
company={company}
snapshot={faydaIdentitySnapshot}
/>
)}
{documentChanges.length > 0 && (
@@ -373,9 +375,10 @@ export function ChangeRequestReview({ company }: { company: Company }) {
type="button"
size="sm"
onClick={() =>
void fetchViewableFile(fileId, `Document ${i + 1}`).then(
view,
)
void fetchViewableFile(
fileId,
`Document ${i + 1}`,
).then(view)
}
>
Document {i + 1}
@@ -446,7 +449,10 @@ export function ChangeRequestReview({ company }: { company: Company }) {
variant="light"
color="yellow"
onClick={() => {
setActionTarget({ id: pending.id, kind: "request-changes" });
setActionTarget({
id: pending.id,
kind: "request-changes",
});
setNote("");
}}
>
@@ -525,7 +531,11 @@ export function ChangeRequestReview({ company }: { company: Company }) {
}
/** Compact "N changes pending" pill for the customer list/detail header. */
export function ChangeRequestPendingBadge({ companyId }: { companyId: string }) {
export function ChangeRequestPendingBadge({
companyId,
}: {
companyId: string;
}) {
const query = useQuery(
api.customers.changeRequests.queryOptions({ input: { id: companyId } }),
);

View File

@@ -203,22 +203,19 @@ export const buildSidebarSections = (demoItems: SidebarItem[]): SidebarSection[]
label: "Routes",
href: "/dashboard/routes",
icon: <Network />,
permission: [FREIGHT_PERMS.routes.view, FREIGHT_PERMS.fleet.view],
permission: FREIGHT_PERMS.routes.view,
},
{
label: "Locomotives",
href: "/dashboard/locomotives",
icon: <Train />,
permission: [
FREIGHT_PERMS.locomotives.view,
FREIGHT_PERMS.fleet.view,
],
permission: FREIGHT_PERMS.locomotives.view,
},
{
label: "Train Builder",
href: "/dashboard/train-builder",
icon: <Hammer />,
permission: [FREIGHT_PERMS.trains.view, FREIGHT_PERMS.fleet.view],
permission: FREIGHT_PERMS.trains.view,
},
// {
@@ -230,7 +227,7 @@ export const buildSidebarSections = (demoItems: SidebarItem[]): SidebarSection[]
label: "Wagons",
href: "/dashboard/wagons",
icon: <Truck />,
permission: [FREIGHT_PERMS.wagons.view, FREIGHT_PERMS.fleet.view],
permission: FREIGHT_PERMS.wagons.view,
},
{
label: "Wagon Transfers",
@@ -287,21 +284,23 @@ export const buildSidebarSections = (demoItems: SidebarItem[]): SidebarSection[]
label: "Compliance & Alerts",
href: "/dashboard/compliance",
icon: <ShieldCheck />,
permission: [FREIGHT_PERMS.compliance.view, FREIGHT_PERMS.fleet.view],
permission: FREIGHT_PERMS.compliance.view,
},
{
label: "Incidents",
href: "/dashboard/incidents",
icon: <FileText />,
// No dedicated backend key exists for incidents yet — stuck on the
// blanket fleet:view fallback until one is added.
// No dedicated backend key exists for incidents yet. Not part of
// the fleet.view/admin fallback cleanup — removing fleet.view
// here with nothing to replace it would lock the page to
// super-admin only, so it stays as the sole (if coarse) gate.
permission: FREIGHT_PERMS.fleet.view,
},
{
label: "Procurement",
href: "/dashboard/procurement",
icon: <Package />,
permission: [FREIGHT_PERMS.procurement.view, FREIGHT_PERMS.fleet.view],
permission: FREIGHT_PERMS.procurement.view,
},
{
label: "Financial Reports",
@@ -486,23 +485,20 @@ export const buildSidebarSections = (demoItems: SidebarItem[]): SidebarSection[]
label: "File settings",
href: "/dashboard/file-settings",
icon: <Paperclip />,
permission: [FREIGHT_PERMS.settings.fileUpload.view, FREIGHT_PERMS.admin],
permission: FREIGHT_PERMS.settings.fileUpload.view,
},
{
label: "Dropdown settings",
href: "/dashboard/dropdown-settings",
icon: <Settings />,
permission: [FREIGHT_PERMS.settings.dropdown.view, FREIGHT_PERMS.admin],
permission: FREIGHT_PERMS.settings.dropdown.view,
},
{
label: "Contract templates",
href: "/dashboard/contract-templates",
icon: <ScrollText />,
// `view` opens the page; `read` alone is API-only and shows no menu.
permission: [
FREIGHT_PERMS.settings.contractTemplates.view,
FREIGHT_PERMS.admin,
],
permission: FREIGHT_PERMS.settings.contractTemplates.view,
},
{
label: "Portal content",
@@ -511,7 +507,6 @@ export const buildSidebarSections = (demoItems: SidebarItem[]): SidebarSection[]
permission: [
FREIGHT_PERMS.settings.supportContent.view,
FREIGHT_PERMS.settings.supportContent.manage,
FREIGHT_PERMS.admin,
],
},
{
@@ -534,12 +529,12 @@ export const buildSidebarSections = (demoItems: SidebarItem[]): SidebarSection[]
{
label: "Trade access",
href: "/dashboard/configuration/trade-access",
permission: [FREIGHT_PERMS.tradeAccess.view, FREIGHT_PERMS.admin],
permission: FREIGHT_PERMS.tradeAccess.view,
},
{
label: "Exchange rate",
href: "/dashboard/configuration/exchange-rate",
permission: [FREIGHT_PERMS.settings.exchangeRate.view, FREIGHT_PERMS.admin],
permission: FREIGHT_PERMS.settings.exchangeRate.view,
},
],
},