feat: implement wagon transfer management modals and page

- Add TransferFulfillModal for fulfilling wagon transfer requests.
- Create TransferRequestFormModal for filing new wagon transfer requests.
- Introduce TransferCloseShortModal for closing requests that cannot be fully fulfilled.
- Develop WagonTransfersPage to manage and display wagon transfer requests.
- Implement utility functions for handling wagon transfer request data and UI components.
- Enhance UI with Mantine components for better user experience.
This commit is contained in:
Marshal
2026-07-26 15:11:50 +00:00
parent 9a1c8e5603
commit 9b13fa2ac6
40 changed files with 2584 additions and 809 deletions

View File

@@ -28,7 +28,11 @@ from (values
('edr_gl_ethiopia', 'edr_gl_ethiopia'),
('edr_gl_djibouti', 'edr_gl_djibouti'),
('demo_user1', 'Demo User1'),
('demo_user2', 'Demo User2')
('demo_user2', 'Demo User2'),
-- `super_admin` is the key isSuperAdmin() looks for. It is what lets this
-- account bypass separation-of-duties rules (e.g. approving a rate it
-- proposed), which several specs depend on.
('super_admin', 'Super Admin')
) v(key, name)
where not exists (select 1 from iam.roles r where r.key = v.key);
@@ -64,20 +68,28 @@ from (values
('gl-et@edr.local', 'gl_et', 'gl_et'),
('gl-dj@edr.local', 'gl_dj', 'gl_dj'),
('user@gmail.com', 'user', 'Demo User 1'),
('user2@gmail.com', 'user2', 'Demo User 2')
('user2@gmail.com', 'user2', 'Demo User 2'),
-- Full-authority operator the corridor specs drive the customs/GL steps with
-- (t1-close, risk, gate pass, second duty, import release). Nothing in the
-- repo seeded it before — the suite silently relied on a hand-made row that
-- only existed in a long-lived dev database, so a fresh stack failed 7 specs.
('superadmin@tria.com', 'superadmin', 'Super Admin')
) v(email, username, display)
where not exists (select 1 from iam.users u where u.email = v.email);
-- ── Credentials ──────────────────────────────────────────────────────────────
insert into iam.user_credentials (id, user_id, password, is_active)
select gen_random_uuid(), u.id,
case when u.email like '%@edr.local'
case when u.email like '%@edr.local' or u.email = 'superadmin@tria.com'
then '$argon2id$v=19$m=65536,t=3,p=4$JFEcHu4Kp55fsrVDPbHDPg$0NfnGzaE39T/qdmzte73oCkohC0Ri+f8DcrvAF4kyH4' -- password@tria
else '$argon2id$v=19$m=65536,t=3,p=4$aBwVFf7I74pqSJqe9cBoig$gCIKa+6dCAb2X86G+0IjgPtil127cx6A6mwhvLj00Bw' -- 12345678
end,
true
from iam.users u
where (u.email like '%@edr.local' or u.email in ('user@gmail.com', 'user2@gmail.com'))
where (
u.email like '%@edr.local'
or u.email in ('user@gmail.com', 'user2@gmail.com', 'superadmin@tria.com')
)
and not exists (select 1 from iam.user_credentials c where c.user_id = u.id);
-- ── User → role (staff under edr_freight, demo under demo_iam) ──────────────
@@ -92,6 +104,7 @@ from (values
('operation@edr.local', 'edr_operations_officer', 'edr_freight'),
('gl-et@edr.local', 'edr_gl_ethiopia', 'edr_freight'),
('gl-dj@edr.local', 'edr_gl_djibouti', 'edr_freight'),
('superadmin@tria.com', 'super_admin', 'edr_freight'),
('user@gmail.com', 'demo_user1', 'demo_iam'),
('user2@gmail.com', 'demo_user2', 'demo_iam')
) v(email, role_key, org_key)
@@ -106,7 +119,7 @@ select gen_random_uuid(), true, 'pending', u.name, o.id, un.id, u.id
from iam.users u
join iam.organizations o on o.key = 'edr_freight'
join iam.units un on un.key = 'edr_freight_app' and un.organization_id = o.id
where u.email like '%@edr.local'
where (u.email like '%@edr.local' or u.email = 'superadmin@tria.com')
and not exists (select 1 from iam.employees e where e.user_id = u.id);
-- start_date must be set: the login query filters positions on
@@ -122,7 +135,10 @@ from (values
('marketer@edr.local', 'marketer'),
('operation@edr.local', 'operation'),
('gl-et@edr.local', 'ethiopian_gl'),
('gl-dj@edr.local', 'djibouti_gl')
('gl-dj@edr.local', 'djibouti_gl'),
-- operations_chief carries the whole freight permission catalog, which is
-- what the corridor specs need from this account.
('superadmin@tria.com', 'operations_chief')
) v(email, position_key)
join iam.users u on u.email = v.email
join iam.employees e on e.user_id = u.id