@freighttech/shipment-tracking 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/NOTICE +25 -0
- package/dist/generated/entities/bic_config/index.js +21 -0
- package/dist/generated/entities/bic_config/index.js.map +7 -0
- package/dist/generated/entities/carrier_config/index.js +27 -0
- package/dist/generated/entities/carrier_config/index.js.map +7 -0
- package/dist/generated/entities/location_override/index.js +33 -0
- package/dist/generated/entities/location_override/index.js.map +7 -0
- package/dist/generated/entities/shipment/index.js +73 -0
- package/dist/generated/entities/shipment/index.js.map +7 -0
- package/dist/generated/entities/ships_go_config/index.js +31 -0
- package/dist/generated/entities/ships_go_config/index.js.map +7 -0
- package/dist/generated/entities/tracking_event/index.js +101 -0
- package/dist/generated/entities/tracking_event/index.js.map +7 -0
- package/dist/generated/entities/tracking_job/index.js +47 -0
- package/dist/generated/entities/tracking_job/index.js.map +7 -0
- package/dist/generated/entities/webhook/index.js +25 -0
- package/dist/generated/entities/webhook/index.js.map +7 -0
- package/dist/generated/entities/webhook_delivery/index.js +25 -0
- package/dist/generated/entities/webhook_delivery/index.js.map +7 -0
- package/dist/generated/entities.ids.generated.js +21 -0
- package/dist/generated/entities.ids.generated.js.map +7 -0
- package/dist/index.js +41 -0
- package/dist/index.js.map +7 -0
- package/dist/modules/shipment_tracking/acl.js +22 -0
- package/dist/modules/shipment_tracking/acl.js.map +7 -0
- package/dist/modules/shipment_tracking/api/bic-configs/route.js +176 -0
- package/dist/modules/shipment_tracking/api/bic-configs/route.js.map +7 -0
- package/dist/modules/shipment_tracking/api/bic-configs/test/route.js +95 -0
- package/dist/modules/shipment_tracking/api/bic-configs/test/route.js.map +7 -0
- package/dist/modules/shipment_tracking/api/cargo-events/route.js +93 -0
- package/dist/modules/shipment_tracking/api/cargo-events/route.js.map +7 -0
- package/dist/modules/shipment_tracking/api/carrier-configs/route.js +139 -0
- package/dist/modules/shipment_tracking/api/carrier-configs/route.js.map +7 -0
- package/dist/modules/shipment_tracking/api/dashboard/ships-map/route.js +177 -0
- package/dist/modules/shipment_tracking/api/dashboard/ships-map/route.js.map +7 -0
- package/dist/modules/shipment_tracking/api/location-overrides/route.js +179 -0
- package/dist/modules/shipment_tracking/api/location-overrides/route.js.map +7 -0
- package/dist/modules/shipment_tracking/api/openapi.js +27 -0
- package/dist/modules/shipment_tracking/api/openapi.js.map +7 -0
- package/dist/modules/shipment_tracking/api/shipments/route.js +192 -0
- package/dist/modules/shipment_tracking/api/shipments/route.js.map +7 -0
- package/dist/modules/shipment_tracking/api/shipsgo-configs/route.js +185 -0
- package/dist/modules/shipment_tracking/api/shipsgo-configs/route.js.map +7 -0
- package/dist/modules/shipment_tracking/api/tracking-jobs/route.js +144 -0
- package/dist/modules/shipment_tracking/api/tracking-jobs/route.js.map +7 -0
- package/dist/modules/shipment_tracking/api/tracking-jobs/sync/route.js +107 -0
- package/dist/modules/shipment_tracking/api/tracking-jobs/sync/route.js.map +7 -0
- package/dist/modules/shipment_tracking/api/utils.js +12 -0
- package/dist/modules/shipment_tracking/api/utils.js.map +7 -0
- package/dist/modules/shipment_tracking/api/webhooks/deliveries/route.js +76 -0
- package/dist/modules/shipment_tracking/api/webhooks/deliveries/route.js.map +7 -0
- package/dist/modules/shipment_tracking/api/webhooks/route.js +135 -0
- package/dist/modules/shipment_tracking/api/webhooks/route.js.map +7 -0
- package/dist/modules/shipment_tracking/api/webhooks/test/route.js +71 -0
- package/dist/modules/shipment_tracking/api/webhooks/test/route.js.map +7 -0
- package/dist/modules/shipment_tracking/assets/carriers/cma_cgm.png +0 -0
- package/dist/modules/shipment_tracking/assets/carriers/cosco.png +0 -0
- package/dist/modules/shipment_tracking/assets/carriers/evergreen.png +0 -0
- package/dist/modules/shipment_tracking/assets/carriers/hapag_lloyd.png +0 -0
- package/dist/modules/shipment_tracking/assets/carriers/maersk.png +0 -0
- package/dist/modules/shipment_tracking/assets/carriers/msc.png +0 -0
- package/dist/modules/shipment_tracking/assets/carriers/one.png +0 -0
- package/dist/modules/shipment_tracking/assets/carriers/oocl.png +0 -0
- package/dist/modules/shipment_tracking/assets/carriers/yang_ming.png +0 -0
- package/dist/modules/shipment_tracking/assets/carriers/zim.png +0 -0
- package/dist/modules/shipment_tracking/assets/index.js +52 -0
- package/dist/modules/shipment_tracking/assets/index.js.map +7 -0
- package/dist/modules/shipment_tracking/backend/carrier-configs/page.js +621 -0
- package/dist/modules/shipment_tracking/backend/carrier-configs/page.js.map +7 -0
- package/dist/modules/shipment_tracking/backend/carrier-configs/page.meta.js +19 -0
- package/dist/modules/shipment_tracking/backend/carrier-configs/page.meta.js.map +7 -0
- package/dist/modules/shipment_tracking/backend/location-overrides/page.js +198 -0
- package/dist/modules/shipment_tracking/backend/location-overrides/page.js.map +7 -0
- package/dist/modules/shipment_tracking/backend/location-overrides/page.meta.js +19 -0
- package/dist/modules/shipment_tracking/backend/location-overrides/page.meta.js.map +7 -0
- package/dist/modules/shipment_tracking/backend/shipment-tracking/page.js +279 -0
- package/dist/modules/shipment_tracking/backend/shipment-tracking/page.js.map +7 -0
- package/dist/modules/shipment_tracking/backend/shipment-tracking/page.meta.js +19 -0
- package/dist/modules/shipment_tracking/backend/shipment-tracking/page.meta.js.map +7 -0
- package/dist/modules/shipment_tracking/backend/tracking-jobs/page.js +10 -0
- package/dist/modules/shipment_tracking/backend/tracking-jobs/page.js.map +7 -0
- package/dist/modules/shipment_tracking/backend/tracking-jobs/page.meta.js +19 -0
- package/dist/modules/shipment_tracking/backend/tracking-jobs/page.meta.js.map +7 -0
- package/dist/modules/shipment_tracking/backend/webhooks/page.js +198 -0
- package/dist/modules/shipment_tracking/backend/webhooks/page.js.map +7 -0
- package/dist/modules/shipment_tracking/backend/webhooks/page.meta.js +19 -0
- package/dist/modules/shipment_tracking/backend/webhooks/page.meta.js.map +7 -0
- package/dist/modules/shipment_tracking/ce.js +52 -0
- package/dist/modules/shipment_tracking/ce.js.map +7 -0
- package/dist/modules/shipment_tracking/cli.js +229 -0
- package/dist/modules/shipment_tracking/cli.js.map +7 -0
- package/dist/modules/shipment_tracking/commands/bic-configs.js +66 -0
- package/dist/modules/shipment_tracking/commands/bic-configs.js.map +7 -0
- package/dist/modules/shipment_tracking/commands/carrier-configs.js +65 -0
- package/dist/modules/shipment_tracking/commands/carrier-configs.js.map +7 -0
- package/dist/modules/shipment_tracking/commands/index.js +9 -0
- package/dist/modules/shipment_tracking/commands/index.js.map +7 -0
- package/dist/modules/shipment_tracking/commands/location-overrides.js +93 -0
- package/dist/modules/shipment_tracking/commands/location-overrides.js.map +7 -0
- package/dist/modules/shipment_tracking/commands/shipments.js +200 -0
- package/dist/modules/shipment_tracking/commands/shipments.js.map +7 -0
- package/dist/modules/shipment_tracking/commands/shipsgo-configs.js +75 -0
- package/dist/modules/shipment_tracking/commands/shipsgo-configs.js.map +7 -0
- package/dist/modules/shipment_tracking/commands/tracking-jobs.js +120 -0
- package/dist/modules/shipment_tracking/commands/tracking-jobs.js.map +7 -0
- package/dist/modules/shipment_tracking/commands/tracking.js +140 -0
- package/dist/modules/shipment_tracking/commands/tracking.js.map +7 -0
- package/dist/modules/shipment_tracking/commands/webhooks.js +115 -0
- package/dist/modules/shipment_tracking/commands/webhooks.js.map +7 -0
- package/dist/modules/shipment_tracking/components/CombinedTimestampCell.js +168 -0
- package/dist/modules/shipment_tracking/components/CombinedTimestampCell.js.map +7 -0
- package/dist/modules/shipment_tracking/components/FacilityLocationInput.js +202 -0
- package/dist/modules/shipment_tracking/components/FacilityLocationInput.js.map +7 -0
- package/dist/modules/shipment_tracking/components/LocationOverrideDrawer.js +501 -0
- package/dist/modules/shipment_tracking/components/LocationOverrideDrawer.js.map +7 -0
- package/dist/modules/shipment_tracking/components/ShipmentDetailsDrawer.js +818 -0
- package/dist/modules/shipment_tracking/components/ShipmentDetailsDrawer.js.map +7 -0
- package/dist/modules/shipment_tracking/components/ShipmentDrawer.js +404 -0
- package/dist/modules/shipment_tracking/components/ShipmentDrawer.js.map +7 -0
- package/dist/modules/shipment_tracking/components/ShipsGoConfigSection.js +200 -0
- package/dist/modules/shipment_tracking/components/ShipsGoConfigSection.js.map +7 -0
- package/dist/modules/shipment_tracking/components/TimestampCell.js +108 -0
- package/dist/modules/shipment_tracking/components/TimestampCell.js.map +7 -0
- package/dist/modules/shipment_tracking/components/TrackingJobDrawer.js +343 -0
- package/dist/modules/shipment_tracking/components/TrackingJobDrawer.js.map +7 -0
- package/dist/modules/shipment_tracking/components/VesselTrackingMap.js +496 -0
- package/dist/modules/shipment_tracking/components/VesselTrackingMap.js.map +7 -0
- package/dist/modules/shipment_tracking/components/WebhookDrawer.js +332 -0
- package/dist/modules/shipment_tracking/components/WebhookDrawer.js.map +7 -0
- package/dist/modules/shipment_tracking/data/entities.js +686 -0
- package/dist/modules/shipment_tracking/data/entities.js.map +7 -0
- package/dist/modules/shipment_tracking/data/validators.js +434 -0
- package/dist/modules/shipment_tracking/data/validators.js.map +7 -0
- package/dist/modules/shipment_tracking/di.js +60 -0
- package/dist/modules/shipment_tracking/di.js.map +7 -0
- package/dist/modules/shipment_tracking/encryption.js +12 -0
- package/dist/modules/shipment_tracking/encryption.js.map +7 -0
- package/dist/modules/shipment_tracking/events.js +87 -0
- package/dist/modules/shipment_tracking/events.js.map +7 -0
- package/dist/modules/shipment_tracking/hooks/useVesselTracking.js +137 -0
- package/dist/modules/shipment_tracking/hooks/useVesselTracking.js.map +7 -0
- package/dist/modules/shipment_tracking/i18n/de.json +327 -0
- package/dist/modules/shipment_tracking/i18n/en.json +327 -0
- package/dist/modules/shipment_tracking/i18n/es.json +327 -0
- package/dist/modules/shipment_tracking/i18n/pl.json +327 -0
- package/dist/modules/shipment_tracking/index.js +15 -0
- package/dist/modules/shipment_tracking/index.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/adapters/cma-cgm.js +66 -0
- package/dist/modules/shipment_tracking/lib/adapters/cma-cgm.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/adapters/cosco-types.js +1 -0
- package/dist/modules/shipment_tracking/lib/adapters/cosco-types.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/adapters/cosco.js +236 -0
- package/dist/modules/shipment_tracking/lib/adapters/cosco.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/adapters/evergreen.js +87 -0
- package/dist/modules/shipment_tracking/lib/adapters/evergreen.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/adapters/hapag-lloyd.js +68 -0
- package/dist/modules/shipment_tracking/lib/adapters/hapag-lloyd.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/adapters/index.js +20 -0
- package/dist/modules/shipment_tracking/lib/adapters/index.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/adapters/maersk.js +84 -0
- package/dist/modules/shipment_tracking/lib/adapters/maersk.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/adapters/msc.js +170 -0
- package/dist/modules/shipment_tracking/lib/adapters/msc.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/adapters/zim.js +85 -0
- package/dist/modules/shipment_tracking/lib/adapters/zim.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/audit-helpers.js +20 -0
- package/dist/modules/shipment_tracking/lib/audit-helpers.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/auth/base64url.js +8 -0
- package/dist/modules/shipment_tracking/lib/auth/base64url.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/auth/oauth-client.js +38 -0
- package/dist/modules/shipment_tracking/lib/auth/oauth-client.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/background.js +15 -0
- package/dist/modules/shipment_tracking/lib/background.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/bic-api-client.js +106 -0
- package/dist/modules/shipment_tracking/lib/bic-api-client.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/carrier-adapter.js +17 -0
- package/dist/modules/shipment_tracking/lib/carrier-adapter.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/current-vessel.js +149 -0
- package/dist/modules/shipment_tracking/lib/current-vessel.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/dcsa-event-mapping.js +124 -0
- package/dist/modules/shipment_tracking/lib/dcsa-event-mapping.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/dcsa-event-parser.js +112 -0
- package/dist/modules/shipment_tracking/lib/dcsa-event-parser.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/dcsa-params.js +16 -0
- package/dist/modules/shipment_tracking/lib/dcsa-params.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/empty-return.js +48 -0
- package/dist/modules/shipment_tracking/lib/empty-return.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/location-overrides.js +85 -0
- package/dist/modules/shipment_tracking/lib/location-overrides.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/location-types.js +59 -0
- package/dist/modules/shipment_tracking/lib/location-types.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/logger.js +113 -0
- package/dist/modules/shipment_tracking/lib/logger.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/poi-event-processor.js +183 -0
- package/dist/modules/shipment_tracking/lib/poi-event-processor.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/poi-nats-config.js +52 -0
- package/dist/modules/shipment_tracking/lib/poi-nats-config.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/poi-types.js +43 -0
- package/dist/modules/shipment_tracking/lib/poi-types.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/rate-limiter.js +31 -0
- package/dist/modules/shipment_tracking/lib/rate-limiter.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/route-extraction.js +187 -0
- package/dist/modules/shipment_tracking/lib/route-extraction.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/route-inference.js +106 -0
- package/dist/modules/shipment_tracking/lib/route-inference.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/schedule-generator.js +63 -0
- package/dist/modules/shipment_tracking/lib/schedule-generator.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/shipsgo-client.js +143 -0
- package/dist/modules/shipment_tracking/lib/shipsgo-client.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/shipsgo-mapper.js +204 -0
- package/dist/modules/shipment_tracking/lib/shipsgo-mapper.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/status-machine.js +131 -0
- package/dist/modules/shipment_tracking/lib/status-machine.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/time-extraction.js +41 -0
- package/dist/modules/shipment_tracking/lib/time-extraction.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/timestamp-utils.js +100 -0
- package/dist/modules/shipment_tracking/lib/timestamp-utils.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/vessel-api.js +111 -0
- package/dist/modules/shipment_tracking/lib/vessel-api.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/vessel-cache.js +50 -0
- package/dist/modules/shipment_tracking/lib/vessel-cache.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/vessel-extraction.js +13 -0
- package/dist/modules/shipment_tracking/lib/vessel-extraction.js.map +7 -0
- package/dist/modules/shipment_tracking/lib/webhook-dispatcher.js +62 -0
- package/dist/modules/shipment_tracking/lib/webhook-dispatcher.js.map +7 -0
- package/dist/modules/shipment_tracking/migrations/Migration20260422161208_shipment_tracking.js +48 -0
- package/dist/modules/shipment_tracking/migrations/Migration20260422161208_shipment_tracking.js.map +7 -0
- package/dist/modules/shipment_tracking/migrations/Migration20260529120000_shipment_tracking_poi_region_names.js +15 -0
- package/dist/modules/shipment_tracking/migrations/Migration20260529120000_shipment_tracking_poi_region_names.js.map +7 -0
- package/dist/modules/shipment_tracking/migrations/Migration20260821120000_shipment_tracking_shipsgo.js +47 -0
- package/dist/modules/shipment_tracking/migrations/Migration20260821120000_shipment_tracking_shipsgo.js.map +7 -0
- package/dist/modules/shipment_tracking/notifications.js +145 -0
- package/dist/modules/shipment_tracking/notifications.js.map +7 -0
- package/dist/modules/shipment_tracking/services/carrierRegistry.js +24 -0
- package/dist/modules/shipment_tracking/services/carrierRegistry.js.map +7 -0
- package/dist/modules/shipment_tracking/services/poiNatsService.js +397 -0
- package/dist/modules/shipment_tracking/services/poiNatsService.js.map +7 -0
- package/dist/modules/shipment_tracking/services/shipsGoProvider.js +163 -0
- package/dist/modules/shipment_tracking/services/shipsGoProvider.js.map +7 -0
- package/dist/modules/shipment_tracking/services/trackingService.js +1283 -0
- package/dist/modules/shipment_tracking/services/trackingService.js.map +7 -0
- package/dist/modules/shipment_tracking/services/webhookService.js +263 -0
- package/dist/modules/shipment_tracking/services/webhookService.js.map +7 -0
- package/dist/modules/shipment_tracking/setup.js +72 -0
- package/dist/modules/shipment_tracking/setup.js.map +7 -0
- package/dist/modules/shipment_tracking/subscribers/cargo-event-created.js +60 -0
- package/dist/modules/shipment_tracking/subscribers/cargo-event-created.js.map +7 -0
- package/dist/modules/shipment_tracking/subscribers/dcsa-event-webhook-dispatch.js +58 -0
- package/dist/modules/shipment_tracking/subscribers/dcsa-event-webhook-dispatch.js.map +7 -0
- package/dist/modules/shipment_tracking/subscribers/poi-event-notification.js +82 -0
- package/dist/modules/shipment_tracking/subscribers/poi-event-notification.js.map +7 -0
- package/dist/modules/shipment_tracking/subscribers/poi-event-webhook-dispatch.js +53 -0
- package/dist/modules/shipment_tracking/subscribers/poi-event-webhook-dispatch.js.map +7 -0
- package/dist/modules/shipment_tracking/subscribers/shipment-status-changed.js +28 -0
- package/dist/modules/shipment_tracking/subscribers/shipment-status-changed.js.map +7 -0
- package/dist/modules/shipment_tracking/subscribers/terminal-event-ingest.js +67 -0
- package/dist/modules/shipment_tracking/subscribers/terminal-event-ingest.js.map +7 -0
- package/dist/modules/shipment_tracking/subscribers/tracking-job-initial-poll.js +30 -0
- package/dist/modules/shipment_tracking/subscribers/tracking-job-initial-poll.js.map +7 -0
- package/dist/modules/shipment_tracking/subscribers/tracking-job-webhook-dispatch.js +19 -0
- package/dist/modules/shipment_tracking/subscribers/tracking-job-webhook-dispatch.js.map +7 -0
- package/dist/modules/shipment_tracking/tables/index.js +6 -0
- package/dist/modules/shipment_tracking/tables/index.js.map +7 -0
- package/dist/modules/shipment_tracking/tables/tracking_job/table.client.js +284 -0
- package/dist/modules/shipment_tracking/tables/tracking_job/table.client.js.map +7 -0
- package/dist/modules/shipment_tracking/tables/tracking_job/table.js +36 -0
- package/dist/modules/shipment_tracking/tables/tracking_job/table.js.map +7 -0
- package/dist/modules/shipment_tracking/widgets/dashboard/ships-map/config.js +25 -0
- package/dist/modules/shipment_tracking/widgets/dashboard/ships-map/config.js.map +7 -0
- package/dist/modules/shipment_tracking/widgets/dashboard/ships-map/widget.client.js +355 -0
- package/dist/modules/shipment_tracking/widgets/dashboard/ships-map/widget.client.js.map +7 -0
- package/dist/modules/shipment_tracking/widgets/dashboard/ships-map/widget.js +26 -0
- package/dist/modules/shipment_tracking/widgets/dashboard/ships-map/widget.js.map +7 -0
- package/dist/types/assets.d.js +1 -0
- package/dist/types/assets.d.js.map +7 -0
- package/generated/entities/bic_config/index.ts +20 -0
- package/generated/entities/carrier_config/index.ts +23 -0
- package/generated/entities/location_override/index.ts +26 -0
- package/generated/entities/shipment/index.ts +46 -0
- package/generated/entities/ships_go_config/index.ts +25 -0
- package/generated/entities/tracking_event/index.ts +60 -0
- package/generated/entities/tracking_job/index.ts +33 -0
- package/generated/entities/webhook/index.ts +22 -0
- package/generated/entities/webhook_delivery/index.ts +22 -0
- package/generated/entities.ids.generated.ts +47 -0
- package/package.json +81 -0
- package/src/index.ts +39 -0
- package/src/modules/shipment_tracking/__integration__/TC-TRACK-410-shipsgo-config-api.spec.ts +133 -0
- package/src/modules/shipment_tracking/__integration__/meta.ts +4 -0
- package/src/modules/shipment_tracking/__tests__/empty-return-stop.test.ts +231 -0
- package/src/modules/shipment_tracking/__tests__/fixtures/hapag-lloyd-transship-container.json +702 -0
- package/src/modules/shipment_tracking/__tests__/fixtures/index.ts +434 -0
- package/src/modules/shipment_tracking/__tests__/fixtures/maersk-multi-transship-completed.json +1518 -0
- package/src/modules/shipment_tracking/__tests__/fixtures/maersk-transship-intransit.json +558 -0
- package/src/modules/shipment_tracking/__tests__/fixtures/msc-direct.json +222 -0
- package/src/modules/shipment_tracking/__tests__/fixtures/msc-multi-transship-completed.json +974 -0
- package/src/modules/shipment_tracking/__tests__/fixtures/msc-multi.json +4846 -0
- package/src/modules/shipment_tracking/__tests__/fixtures/msc-transship.json +409 -0
- package/src/modules/shipment_tracking/__tests__/fixtures/poi-events.json +240 -0
- package/src/modules/shipment_tracking/__tests__/fixtures/synthetic/index.ts +138 -0
- package/src/modules/shipment_tracking/__tests__/fixtures/synthetic-eta-updates.json +288 -0
- package/src/modules/shipment_tracking/__tests__/fixtures/synthetic-route-inference.json +201 -0
- package/src/modules/shipment_tracking/__tests__/fixtures/synthetic-voyage-progression.json +410 -0
- package/src/modules/shipment_tracking/__tests__/shipsgo-air-mapper.test.ts +157 -0
- package/src/modules/shipment_tracking/__tests__/shipsgo-client.test.ts +155 -0
- package/src/modules/shipment_tracking/__tests__/shipsgo-mapper.test.ts +201 -0
- package/src/modules/shipment_tracking/__tests__/shipsgo-poll.test.ts +357 -0
- package/src/modules/shipment_tracking/__tests__/shipsgo-provider.test.ts +364 -0
- package/src/modules/shipment_tracking/__tests__/trackingService.integration.test.ts +2248 -0
- package/src/modules/shipment_tracking/__tests__/webhookPayload.test.ts +151 -0
- package/src/modules/shipment_tracking/acl.ts +18 -0
- package/src/modules/shipment_tracking/api/bic-configs/route.ts +206 -0
- package/src/modules/shipment_tracking/api/bic-configs/test/route.ts +108 -0
- package/src/modules/shipment_tracking/api/cargo-events/route.ts +101 -0
- package/src/modules/shipment_tracking/api/carrier-configs/route.ts +142 -0
- package/src/modules/shipment_tracking/api/dashboard/ships-map/route.ts +246 -0
- package/src/modules/shipment_tracking/api/location-overrides/route.ts +185 -0
- package/src/modules/shipment_tracking/api/openapi.ts +28 -0
- package/src/modules/shipment_tracking/api/shipments/route.ts +197 -0
- package/src/modules/shipment_tracking/api/shipsgo-configs/route.ts +215 -0
- package/src/modules/shipment_tracking/api/tracking-jobs/route.ts +149 -0
- package/src/modules/shipment_tracking/api/tracking-jobs/sync/route.ts +116 -0
- package/src/modules/shipment_tracking/api/utils.ts +10 -0
- package/src/modules/shipment_tracking/api/webhooks/deliveries/route.ts +82 -0
- package/src/modules/shipment_tracking/api/webhooks/route.ts +138 -0
- package/src/modules/shipment_tracking/api/webhooks/test/route.ts +84 -0
- package/src/modules/shipment_tracking/assets/carriers/cma_cgm.png +0 -0
- package/src/modules/shipment_tracking/assets/carriers/cosco.png +0 -0
- package/src/modules/shipment_tracking/assets/carriers/evergreen.png +0 -0
- package/src/modules/shipment_tracking/assets/carriers/hapag_lloyd.png +0 -0
- package/src/modules/shipment_tracking/assets/carriers/maersk.png +0 -0
- package/src/modules/shipment_tracking/assets/carriers/msc.png +0 -0
- package/src/modules/shipment_tracking/assets/carriers/one.png +0 -0
- package/src/modules/shipment_tracking/assets/carriers/oocl.png +0 -0
- package/src/modules/shipment_tracking/assets/carriers/yang_ming.png +0 -0
- package/src/modules/shipment_tracking/assets/carriers/zim.png +0 -0
- package/src/modules/shipment_tracking/assets/index.ts +66 -0
- package/src/modules/shipment_tracking/backend/carrier-configs/page.meta.ts +16 -0
- package/src/modules/shipment_tracking/backend/carrier-configs/page.tsx +782 -0
- package/src/modules/shipment_tracking/backend/location-overrides/page.meta.ts +16 -0
- package/src/modules/shipment_tracking/backend/location-overrides/page.tsx +241 -0
- package/src/modules/shipment_tracking/backend/shipment-tracking/page.meta.ts +16 -0
- package/src/modules/shipment_tracking/backend/shipment-tracking/page.tsx +340 -0
- package/src/modules/shipment_tracking/backend/tracking-jobs/page.meta.ts +16 -0
- package/src/modules/shipment_tracking/backend/tracking-jobs/page.tsx +16 -0
- package/src/modules/shipment_tracking/backend/webhooks/page.meta.ts +16 -0
- package/src/modules/shipment_tracking/backend/webhooks/page.tsx +228 -0
- package/src/modules/shipment_tracking/ce.ts +48 -0
- package/src/modules/shipment_tracking/cli.ts +321 -0
- package/src/modules/shipment_tracking/commands/bic-configs.ts +94 -0
- package/src/modules/shipment_tracking/commands/carrier-configs.ts +89 -0
- package/src/modules/shipment_tracking/commands/index.ts +8 -0
- package/src/modules/shipment_tracking/commands/location-overrides.ts +119 -0
- package/src/modules/shipment_tracking/commands/shipments.ts +247 -0
- package/src/modules/shipment_tracking/commands/shipsgo-configs.ts +101 -0
- package/src/modules/shipment_tracking/commands/tracking-jobs.ts +158 -0
- package/src/modules/shipment_tracking/commands/tracking.ts +230 -0
- package/src/modules/shipment_tracking/commands/webhooks.ts +159 -0
- package/src/modules/shipment_tracking/components/CombinedTimestampCell.tsx +236 -0
- package/src/modules/shipment_tracking/components/FacilityLocationInput.tsx +235 -0
- package/src/modules/shipment_tracking/components/LocationOverrideDrawer.tsx +586 -0
- package/src/modules/shipment_tracking/components/ShipmentDetailsDrawer.tsx +1364 -0
- package/src/modules/shipment_tracking/components/ShipmentDrawer.tsx +498 -0
- package/src/modules/shipment_tracking/components/ShipsGoConfigSection.tsx +266 -0
- package/src/modules/shipment_tracking/components/TimestampCell.tsx +146 -0
- package/src/modules/shipment_tracking/components/TrackingJobDrawer.tsx +467 -0
- package/src/modules/shipment_tracking/components/VesselTrackingMap.tsx +761 -0
- package/src/modules/shipment_tracking/components/WebhookDrawer.tsx +434 -0
- package/src/modules/shipment_tracking/data/entities.ts +748 -0
- package/src/modules/shipment_tracking/data/validators.ts +523 -0
- package/src/modules/shipment_tracking/di.ts +73 -0
- package/src/modules/shipment_tracking/encryption.ts +17 -0
- package/src/modules/shipment_tracking/events.ts +122 -0
- package/src/modules/shipment_tracking/hooks/useVesselTracking.ts +297 -0
- package/src/modules/shipment_tracking/i18n/de.json +327 -0
- package/src/modules/shipment_tracking/i18n/en.json +327 -0
- package/src/modules/shipment_tracking/i18n/es.json +327 -0
- package/src/modules/shipment_tracking/i18n/pl.json +327 -0
- package/src/modules/shipment_tracking/index.ts +13 -0
- package/src/modules/shipment_tracking/lib/__tests__/dcsa-event-mapping.test.ts +385 -0
- package/src/modules/shipment_tracking/lib/__tests__/dcsa-event-parser.test.ts +398 -0
- package/src/modules/shipment_tracking/lib/__tests__/empty-return.test.ts +174 -0
- package/src/modules/shipment_tracking/lib/__tests__/poi-event-processor.test.ts +699 -0
- package/src/modules/shipment_tracking/lib/__tests__/route-inference.test.ts +402 -0
- package/src/modules/shipment_tracking/lib/__tests__/status-machine.test.ts +447 -0
- package/src/modules/shipment_tracking/lib/__tests__/time-extraction.test.ts +331 -0
- package/src/modules/shipment_tracking/lib/__tests__/timestamp-utils.test.ts +260 -0
- package/src/modules/shipment_tracking/lib/__tests__/vessel-api.test.ts +125 -0
- package/src/modules/shipment_tracking/lib/__tests__/vessel-extraction.test.ts +108 -0
- package/src/modules/shipment_tracking/lib/adapters/cma-cgm.ts +84 -0
- package/src/modules/shipment_tracking/lib/adapters/cosco-types.ts +145 -0
- package/src/modules/shipment_tracking/lib/adapters/cosco.ts +314 -0
- package/src/modules/shipment_tracking/lib/adapters/evergreen.ts +107 -0
- package/src/modules/shipment_tracking/lib/adapters/hapag-lloyd.ts +88 -0
- package/src/modules/shipment_tracking/lib/adapters/index.ts +18 -0
- package/src/modules/shipment_tracking/lib/adapters/maersk.ts +104 -0
- package/src/modules/shipment_tracking/lib/adapters/msc.ts +223 -0
- package/src/modules/shipment_tracking/lib/adapters/zim.ts +106 -0
- package/src/modules/shipment_tracking/lib/audit-helpers.ts +29 -0
- package/src/modules/shipment_tracking/lib/auth/base64url.ts +4 -0
- package/src/modules/shipment_tracking/lib/auth/oauth-client.ts +53 -0
- package/src/modules/shipment_tracking/lib/background.ts +24 -0
- package/src/modules/shipment_tracking/lib/bic-api-client.ts +199 -0
- package/src/modules/shipment_tracking/lib/carrier-adapter.ts +136 -0
- package/src/modules/shipment_tracking/lib/current-vessel.ts +274 -0
- package/src/modules/shipment_tracking/lib/dcsa-event-mapping.ts +202 -0
- package/src/modules/shipment_tracking/lib/dcsa-event-parser.ts +163 -0
- package/src/modules/shipment_tracking/lib/dcsa-params.ts +14 -0
- package/src/modules/shipment_tracking/lib/empty-return.ts +122 -0
- package/src/modules/shipment_tracking/lib/location-overrides.ts +150 -0
- package/src/modules/shipment_tracking/lib/location-types.ts +154 -0
- package/src/modules/shipment_tracking/lib/logger.ts +195 -0
- package/src/modules/shipment_tracking/lib/poi-event-processor.ts +302 -0
- package/src/modules/shipment_tracking/lib/poi-nats-config.ts +134 -0
- package/src/modules/shipment_tracking/lib/poi-types.ts +198 -0
- package/src/modules/shipment_tracking/lib/rate-limiter.ts +58 -0
- package/src/modules/shipment_tracking/lib/route-extraction.ts +439 -0
- package/src/modules/shipment_tracking/lib/route-inference.ts +238 -0
- package/src/modules/shipment_tracking/lib/schedule-generator.ts +92 -0
- package/src/modules/shipment_tracking/lib/shipsgo-client.ts +350 -0
- package/src/modules/shipment_tracking/lib/shipsgo-mapper.ts +296 -0
- package/src/modules/shipment_tracking/lib/status-machine.ts +230 -0
- package/src/modules/shipment_tracking/lib/time-extraction.ts +85 -0
- package/src/modules/shipment_tracking/lib/timestamp-utils.ts +244 -0
- package/src/modules/shipment_tracking/lib/vessel-api.ts +299 -0
- package/src/modules/shipment_tracking/lib/vessel-cache.ts +102 -0
- package/src/modules/shipment_tracking/lib/vessel-extraction.ts +39 -0
- package/src/modules/shipment_tracking/lib/webhook-dispatcher.ts +93 -0
- package/src/modules/shipment_tracking/migrations/.snapshot-open-mercato.json +2914 -0
- package/src/modules/shipment_tracking/migrations/Migration20260422161208_shipment_tracking.ts +60 -0
- package/src/modules/shipment_tracking/migrations/Migration20260529120000_shipment_tracking_poi_region_names.ts +22 -0
- package/src/modules/shipment_tracking/migrations/Migration20260821120000_shipment_tracking_shipsgo.ts +65 -0
- package/src/modules/shipment_tracking/notifications.ts +151 -0
- package/src/modules/shipment_tracking/services/carrierRegistry.ts +29 -0
- package/src/modules/shipment_tracking/services/poiNatsService.ts +526 -0
- package/src/modules/shipment_tracking/services/shipsGoProvider.ts +231 -0
- package/src/modules/shipment_tracking/services/trackingService.ts +1777 -0
- package/src/modules/shipment_tracking/services/webhookService.ts +347 -0
- package/src/modules/shipment_tracking/setup.ts +99 -0
- package/src/modules/shipment_tracking/subscribers/__tests__/terminal-event-ingest.test.ts +141 -0
- package/src/modules/shipment_tracking/subscribers/cargo-event-created.ts +115 -0
- package/src/modules/shipment_tracking/subscribers/dcsa-event-webhook-dispatch.ts +115 -0
- package/src/modules/shipment_tracking/subscribers/poi-event-notification.ts +144 -0
- package/src/modules/shipment_tracking/subscribers/poi-event-webhook-dispatch.ts +94 -0
- package/src/modules/shipment_tracking/subscribers/shipment-status-changed.ts +41 -0
- package/src/modules/shipment_tracking/subscribers/terminal-event-ingest.ts +109 -0
- package/src/modules/shipment_tracking/subscribers/tracking-job-initial-poll.ts +53 -0
- package/src/modules/shipment_tracking/subscribers/tracking-job-webhook-dispatch.ts +50 -0
- package/src/modules/shipment_tracking/tables/index.ts +4 -0
- package/src/modules/shipment_tracking/tables/tracking_job/table.client.tsx +337 -0
- package/src/modules/shipment_tracking/tables/tracking_job/table.ts +34 -0
- package/src/modules/shipment_tracking/widgets/dashboard/ships-map/config.ts +32 -0
- package/src/modules/shipment_tracking/widgets/dashboard/ships-map/widget.client.tsx +448 -0
- package/src/modules/shipment_tracking/widgets/dashboard/ships-map/widget.ts +25 -0
- package/src/types/assets.d.ts +5 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/modules/shipment_tracking/commands/tracking.ts"],
|
|
4
|
+
"sourcesContent": ["import { registerCommand } from '@open-mercato/shared/lib/commands'\nimport type { CommandHandler, CommandRuntimeContext } from '@open-mercato/shared/lib/commands'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport type { EventBus } from '@open-mercato/events'\nimport type { TrackingService } from '../services/trackingService'\nimport { Shipment } from '../data/entities'\nimport { evaluatePreArrivalUpgrade } from '../lib/status-machine'\nimport { getPrimaryTimestampValue } from '../lib/timestamp-utils'\n\nfunction ensureScope(ctx: CommandRuntimeContext, tenantId: string, organizationId?: string) {\n if (ctx.auth?.tenantId && ctx.auth.tenantId !== tenantId) {\n throw new Error('Tenant mismatch')\n }\n if (organizationId && !ctx.auth?.isSuperAdmin && ctx.auth?.organizationId && ctx.auth.organizationId !== organizationId) {\n throw new Error('Organization mismatch')\n }\n}\n\ntype PollAllInput = {\n tenantId: string\n organizationId?: string\n}\n\ntype PollAllResult = {\n polled: number\n newEvents: number\n failed: number\n}\n\n/**\n * Command to poll all active tracking jobs for a tenant/organization.\n * This is called by the scheduler for daily re-polling.\n */\nconst pollAllActiveJobs: CommandHandler<PollAllInput, PollAllResult> = {\n id: 'shipment_tracking.tracking.poll_all',\n\n async execute(input, ctx) {\n ensureScope(ctx, input.tenantId, input.organizationId)\n\n const trackingService = ctx.container.resolve<TrackingService>('shipmentTrackingService')\n\n const result = await trackingService.pollAllActiveJobs(input.tenantId, input.organizationId)\n\n console.log('[shipment-tracking:poll_all] Command completed:', {\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n ...result,\n })\n\n return result\n },\n\n buildLog({ result, input }) {\n return {\n actionLabel: 'Poll all tracking jobs',\n resourceKind: 'shipment_tracking.tracking',\n resourceId: input.organizationId ?? input.tenantId,\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n details: {\n polled: result.polled,\n newEvents: result.newEvents,\n failed: result.failed,\n },\n }\n },\n}\n\ntype PollSingleInput = {\n jobId: string\n tenantId: string\n organizationId: string\n}\n\ntype PollSingleResult = {\n newEvents: number\n shipmentsCreated: number\n shipmentsUpdated: number\n}\n\n/**\n * Command to poll a single tracking job.\n * Can be called manually to trigger an immediate poll.\n */\nconst pollSingleJob: CommandHandler<PollSingleInput, PollSingleResult> = {\n id: 'shipment_tracking.tracking.poll_single',\n\n async execute(input, ctx) {\n ensureScope(ctx, input.tenantId, input.organizationId)\n\n const trackingService = ctx.container.resolve<TrackingService>('shipmentTrackingService')\n\n const result = await trackingService.pollTrackingJob(input.jobId)\n\n return {\n newEvents: result.newEvents,\n shipmentsCreated: result.shipmentsCreated,\n shipmentsUpdated: result.shipmentsUpdated,\n }\n },\n\n buildLog({ result, input }) {\n return {\n actionLabel: 'Poll tracking job',\n resourceKind: 'shipment_tracking.tracking_job',\n resourceId: input.jobId,\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n details: {\n newEvents: result.newEvents,\n shipmentsCreated: result.shipmentsCreated,\n shipmentsUpdated: result.shipmentsUpdated,\n },\n }\n },\n}\n\ntype EvaluatePreArrivalInput = {\n tenantId: string\n organizationId?: string\n}\n\ntype EvaluatePreArrivalResult = {\n evaluated: number\n upgraded: number\n}\n\n/**\n * Command to evaluate IN_TRANSIT shipments for PRE_ARRIVAL status upgrade.\n * This is called by the scheduler to check shipments approaching their destination.\n *\n * A shipment is upgraded to PRE_ARRIVAL when:\n * - Current status is IN_TRANSIT\n * - ETA is within 7 days\n * - No ATA (actual arrival) yet\n */\nconst evaluatePreArrival: CommandHandler<EvaluatePreArrivalInput, EvaluatePreArrivalResult> = {\n id: 'shipment_tracking.tracking.evaluate_pre_arrival',\n\n async execute(input, ctx) {\n ensureScope(ctx, input.tenantId, input.organizationId)\n\n const em = ctx.container.resolve<EntityManager>('em')\n const eventBus = ctx.container.resolve<EventBus>('eventBus')\n\n // Find all IN_TRANSIT shipments for the tenant/organization\n const filters: Record<string, unknown> = {\n tenantId: input.tenantId,\n status: 'IN_TRANSIT',\n deletedAt: null,\n }\n\n if (input.organizationId) {\n filters.organizationId = input.organizationId\n }\n\n const shipments = await em.find(Shipment, filters)\n\n let upgraded = 0\n\n for (const shipment of shipments) {\n const eta = getPrimaryTimestampValue(shipment.etaTimestamps)\n const ata = getPrimaryTimestampValue(shipment.ataTimestamps)\n\n const newStatus = evaluatePreArrivalUpgrade(shipment.status, { eta, ata })\n\n if (newStatus !== shipment.status) {\n const previousStatus = shipment.status\n shipment.status = newStatus\n\n // Emit status_changed event\n await eventBus.emit('shipment_tracking.shipment.status_changed', {\n id: shipment.id,\n previousStatus,\n newStatus,\n tenantId: shipment.tenantId,\n organizationId: shipment.organizationId,\n })\n\n // Emit pre_arrival lifecycle event\n await eventBus.emit('shipment_tracking.shipment.pre_arrival', {\n id: shipment.id,\n tenantId: shipment.tenantId,\n organizationId: shipment.organizationId,\n })\n\n // Emit updated event\n await eventBus.emit('shipment_tracking.shipment.updated', {\n id: shipment.id,\n tenantId: shipment.tenantId,\n organizationId: shipment.organizationId,\n })\n\n upgraded++\n }\n }\n\n await em.flush()\n\n console.log('[shipment-tracking:evaluate_pre_arrival] Command completed:', {\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n evaluated: shipments.length,\n upgraded,\n })\n\n return {\n evaluated: shipments.length,\n upgraded,\n }\n },\n\n buildLog({ result, input }) {\n return {\n actionLabel: 'Evaluate PRE_ARRIVAL status',\n resourceKind: 'shipment_tracking.tracking',\n resourceId: input.organizationId ?? input.tenantId,\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n details: {\n evaluated: result.evaluated,\n upgraded: result.upgraded,\n },\n }\n },\n}\n\nregisterCommand(pollAllActiveJobs)\nregisterCommand(pollSingleJob)\nregisterCommand(evaluatePreArrival)\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { registerCommand } from "@open-mercato/shared/lib/commands";
|
|
2
|
+
import { findOneWithDecryption, findWithDecryption } from "@open-mercato/shared/lib/encryption/find";
|
|
3
|
+
import { Webhook, WebhookDelivery } from "../data/entities.js";
|
|
4
|
+
import { dispatchWebhook } from "../lib/webhook-dispatcher.js";
|
|
5
|
+
function ensureScope(ctx, tenantId, organizationId) {
|
|
6
|
+
if (ctx.auth?.tenantId && ctx.auth.tenantId !== tenantId) {
|
|
7
|
+
throw new Error("Tenant mismatch");
|
|
8
|
+
}
|
|
9
|
+
if (!ctx.auth?.isSuperAdmin && ctx.auth?.organizationId && ctx.auth.organizationId !== organizationId) {
|
|
10
|
+
throw new Error("Organization mismatch");
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
const createWebhook = {
|
|
14
|
+
id: "shipment_tracking.webhook.create",
|
|
15
|
+
async execute(input, ctx) {
|
|
16
|
+
ensureScope(ctx, input.tenantId, input.organizationId);
|
|
17
|
+
const em = ctx.container.resolve("em").fork();
|
|
18
|
+
const webhook = em.create(Webhook, {
|
|
19
|
+
organizationId: input.organizationId,
|
|
20
|
+
tenantId: input.tenantId,
|
|
21
|
+
url: input.url,
|
|
22
|
+
eventsSubscribed: input.eventsSubscribed,
|
|
23
|
+
hmacSecret: input.hmacSecret ?? null,
|
|
24
|
+
isActive: input.isActive ?? true
|
|
25
|
+
});
|
|
26
|
+
await em.flush();
|
|
27
|
+
return { id: webhook.id };
|
|
28
|
+
},
|
|
29
|
+
async undo({ input, ctx }) {
|
|
30
|
+
const em = ctx.container.resolve("em").fork();
|
|
31
|
+
const webhooks = await findWithDecryption(em, Webhook, {
|
|
32
|
+
tenantId: input.tenantId,
|
|
33
|
+
organizationId: input.organizationId
|
|
34
|
+
}, { orderBy: { createdAt: "desc" }, limit: 1 });
|
|
35
|
+
const webhook = webhooks[0];
|
|
36
|
+
if (webhook) {
|
|
37
|
+
em.remove(webhook);
|
|
38
|
+
await em.flush();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
};
|
|
42
|
+
const updateWebhook = {
|
|
43
|
+
id: "shipment_tracking.webhook.update",
|
|
44
|
+
async execute(input, ctx) {
|
|
45
|
+
const em = ctx.container.resolve("em").fork();
|
|
46
|
+
const webhook = await findOneWithDecryption(em, Webhook, { id: input.id });
|
|
47
|
+
if (!webhook) throw new Error("Webhook not found");
|
|
48
|
+
ensureScope(ctx, webhook.tenantId, webhook.organizationId);
|
|
49
|
+
if (input.url !== void 0) webhook.url = input.url;
|
|
50
|
+
if (input.eventsSubscribed !== void 0) webhook.eventsSubscribed = input.eventsSubscribed;
|
|
51
|
+
if (input.hmacSecret !== void 0) webhook.hmacSecret = input.hmacSecret;
|
|
52
|
+
if (input.isActive !== void 0) webhook.isActive = input.isActive;
|
|
53
|
+
await em.flush();
|
|
54
|
+
return { id: webhook.id };
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
const deleteWebhook = {
|
|
58
|
+
id: "shipment_tracking.webhook.delete",
|
|
59
|
+
async execute(input, ctx) {
|
|
60
|
+
ensureScope(ctx, input.tenantId, input.organizationId);
|
|
61
|
+
const em = ctx.container.resolve("em").fork();
|
|
62
|
+
const webhook = await findOneWithDecryption(em, Webhook, { id: input.id });
|
|
63
|
+
if (!webhook) throw new Error("Webhook not found");
|
|
64
|
+
em.remove(webhook);
|
|
65
|
+
await em.flush();
|
|
66
|
+
return { id: input.id };
|
|
67
|
+
}
|
|
68
|
+
};
|
|
69
|
+
const testWebhook = {
|
|
70
|
+
id: "shipment_tracking.webhook.test",
|
|
71
|
+
async execute(input, ctx) {
|
|
72
|
+
ensureScope(ctx, input.tenantId, input.organizationId);
|
|
73
|
+
const em = ctx.container.resolve("em").fork();
|
|
74
|
+
const webhook = await findOneWithDecryption(em, Webhook, { id: input.id });
|
|
75
|
+
if (!webhook) throw new Error("Webhook not found");
|
|
76
|
+
if (!webhook.isActive) {
|
|
77
|
+
throw new Error("Webhook is inactive");
|
|
78
|
+
}
|
|
79
|
+
const testPayload = {
|
|
80
|
+
type: "test",
|
|
81
|
+
event: "webhook.test",
|
|
82
|
+
message: "This is a test webhook delivery from Shipment Tracking",
|
|
83
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
84
|
+
webhookId: webhook.id
|
|
85
|
+
};
|
|
86
|
+
const delivery = em.create(WebhookDelivery, {
|
|
87
|
+
webhook: em.getReference(Webhook, webhook.id),
|
|
88
|
+
eventType: "webhook.test",
|
|
89
|
+
status: "pending",
|
|
90
|
+
payload: testPayload,
|
|
91
|
+
retryCount: 0
|
|
92
|
+
});
|
|
93
|
+
em.persist(delivery);
|
|
94
|
+
await em.flush();
|
|
95
|
+
const result = await dispatchWebhook({
|
|
96
|
+
url: webhook.url,
|
|
97
|
+
payload: testPayload,
|
|
98
|
+
hmacSecret: webhook.hmacSecret
|
|
99
|
+
});
|
|
100
|
+
delivery.responseStatus = result.responseStatus ?? null;
|
|
101
|
+
delivery.responseBody = result.responseBody ?? null;
|
|
102
|
+
delivery.status = result.success ? "success" : "failed";
|
|
103
|
+
delivery.errorMessage = result.errorMessage ?? null;
|
|
104
|
+
await em.flush();
|
|
105
|
+
if (!result.success) {
|
|
106
|
+
throw new Error(result.errorMessage || "Webhook delivery failed");
|
|
107
|
+
}
|
|
108
|
+
return { success: true, deliveryId: delivery.id };
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
registerCommand(createWebhook);
|
|
112
|
+
registerCommand(updateWebhook);
|
|
113
|
+
registerCommand(deleteWebhook);
|
|
114
|
+
registerCommand(testWebhook);
|
|
115
|
+
//# sourceMappingURL=webhooks.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/modules/shipment_tracking/commands/webhooks.ts"],
|
|
4
|
+
"sourcesContent": ["import { registerCommand } from '@open-mercato/shared/lib/commands'\nimport type { CommandHandler, CommandRuntimeContext } from '@open-mercato/shared/lib/commands'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { findOneWithDecryption, findWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport { Webhook, WebhookDelivery } from '../data/entities'\nimport type { WebhookCreateInput, WebhookUpdateInput } from '../data/validators'\nimport { dispatchWebhook } from '../lib/webhook-dispatcher'\n\nfunction ensureScope(ctx: CommandRuntimeContext, tenantId: string, organizationId: string) {\n if (ctx.auth?.tenantId && ctx.auth.tenantId !== tenantId) {\n throw new Error('Tenant mismatch')\n }\n if (!ctx.auth?.isSuperAdmin && ctx.auth?.organizationId && ctx.auth.organizationId !== organizationId) {\n throw new Error('Organization mismatch')\n }\n}\n\nconst createWebhook: CommandHandler<WebhookCreateInput, { id: string }> = {\n id: 'shipment_tracking.webhook.create',\n\n async execute(input, ctx) {\n ensureScope(ctx, input.tenantId, input.organizationId)\n\n const em = ctx.container.resolve<EntityManager>('em').fork()\n\n const webhook = em.create(Webhook, {\n organizationId: input.organizationId,\n tenantId: input.tenantId,\n url: input.url,\n eventsSubscribed: input.eventsSubscribed,\n hmacSecret: input.hmacSecret ?? null,\n isActive: input.isActive ?? true,\n })\n\n await em.flush()\n\n return { id: webhook.id }\n },\n\n async undo({ input, ctx }) {\n const em = ctx.container.resolve<EntityManager>('em').fork()\n const webhooks = await findWithDecryption(em, Webhook, {\n tenantId: input.tenantId,\n organizationId: input.organizationId,\n }, { orderBy: { createdAt: 'desc' }, limit: 1 })\n const webhook = webhooks[0]\n if (webhook) {\n em.remove(webhook)\n await em.flush()\n }\n },\n}\n\nconst updateWebhook: CommandHandler<WebhookUpdateInput, { id: string }> = {\n id: 'shipment_tracking.webhook.update',\n\n async execute(input, ctx) {\n const em = ctx.container.resolve<EntityManager>('em').fork()\n\n const webhook = await findOneWithDecryption(em, Webhook, { id: input.id })\n if (!webhook) throw new Error('Webhook not found')\n\n ensureScope(ctx, webhook.tenantId, webhook.organizationId)\n\n if (input.url !== undefined) webhook.url = input.url\n if (input.eventsSubscribed !== undefined) webhook.eventsSubscribed = input.eventsSubscribed\n if (input.hmacSecret !== undefined) webhook.hmacSecret = input.hmacSecret\n if (input.isActive !== undefined) webhook.isActive = input.isActive\n\n await em.flush()\n\n return { id: webhook.id }\n },\n}\n\nconst deleteWebhook: CommandHandler<{ id: string; tenantId: string; organizationId: string }, { id: string }> = {\n id: 'shipment_tracking.webhook.delete',\n\n async execute(input, ctx) {\n ensureScope(ctx, input.tenantId, input.organizationId)\n\n const em = ctx.container.resolve<EntityManager>('em').fork()\n\n const webhook = await findOneWithDecryption(em, Webhook, { id: input.id })\n if (!webhook) throw new Error('Webhook not found')\n\n em.remove(webhook)\n await em.flush()\n\n return { id: input.id }\n },\n}\n\nconst testWebhook: CommandHandler<\n { id: string; tenantId: string; organizationId: string },\n { success: boolean; deliveryId: string }\n> = {\n id: 'shipment_tracking.webhook.test',\n\n async execute(input, ctx) {\n ensureScope(ctx, input.tenantId, input.organizationId)\n\n const em = ctx.container.resolve<EntityManager>('em').fork()\n\n const webhook = await findOneWithDecryption(em, Webhook, { id: input.id })\n if (!webhook) throw new Error('Webhook not found')\n\n if (!webhook.isActive) {\n throw new Error('Webhook is inactive')\n }\n\n // Build test payload\n const testPayload = {\n type: 'test',\n event: 'webhook.test',\n message: 'This is a test webhook delivery from Shipment Tracking',\n timestamp: new Date().toISOString(),\n webhookId: webhook.id,\n }\n\n // Create delivery record\n // Use getReference to create a managed reference since webhook may be detached after decryption\n const delivery = em.create(WebhookDelivery, {\n webhook: em.getReference(Webhook, webhook.id),\n eventType: 'webhook.test',\n status: 'pending',\n payload: testPayload,\n retryCount: 0,\n })\n\n em.persist(delivery)\n await em.flush()\n\n // Dispatch synchronously for immediate feedback\n const result = await dispatchWebhook({\n url: webhook.url,\n payload: testPayload,\n hmacSecret: webhook.hmacSecret,\n })\n\n // Update delivery record with result\n delivery.responseStatus = result.responseStatus ?? null\n delivery.responseBody = result.responseBody ?? null\n delivery.status = result.success ? 'success' : 'failed'\n delivery.errorMessage = result.errorMessage ?? null\n await em.flush()\n\n if (!result.success) {\n throw new Error(result.errorMessage || 'Webhook delivery failed')\n }\n\n return { success: true, deliveryId: delivery.id }\n },\n}\n\nregisterCommand(createWebhook)\nregisterCommand(updateWebhook)\nregisterCommand(deleteWebhook)\nregisterCommand(testWebhook)\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import {
|
|
4
|
+
Tooltip,
|
|
5
|
+
TooltipContent,
|
|
6
|
+
TooltipProvider,
|
|
7
|
+
TooltipTrigger
|
|
8
|
+
} from "@freighttech/ui/primitives/tooltip";
|
|
9
|
+
import { useT } from "@open-mercato/shared/lib/i18n/context";
|
|
10
|
+
const SOURCE_LABELS = {
|
|
11
|
+
carrier_api: "Carrier API",
|
|
12
|
+
manual: "Manual",
|
|
13
|
+
ais: "AIS",
|
|
14
|
+
port: "Port",
|
|
15
|
+
edi: "EDI"
|
|
16
|
+
};
|
|
17
|
+
const SOURCE_COLORS = {
|
|
18
|
+
carrier_api: "bg-blue-100 text-blue-700",
|
|
19
|
+
manual: "bg-purple-100 text-purple-700",
|
|
20
|
+
ais: "bg-green-100 text-green-700",
|
|
21
|
+
port: "bg-orange-100 text-orange-700",
|
|
22
|
+
edi: "bg-gray-100 text-gray-700"
|
|
23
|
+
};
|
|
24
|
+
function formatDate(date) {
|
|
25
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
26
|
+
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
27
|
+
const year = date.getFullYear();
|
|
28
|
+
return `${day}/${month}/${year}`;
|
|
29
|
+
}
|
|
30
|
+
function FormattedDate({ date }) {
|
|
31
|
+
const day = String(date.getDate()).padStart(2, "0");
|
|
32
|
+
const month = String(date.getMonth() + 1).padStart(2, "0");
|
|
33
|
+
const year = date.getFullYear();
|
|
34
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
35
|
+
day,
|
|
36
|
+
/* @__PURE__ */ jsx("span", { className: "opacity-50", children: "/" }),
|
|
37
|
+
month,
|
|
38
|
+
/* @__PURE__ */ jsx("span", { className: "opacity-50", children: "/" }),
|
|
39
|
+
year
|
|
40
|
+
] });
|
|
41
|
+
}
|
|
42
|
+
function formatTimestamp(value, offset, format) {
|
|
43
|
+
const date = new Date(value);
|
|
44
|
+
if (Number.isNaN(date.getTime())) return "-";
|
|
45
|
+
if (format === "date") {
|
|
46
|
+
return formatDate(date);
|
|
47
|
+
}
|
|
48
|
+
const timeStr = date.toLocaleTimeString(void 0, { hour: "2-digit", minute: "2-digit" });
|
|
49
|
+
const dateStr = formatDate(date);
|
|
50
|
+
const offsetStr = offset ? ` (${offset})` : "";
|
|
51
|
+
return `${dateStr} ${timeStr}${offsetStr}`;
|
|
52
|
+
}
|
|
53
|
+
function FormattedTimestamp({ value, offset, format }) {
|
|
54
|
+
const date = new Date(value);
|
|
55
|
+
if (Number.isNaN(date.getTime())) return /* @__PURE__ */ jsx(Fragment, { children: "-" });
|
|
56
|
+
if (format === "date") {
|
|
57
|
+
return /* @__PURE__ */ jsx(FormattedDate, { date });
|
|
58
|
+
}
|
|
59
|
+
const timeStr = date.toLocaleTimeString(void 0, { hour: "2-digit", minute: "2-digit" });
|
|
60
|
+
const offsetStr = offset ? ` (${offset})` : "";
|
|
61
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
62
|
+
/* @__PURE__ */ jsx(FormattedDate, { date }),
|
|
63
|
+
" ",
|
|
64
|
+
timeStr,
|
|
65
|
+
offsetStr
|
|
66
|
+
] });
|
|
67
|
+
}
|
|
68
|
+
function formatUpdatedAt(value) {
|
|
69
|
+
const date = new Date(value);
|
|
70
|
+
if (Number.isNaN(date.getTime())) return "-";
|
|
71
|
+
return date.toLocaleString(void 0, {
|
|
72
|
+
month: "short",
|
|
73
|
+
day: "numeric",
|
|
74
|
+
hour: "2-digit",
|
|
75
|
+
minute: "2-digit"
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
function combineTimestamps(estimatedTimestamps, actualTimestamps) {
|
|
79
|
+
const combined = [];
|
|
80
|
+
if (estimatedTimestamps) {
|
|
81
|
+
for (const entry of estimatedTimestamps) {
|
|
82
|
+
combined.push({ ...entry, isActual: false });
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (actualTimestamps) {
|
|
86
|
+
for (const entry of actualTimestamps) {
|
|
87
|
+
combined.push({ ...entry, isActual: true });
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return combined;
|
|
91
|
+
}
|
|
92
|
+
function getLatestEntry(entries) {
|
|
93
|
+
if (entries.length === 0) return null;
|
|
94
|
+
return entries.reduce(
|
|
95
|
+
(latest, entry) => entry.updatedAt > latest.updatedAt ? entry : latest
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
function CombinedTimestampCell({
|
|
99
|
+
estimatedTimestamps,
|
|
100
|
+
actualTimestamps,
|
|
101
|
+
label,
|
|
102
|
+
format = "date"
|
|
103
|
+
}) {
|
|
104
|
+
const t = useT();
|
|
105
|
+
const combined = combineTimestamps(estimatedTimestamps, actualTimestamps);
|
|
106
|
+
if (combined.length === 0) {
|
|
107
|
+
return /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "-" });
|
|
108
|
+
}
|
|
109
|
+
const latest = getLatestEntry(combined);
|
|
110
|
+
if (!latest) {
|
|
111
|
+
return /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "-" });
|
|
112
|
+
}
|
|
113
|
+
const hasHistory = combined.length > 1;
|
|
114
|
+
const sortedHistory = [...combined].sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
|
|
115
|
+
const typeBadgeClass = latest.isActual ? "bg-green-100 text-green-700" : "bg-gray-100 text-gray-600";
|
|
116
|
+
const typeBadgeLabel = latest.isActual ? t("shipment_tracking.timestamps.actual", "Actual") : t("shipment_tracking.timestamps.estimated", "Est.");
|
|
117
|
+
return /* @__PURE__ */ jsx(TooltipProvider, { children: /* @__PURE__ */ jsxs(Tooltip, { delayDuration: 200, children: [
|
|
118
|
+
/* @__PURE__ */ jsx(TooltipTrigger, { asChild: true, children: /* @__PURE__ */ jsxs("span", { className: `inline-flex items-center gap-1.5 cursor-help ${hasHistory ? "border-b border-dashed border-muted-foreground/50" : ""}`, children: [
|
|
119
|
+
/* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(FormattedTimestamp, { value: latest.value, offset: latest.offset, format }) }),
|
|
120
|
+
/* @__PURE__ */ jsx("span", { className: `inline-flex items-center rounded px-1 py-0.5 text-[10px] font-medium ${typeBadgeClass}`, children: typeBadgeLabel }),
|
|
121
|
+
hasHistory && /* @__PURE__ */ jsxs("span", { className: "text-[10px] text-muted-foreground", children: [
|
|
122
|
+
"(",
|
|
123
|
+
combined.length,
|
|
124
|
+
")"
|
|
125
|
+
] })
|
|
126
|
+
] }) }),
|
|
127
|
+
/* @__PURE__ */ jsx(TooltipContent, { side: "bottom", align: "start", className: "max-w-sm p-0", children: /* @__PURE__ */ jsxs("div", { className: "p-2 space-y-2", children: [
|
|
128
|
+
/* @__PURE__ */ jsx("div", { className: "text-xs font-medium text-muted-foreground border-b pb-1 mb-2", children: t(`shipment_tracking.timestamps.${label.replace("/", "_").toLowerCase()}History`, `${label} History`) }),
|
|
129
|
+
/* @__PURE__ */ jsx("div", { className: "space-y-1.5 max-h-64 overflow-y-auto", children: sortedHistory.map((entry, index) => {
|
|
130
|
+
const isLatest = entry === latest;
|
|
131
|
+
const entryTypeBadgeClass = entry.isActual ? "bg-green-100 text-green-700" : "bg-slate-200 text-slate-700";
|
|
132
|
+
const entryTypeBadgeLabel = entry.isActual ? t("shipment_tracking.timestamps.actual", "Actual") : t("shipment_tracking.timestamps.estimated", "Est.");
|
|
133
|
+
return /* @__PURE__ */ jsxs(
|
|
134
|
+
"div",
|
|
135
|
+
{
|
|
136
|
+
className: `text-xs rounded p-1.5 ${isLatest ? "bg-accent" : "bg-muted"}`,
|
|
137
|
+
children: [
|
|
138
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2", children: [
|
|
139
|
+
/* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: formatTimestamp(entry.value, entry.offset, "datetime") }),
|
|
140
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center gap-1", children: [
|
|
141
|
+
/* @__PURE__ */ jsx("span", { className: `inline-flex items-center rounded px-1 py-0.5 text-[10px] font-medium ${entryTypeBadgeClass}`, children: entryTypeBadgeLabel }),
|
|
142
|
+
/* @__PURE__ */ jsx("span", { className: `inline-flex items-center rounded px-1 py-0.5 text-[10px] font-medium ${SOURCE_COLORS[entry.source] || "bg-gray-100 text-gray-700"}`, children: SOURCE_LABELS[entry.source] || entry.source })
|
|
143
|
+
] })
|
|
144
|
+
] }),
|
|
145
|
+
/* @__PURE__ */ jsxs("div", { className: "text-[10px] text-muted-foreground mt-0.5", children: [
|
|
146
|
+
t("shipment_tracking.timestamps.updatedAt", "Updated"),
|
|
147
|
+
": ",
|
|
148
|
+
formatUpdatedAt(entry.updatedAt),
|
|
149
|
+
isLatest && /* @__PURE__ */ jsxs("span", { className: "ml-1 text-primary font-medium", children: [
|
|
150
|
+
"(",
|
|
151
|
+
t("shipment_tracking.timestamps.latest", "latest"),
|
|
152
|
+
")"
|
|
153
|
+
] })
|
|
154
|
+
] })
|
|
155
|
+
]
|
|
156
|
+
},
|
|
157
|
+
`${entry.value}-${entry.updatedAt}-${index}`
|
|
158
|
+
);
|
|
159
|
+
}) })
|
|
160
|
+
] }) })
|
|
161
|
+
] }) });
|
|
162
|
+
}
|
|
163
|
+
var CombinedTimestampCell_default = CombinedTimestampCell;
|
|
164
|
+
export {
|
|
165
|
+
CombinedTimestampCell,
|
|
166
|
+
CombinedTimestampCell_default as default
|
|
167
|
+
};
|
|
168
|
+
//# sourceMappingURL=CombinedTimestampCell.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/modules/shipment_tracking/components/CombinedTimestampCell.tsx"],
|
|
4
|
+
"sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from '@freighttech/ui/primitives/tooltip'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\n\nexport type TimestampEntry = {\n value: string\n offset: string | null\n source: 'carrier_api' | 'manual' | 'ais' | 'port' | 'edi'\n updatedAt: string\n sourceEventId?: string | null\n}\n\ntype CombinedEntry = TimestampEntry & {\n isActual: boolean\n}\n\ntype CombinedTimestampCellProps = {\n estimatedTimestamps: TimestampEntry[] | null | undefined\n actualTimestamps: TimestampEntry[] | null | undefined\n label: 'ETD/ATD' | 'ETA/ATA'\n format?: 'date' | 'datetime'\n}\n\nconst SOURCE_LABELS: Record<string, string> = {\n carrier_api: 'Carrier API',\n manual: 'Manual',\n ais: 'AIS',\n port: 'Port',\n edi: 'EDI',\n}\n\nconst SOURCE_COLORS: Record<string, string> = {\n carrier_api: 'bg-blue-100 text-blue-700',\n manual: 'bg-purple-100 text-purple-700',\n ais: 'bg-green-100 text-green-700',\n port: 'bg-orange-100 text-orange-700',\n edi: 'bg-gray-100 text-gray-700',\n}\n\nfunction formatDate(date: Date): string {\n const day = String(date.getDate()).padStart(2, '0')\n const month = String(date.getMonth() + 1).padStart(2, '0')\n const year = date.getFullYear()\n return `${day}/${month}/${year}`\n}\n\nfunction FormattedDate({ date }: { date: Date }) {\n const day = String(date.getDate()).padStart(2, '0')\n const month = String(date.getMonth() + 1).padStart(2, '0')\n const year = date.getFullYear()\n return (\n <>\n {day}<span className=\"opacity-50\">/</span>{month}<span className=\"opacity-50\">/</span>{year}\n </>\n )\n}\n\nfunction formatTimestamp(value: string, offset: string | null, format: 'date' | 'datetime'): string {\n const date = new Date(value)\n if (Number.isNaN(date.getTime())) return '-'\n\n if (format === 'date') {\n return formatDate(date)\n }\n\n // Include time\n const timeStr = date.toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit' })\n const dateStr = formatDate(date)\n const offsetStr = offset ? ` (${offset})` : ''\n return `${dateStr} ${timeStr}${offsetStr}`\n}\n\nfunction FormattedTimestamp({ value, offset, format }: { value: string; offset: string | null; format: 'date' | 'datetime' }) {\n const date = new Date(value)\n if (Number.isNaN(date.getTime())) return <>-</>\n\n if (format === 'date') {\n return <FormattedDate date={date} />\n }\n\n const timeStr = date.toLocaleTimeString(undefined, { hour: '2-digit', minute: '2-digit' })\n const offsetStr = offset ? ` (${offset})` : ''\n return (\n <>\n <FormattedDate date={date} /> {timeStr}{offsetStr}\n </>\n )\n}\n\nfunction formatUpdatedAt(value: string): string {\n const date = new Date(value)\n if (Number.isNaN(date.getTime())) return '-'\n return date.toLocaleString(undefined, {\n month: 'short',\n day: 'numeric',\n hour: '2-digit',\n minute: '2-digit',\n })\n}\n\nfunction combineTimestamps(\n estimatedTimestamps: TimestampEntry[] | null | undefined,\n actualTimestamps: TimestampEntry[] | null | undefined\n): CombinedEntry[] {\n const combined: CombinedEntry[] = []\n\n if (estimatedTimestamps) {\n for (const entry of estimatedTimestamps) {\n combined.push({ ...entry, isActual: false })\n }\n }\n\n if (actualTimestamps) {\n for (const entry of actualTimestamps) {\n combined.push({ ...entry, isActual: true })\n }\n }\n\n return combined\n}\n\nfunction getLatestEntry(entries: CombinedEntry[]): CombinedEntry | null {\n if (entries.length === 0) return null\n return entries.reduce((latest, entry) =>\n entry.updatedAt > latest.updatedAt ? entry : latest\n )\n}\n\nexport function CombinedTimestampCell({\n estimatedTimestamps,\n actualTimestamps,\n label,\n format = 'date',\n}: CombinedTimestampCellProps) {\n const t = useT()\n\n const combined = combineTimestamps(estimatedTimestamps, actualTimestamps)\n\n if (combined.length === 0) {\n return <span className=\"text-muted-foreground\">-</span>\n }\n\n const latest = getLatestEntry(combined)\n if (!latest) {\n return <span className=\"text-muted-foreground\">-</span>\n }\n\n const hasHistory = combined.length > 1\n\n // Sort by updatedAt descending (newest first)\n const sortedHistory = [...combined].sort((a, b) => b.updatedAt.localeCompare(a.updatedAt))\n\n // Badge for estimated vs actual\n const typeBadgeClass = latest.isActual\n ? 'bg-green-100 text-green-700'\n : 'bg-gray-100 text-gray-600'\n const typeBadgeLabel = latest.isActual\n ? t('shipment_tracking.timestamps.actual', 'Actual')\n : t('shipment_tracking.timestamps.estimated', 'Est.')\n\n return (\n <TooltipProvider>\n <Tooltip delayDuration={200}>\n <TooltipTrigger asChild>\n <span className={`inline-flex items-center gap-1.5 cursor-help ${hasHistory ? 'border-b border-dashed border-muted-foreground/50' : ''}`}>\n <span><FormattedTimestamp value={latest.value} offset={latest.offset} format={format} /></span>\n <span className={`inline-flex items-center rounded px-1 py-0.5 text-[10px] font-medium ${typeBadgeClass}`}>\n {typeBadgeLabel}\n </span>\n {hasHistory && (\n <span className=\"text-[10px] text-muted-foreground\">\n ({combined.length})\n </span>\n )}\n </span>\n </TooltipTrigger>\n <TooltipContent side=\"bottom\" align=\"start\" className=\"max-w-sm p-0\">\n <div className=\"p-2 space-y-2\">\n <div className=\"text-xs font-medium text-muted-foreground border-b pb-1 mb-2\">\n {t(`shipment_tracking.timestamps.${label.replace('/', '_').toLowerCase()}History`, `${label} History`)}\n </div>\n <div className=\"space-y-1.5 max-h-64 overflow-y-auto\">\n {sortedHistory.map((entry, index) => {\n const isLatest = entry === latest\n const entryTypeBadgeClass = entry.isActual\n ? 'bg-green-100 text-green-700'\n : 'bg-slate-200 text-slate-700'\n const entryTypeBadgeLabel = entry.isActual\n ? t('shipment_tracking.timestamps.actual', 'Actual')\n : t('shipment_tracking.timestamps.estimated', 'Est.')\n\n return (\n <div\n key={`${entry.value}-${entry.updatedAt}-${index}`}\n className={`text-xs rounded p-1.5 ${isLatest ? 'bg-accent' : 'bg-muted'}`}\n >\n <div className=\"flex items-center justify-between gap-2\">\n <span className=\"font-medium text-foreground\">\n {formatTimestamp(entry.value, entry.offset, 'datetime')}\n </span>\n <div className=\"flex items-center gap-1\">\n <span className={`inline-flex items-center rounded px-1 py-0.5 text-[10px] font-medium ${entryTypeBadgeClass}`}>\n {entryTypeBadgeLabel}\n </span>\n <span className={`inline-flex items-center rounded px-1 py-0.5 text-[10px] font-medium ${SOURCE_COLORS[entry.source] || 'bg-gray-100 text-gray-700'}`}>\n {SOURCE_LABELS[entry.source] || entry.source}\n </span>\n </div>\n </div>\n <div className=\"text-[10px] text-muted-foreground mt-0.5\">\n {t('shipment_tracking.timestamps.updatedAt', 'Updated')}: {formatUpdatedAt(entry.updatedAt)}\n {isLatest && (\n <span className=\"ml-1 text-primary font-medium\">\n ({t('shipment_tracking.timestamps.latest', 'latest')})\n </span>\n )}\n </div>\n </div>\n )\n })}\n </div>\n </div>\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )\n}\n\nexport default CombinedTimestampCell\n"],
|
|
5
|
+
"mappings": ";AA0DI,mBACO,KADP;AAvDJ;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,YAAY;AAqBrB,MAAM,gBAAwC;AAAA,EAC5C,aAAa;AAAA,EACb,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,MAAM;AAAA,EACN,KAAK;AACP;AAEA,MAAM,gBAAwC;AAAA,EAC5C,aAAa;AAAA,EACb,QAAQ;AAAA,EACR,KAAK;AAAA,EACL,MAAM;AAAA,EACN,KAAK;AACP;AAEA,SAAS,WAAW,MAAoB;AACtC,QAAM,MAAM,OAAO,KAAK,QAAQ,CAAC,EAAE,SAAS,GAAG,GAAG;AAClD,QAAM,QAAQ,OAAO,KAAK,SAAS,IAAI,CAAC,EAAE,SAAS,GAAG,GAAG;AACzD,QAAM,OAAO,KAAK,YAAY;AAC9B,SAAO,GAAG,GAAG,IAAI,KAAK,IAAI,IAAI;AAChC;AAEA,SAAS,cAAc,EAAE,KAAK,GAAmB;AAC/C,QAAM,MAAM,OAAO,KAAK,QAAQ,CAAC,EAAE,SAAS,GAAG,GAAG;AAClD,QAAM,QAAQ,OAAO,KAAK,SAAS,IAAI,CAAC,EAAE,SAAS,GAAG,GAAG;AACzD,QAAM,OAAO,KAAK,YAAY;AAC9B,SACE,iCACG;AAAA;AAAA,IAAI,oBAAC,UAAK,WAAU,cAAa,eAAC;AAAA,IAAQ;AAAA,IAAM,oBAAC,UAAK,WAAU,cAAa,eAAC;AAAA,IAAQ;AAAA,KACzF;AAEJ;AAEA,SAAS,gBAAgB,OAAe,QAAuB,QAAqC;AAClG,QAAM,OAAO,IAAI,KAAK,KAAK;AAC3B,MAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,EAAG,QAAO;AAEzC,MAAI,WAAW,QAAQ;AACrB,WAAO,WAAW,IAAI;AAAA,EACxB;AAGA,QAAM,UAAU,KAAK,mBAAmB,QAAW,EAAE,MAAM,WAAW,QAAQ,UAAU,CAAC;AACzF,QAAM,UAAU,WAAW,IAAI;AAC/B,QAAM,YAAY,SAAS,KAAK,MAAM,MAAM;AAC5C,SAAO,GAAG,OAAO,IAAI,OAAO,GAAG,SAAS;AAC1C;AAEA,SAAS,mBAAmB,EAAE,OAAO,QAAQ,OAAO,GAA0E;AAC5H,QAAM,OAAO,IAAI,KAAK,KAAK;AAC3B,MAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,EAAG,QAAO,gCAAE,eAAC;AAE5C,MAAI,WAAW,QAAQ;AACrB,WAAO,oBAAC,iBAAc,MAAY;AAAA,EACpC;AAEA,QAAM,UAAU,KAAK,mBAAmB,QAAW,EAAE,MAAM,WAAW,QAAQ,UAAU,CAAC;AACzF,QAAM,YAAY,SAAS,KAAK,MAAM,MAAM;AAC5C,SACE,iCACE;AAAA,wBAAC,iBAAc,MAAY;AAAA,IAAE;AAAA,IAAE;AAAA,IAAS;AAAA,KAC1C;AAEJ;AAEA,SAAS,gBAAgB,OAAuB;AAC9C,QAAM,OAAO,IAAI,KAAK,KAAK;AAC3B,MAAI,OAAO,MAAM,KAAK,QAAQ,CAAC,EAAG,QAAO;AACzC,SAAO,KAAK,eAAe,QAAW;AAAA,IACpC,OAAO;AAAA,IACP,KAAK;AAAA,IACL,MAAM;AAAA,IACN,QAAQ;AAAA,EACV,CAAC;AACH;AAEA,SAAS,kBACP,qBACA,kBACiB;AACjB,QAAM,WAA4B,CAAC;AAEnC,MAAI,qBAAqB;AACvB,eAAW,SAAS,qBAAqB;AACvC,eAAS,KAAK,EAAE,GAAG,OAAO,UAAU,MAAM,CAAC;AAAA,IAC7C;AAAA,EACF;AAEA,MAAI,kBAAkB;AACpB,eAAW,SAAS,kBAAkB;AACpC,eAAS,KAAK,EAAE,GAAG,OAAO,UAAU,KAAK,CAAC;AAAA,IAC5C;AAAA,EACF;AAEA,SAAO;AACT;AAEA,SAAS,eAAe,SAAgD;AACtE,MAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,SAAO,QAAQ;AAAA,IAAO,CAAC,QAAQ,UAC7B,MAAM,YAAY,OAAO,YAAY,QAAQ;AAAA,EAC/C;AACF;AAEO,SAAS,sBAAsB;AAAA,EACpC;AAAA,EACA;AAAA,EACA;AAAA,EACA,SAAS;AACX,GAA+B;AAC7B,QAAM,IAAI,KAAK;AAEf,QAAM,WAAW,kBAAkB,qBAAqB,gBAAgB;AAExE,MAAI,SAAS,WAAW,GAAG;AACzB,WAAO,oBAAC,UAAK,WAAU,yBAAwB,eAAC;AAAA,EAClD;AAEA,QAAM,SAAS,eAAe,QAAQ;AACtC,MAAI,CAAC,QAAQ;AACX,WAAO,oBAAC,UAAK,WAAU,yBAAwB,eAAC;AAAA,EAClD;AAEA,QAAM,aAAa,SAAS,SAAS;AAGrC,QAAM,gBAAgB,CAAC,GAAG,QAAQ,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,UAAU,cAAc,EAAE,SAAS,CAAC;AAGzF,QAAM,iBAAiB,OAAO,WAC1B,gCACA;AACJ,QAAM,iBAAiB,OAAO,WAC1B,EAAE,uCAAuC,QAAQ,IACjD,EAAE,0CAA0C,MAAM;AAEtD,SACE,oBAAC,mBACC,+BAAC,WAAQ,eAAe,KACtB;AAAA,wBAAC,kBAAe,SAAO,MACrB,+BAAC,UAAK,WAAW,gDAAgD,aAAa,sDAAsD,EAAE,IACpI;AAAA,0BAAC,UAAK,8BAAC,sBAAmB,OAAO,OAAO,OAAO,QAAQ,OAAO,QAAQ,QAAgB,GAAE;AAAA,MACxF,oBAAC,UAAK,WAAW,wEAAwE,cAAc,IACpG,0BACH;AAAA,MACC,cACC,qBAAC,UAAK,WAAU,qCAAoC;AAAA;AAAA,QAChD,SAAS;AAAA,QAAO;AAAA,SACpB;AAAA,OAEJ,GACF;AAAA,IACA,oBAAC,kBAAe,MAAK,UAAS,OAAM,SAAQ,WAAU,gBACpD,+BAAC,SAAI,WAAU,iBACb;AAAA,0BAAC,SAAI,WAAU,gEACZ,YAAE,gCAAgC,MAAM,QAAQ,KAAK,GAAG,EAAE,YAAY,CAAC,WAAW,GAAG,KAAK,UAAU,GACvG;AAAA,MACA,oBAAC,SAAI,WAAU,wCACZ,wBAAc,IAAI,CAAC,OAAO,UAAU;AACnC,cAAM,WAAW,UAAU;AAC3B,cAAM,sBAAsB,MAAM,WAC9B,gCACA;AACJ,cAAM,sBAAsB,MAAM,WAC9B,EAAE,uCAAuC,QAAQ,IACjD,EAAE,0CAA0C,MAAM;AAEtD,eACE;AAAA,UAAC;AAAA;AAAA,YAEC,WAAW,yBAAyB,WAAW,cAAc,UAAU;AAAA,YAEvE;AAAA,mCAAC,SAAI,WAAU,2CACb;AAAA,oCAAC,UAAK,WAAU,+BACb,0BAAgB,MAAM,OAAO,MAAM,QAAQ,UAAU,GACxD;AAAA,gBACA,qBAAC,SAAI,WAAU,2BACb;AAAA,sCAAC,UAAK,WAAW,wEAAwE,mBAAmB,IACzG,+BACH;AAAA,kBACA,oBAAC,UAAK,WAAW,wEAAwE,cAAc,MAAM,MAAM,KAAK,2BAA2B,IAChJ,wBAAc,MAAM,MAAM,KAAK,MAAM,QACxC;AAAA,mBACF;AAAA,iBACF;AAAA,cACA,qBAAC,SAAI,WAAU,4CACZ;AAAA,kBAAE,0CAA0C,SAAS;AAAA,gBAAE;AAAA,gBAAG,gBAAgB,MAAM,SAAS;AAAA,gBACzF,YACC,qBAAC,UAAK,WAAU,iCAAgC;AAAA;AAAA,kBAC5C,EAAE,uCAAuC,QAAQ;AAAA,kBAAE;AAAA,mBACvD;AAAA,iBAEJ;AAAA;AAAA;AAAA,UAvBK,GAAG,MAAM,KAAK,IAAI,MAAM,SAAS,IAAI,KAAK;AAAA,QAwBjD;AAAA,MAEJ,CAAC,GACH;AAAA,OACF,GACF;AAAA,KACF,GACF;AAEJ;AAEA,IAAO,gCAAQ;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useState, useCallback } from "react";
|
|
4
|
+
import { MapPin, Building2, Navigation, ChevronDown, ChevronUp } from "lucide-react";
|
|
5
|
+
import { Input } from "@freighttech/ui/primitives/input";
|
|
6
|
+
import { Label } from "@freighttech/ui/primitives/label";
|
|
7
|
+
import { Button } from "@freighttech/ui/primitives/button";
|
|
8
|
+
import { useT } from "@open-mercato/shared/lib/i18n/context";
|
|
9
|
+
function FacilityLocationInput({
|
|
10
|
+
value,
|
|
11
|
+
onChange,
|
|
12
|
+
label,
|
|
13
|
+
disabled = false,
|
|
14
|
+
showAdvanced = false
|
|
15
|
+
}) {
|
|
16
|
+
const t = useT();
|
|
17
|
+
const [advancedOpen, setAdvancedOpen] = useState(showAdvanced);
|
|
18
|
+
const updateField = useCallback(
|
|
19
|
+
(field, fieldValue) => {
|
|
20
|
+
onChange({
|
|
21
|
+
...value,
|
|
22
|
+
[field]: fieldValue,
|
|
23
|
+
source: "manual"
|
|
24
|
+
});
|
|
25
|
+
},
|
|
26
|
+
[value, onChange]
|
|
27
|
+
);
|
|
28
|
+
const updateCoord = useCallback(
|
|
29
|
+
(coord, numValue) => {
|
|
30
|
+
const currentCoords = value?.coords;
|
|
31
|
+
const otherCoord = coord === "latitude" ? currentCoords?.longitude : currentCoords?.latitude;
|
|
32
|
+
if (numValue === null && (otherCoord === null || otherCoord === void 0)) {
|
|
33
|
+
onChange({
|
|
34
|
+
...value,
|
|
35
|
+
coords: null,
|
|
36
|
+
source: "manual"
|
|
37
|
+
});
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
onChange({
|
|
41
|
+
...value,
|
|
42
|
+
coords: {
|
|
43
|
+
latitude: coord === "latitude" ? numValue ?? 0 : currentCoords?.latitude ?? 0,
|
|
44
|
+
longitude: coord === "longitude" ? numValue ?? 0 : currentCoords?.longitude ?? 0
|
|
45
|
+
},
|
|
46
|
+
source: "manual"
|
|
47
|
+
});
|
|
48
|
+
},
|
|
49
|
+
[value, onChange]
|
|
50
|
+
);
|
|
51
|
+
return /* @__PURE__ */ jsxs("div", { className: "space-y-4", children: [
|
|
52
|
+
label && /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2 text-sm font-medium text-foreground", children: [
|
|
53
|
+
/* @__PURE__ */ jsx(MapPin, { className: "h-4 w-4" }),
|
|
54
|
+
label
|
|
55
|
+
] }),
|
|
56
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
|
|
57
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
58
|
+
/* @__PURE__ */ jsx(Label, { children: t("shipment_tracking.location.name", "Port/Terminal Name") }),
|
|
59
|
+
/* @__PURE__ */ jsx(
|
|
60
|
+
Input,
|
|
61
|
+
{
|
|
62
|
+
placeholder: "Shanghai Port",
|
|
63
|
+
value: value?.name || "",
|
|
64
|
+
onChange: (e) => updateField("name", e.target.value || ""),
|
|
65
|
+
disabled
|
|
66
|
+
}
|
|
67
|
+
)
|
|
68
|
+
] }),
|
|
69
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
70
|
+
/* @__PURE__ */ jsx(Label, { children: t("shipment_tracking.location.unlocode", "UN/LOCODE") }),
|
|
71
|
+
/* @__PURE__ */ jsx(
|
|
72
|
+
Input,
|
|
73
|
+
{
|
|
74
|
+
placeholder: "CNSHA",
|
|
75
|
+
value: value?.unlocode || "",
|
|
76
|
+
onChange: (e) => updateField("unlocode", e.target.value.toUpperCase() || null),
|
|
77
|
+
disabled,
|
|
78
|
+
maxLength: 5
|
|
79
|
+
}
|
|
80
|
+
)
|
|
81
|
+
] })
|
|
82
|
+
] }),
|
|
83
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
84
|
+
/* @__PURE__ */ jsx(Label, { children: t("shipment_tracking.location.country", "Country Code") }),
|
|
85
|
+
/* @__PURE__ */ jsx(
|
|
86
|
+
Input,
|
|
87
|
+
{
|
|
88
|
+
placeholder: "CN",
|
|
89
|
+
value: value?.countryCode || "",
|
|
90
|
+
onChange: (e) => updateField("countryCode", e.target.value.toUpperCase() || null),
|
|
91
|
+
disabled,
|
|
92
|
+
maxLength: 2
|
|
93
|
+
}
|
|
94
|
+
)
|
|
95
|
+
] }),
|
|
96
|
+
/* @__PURE__ */ jsxs(
|
|
97
|
+
Button,
|
|
98
|
+
{
|
|
99
|
+
type: "button",
|
|
100
|
+
variant: "ghost",
|
|
101
|
+
size: "sm",
|
|
102
|
+
className: "w-full justify-between",
|
|
103
|
+
onClick: () => setAdvancedOpen(!advancedOpen),
|
|
104
|
+
children: [
|
|
105
|
+
/* @__PURE__ */ jsxs("span", { className: "flex items-center gap-2", children: [
|
|
106
|
+
/* @__PURE__ */ jsx(Building2, { className: "h-4 w-4" }),
|
|
107
|
+
t("shipment_tracking.location.advancedDetails", "Facility & Coordinates")
|
|
108
|
+
] }),
|
|
109
|
+
advancedOpen ? /* @__PURE__ */ jsx(ChevronUp, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx(ChevronDown, { className: "h-4 w-4" })
|
|
110
|
+
]
|
|
111
|
+
}
|
|
112
|
+
),
|
|
113
|
+
advancedOpen && /* @__PURE__ */ jsxs("div", { className: "space-y-4 pt-2", children: [
|
|
114
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
|
|
115
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
116
|
+
/* @__PURE__ */ jsx(Label, { children: t("shipment_tracking.location.facilityCode", "Facility Code") }),
|
|
117
|
+
/* @__PURE__ */ jsx(
|
|
118
|
+
Input,
|
|
119
|
+
{
|
|
120
|
+
placeholder: "DCT",
|
|
121
|
+
value: value?.facilityCode || "",
|
|
122
|
+
onChange: (e) => updateField("facilityCode", e.target.value.toUpperCase() || null),
|
|
123
|
+
disabled
|
|
124
|
+
}
|
|
125
|
+
)
|
|
126
|
+
] }),
|
|
127
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
128
|
+
/* @__PURE__ */ jsx(Label, { children: t("shipment_tracking.location.facilityProvider", "Provider") }),
|
|
129
|
+
/* @__PURE__ */ jsxs(
|
|
130
|
+
"select",
|
|
131
|
+
{
|
|
132
|
+
className: "flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",
|
|
133
|
+
value: value?.facilityCodeListProvider || "",
|
|
134
|
+
onChange: (e) => updateField(
|
|
135
|
+
"facilityCodeListProvider",
|
|
136
|
+
e.target.value || null
|
|
137
|
+
),
|
|
138
|
+
disabled,
|
|
139
|
+
children: [
|
|
140
|
+
/* @__PURE__ */ jsx("option", { value: "", children: "-" }),
|
|
141
|
+
/* @__PURE__ */ jsx("option", { value: "SMDG", children: "SMDG" }),
|
|
142
|
+
/* @__PURE__ */ jsx("option", { value: "BIC", children: "BIC" })
|
|
143
|
+
]
|
|
144
|
+
}
|
|
145
|
+
)
|
|
146
|
+
] })
|
|
147
|
+
] }),
|
|
148
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
149
|
+
/* @__PURE__ */ jsx(Label, { children: t("shipment_tracking.location.address", "Address") }),
|
|
150
|
+
/* @__PURE__ */ jsx(
|
|
151
|
+
Input,
|
|
152
|
+
{
|
|
153
|
+
placeholder: "Terminal Road 123, Shanghai, China",
|
|
154
|
+
value: value?.address || "",
|
|
155
|
+
onChange: (e) => updateField("address", e.target.value || null),
|
|
156
|
+
disabled
|
|
157
|
+
}
|
|
158
|
+
)
|
|
159
|
+
] }),
|
|
160
|
+
/* @__PURE__ */ jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
|
|
161
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
162
|
+
/* @__PURE__ */ jsxs(Label, { className: "flex items-center gap-1", children: [
|
|
163
|
+
/* @__PURE__ */ jsx(Navigation, { className: "h-3 w-3" }),
|
|
164
|
+
t("shipment_tracking.location.latitude", "Latitude")
|
|
165
|
+
] }),
|
|
166
|
+
/* @__PURE__ */ jsx(
|
|
167
|
+
Input,
|
|
168
|
+
{
|
|
169
|
+
type: "number",
|
|
170
|
+
step: "0.000001",
|
|
171
|
+
placeholder: "31.2304",
|
|
172
|
+
value: value?.coords?.latitude ?? "",
|
|
173
|
+
onChange: (e) => updateCoord("latitude", e.target.value ? parseFloat(e.target.value) : null),
|
|
174
|
+
disabled
|
|
175
|
+
}
|
|
176
|
+
)
|
|
177
|
+
] }),
|
|
178
|
+
/* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
|
|
179
|
+
/* @__PURE__ */ jsxs(Label, { className: "flex items-center gap-1", children: [
|
|
180
|
+
/* @__PURE__ */ jsx(Navigation, { className: "h-3 w-3" }),
|
|
181
|
+
t("shipment_tracking.location.longitude", "Longitude")
|
|
182
|
+
] }),
|
|
183
|
+
/* @__PURE__ */ jsx(
|
|
184
|
+
Input,
|
|
185
|
+
{
|
|
186
|
+
type: "number",
|
|
187
|
+
step: "0.000001",
|
|
188
|
+
placeholder: "121.4737",
|
|
189
|
+
value: value?.coords?.longitude ?? "",
|
|
190
|
+
onChange: (e) => updateCoord("longitude", e.target.value ? parseFloat(e.target.value) : null),
|
|
191
|
+
disabled
|
|
192
|
+
}
|
|
193
|
+
)
|
|
194
|
+
] })
|
|
195
|
+
] })
|
|
196
|
+
] })
|
|
197
|
+
] });
|
|
198
|
+
}
|
|
199
|
+
export {
|
|
200
|
+
FacilityLocationInput
|
|
201
|
+
};
|
|
202
|
+
//# sourceMappingURL=FacilityLocationInput.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/modules/shipment_tracking/components/FacilityLocationInput.tsx"],
|
|
4
|
+
"sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { useState, useCallback } from 'react'\nimport { MapPin, Building2, Navigation, ChevronDown, ChevronUp } from 'lucide-react'\nimport { Input } from '@freighttech/ui/primitives/input'\nimport { Label } from '@freighttech/ui/primitives/label'\nimport { Button } from '@freighttech/ui/primitives/button'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport type { FacilityLocation } from '../lib/location-types'\n\n/**\n * Partial FacilityLocation for form input - all fields optional\n */\nexport type FacilityLocationInputValue = Partial<FacilityLocation>\n\ninterface FacilityLocationInputProps {\n value: FacilityLocationInputValue | null\n onChange: (value: FacilityLocationInputValue | null) => void\n label?: string\n disabled?: boolean\n /** Show facility code and coordinates by default (not collapsed) */\n showAdvanced?: boolean\n}\n\n/**\n * A form component for editing FacilityLocation data.\n * \n * Primary fields (always visible):\n * - Port/Terminal Name\n * - UN/LOCODE\n * - Country Code\n * \n * Advanced fields (collapsible):\n * - Facility Code + Provider (SMDG/BIC)\n * - Address\n * - Coordinates (lat/lng)\n */\nexport function FacilityLocationInput({\n value,\n onChange,\n label,\n disabled = false,\n showAdvanced = false,\n}: FacilityLocationInputProps) {\n const t = useT()\n const [advancedOpen, setAdvancedOpen] = useState(showAdvanced)\n\n const updateField = useCallback(\n <K extends keyof FacilityLocation>(field: K, fieldValue: FacilityLocation[K]) => {\n onChange({\n ...value,\n [field]: fieldValue,\n source: 'manual',\n })\n },\n [value, onChange]\n )\n\n const updateCoord = useCallback(\n (coord: 'latitude' | 'longitude', numValue: number | null) => {\n const currentCoords = value?.coords\n const otherCoord = coord === 'latitude' ? currentCoords?.longitude : currentCoords?.latitude\n\n // If both are null/undefined, set coords to null\n if (numValue === null && (otherCoord === null || otherCoord === undefined)) {\n onChange({\n ...value,\n coords: null,\n source: 'manual',\n })\n return\n }\n\n onChange({\n ...value,\n coords: {\n latitude: coord === 'latitude' ? (numValue ?? 0) : (currentCoords?.latitude ?? 0),\n longitude: coord === 'longitude' ? (numValue ?? 0) : (currentCoords?.longitude ?? 0),\n },\n source: 'manual',\n })\n },\n [value, onChange]\n )\n\n return (\n <div className=\"space-y-4\">\n {label && (\n <div className=\"flex items-center gap-2 text-sm font-medium text-foreground\">\n <MapPin className=\"h-4 w-4\" />\n {label}\n </div>\n )}\n\n {/* Primary fields: Name, UN/LOCODE, Country */}\n <div className=\"grid grid-cols-2 gap-4\">\n <div className=\"space-y-2\">\n <Label>{t('shipment_tracking.location.name', 'Port/Terminal Name')}</Label>\n <Input\n placeholder=\"Shanghai Port\"\n value={value?.name || ''}\n onChange={(e) => updateField('name', e.target.value || '')}\n disabled={disabled}\n />\n </div>\n <div className=\"space-y-2\">\n <Label>{t('shipment_tracking.location.unlocode', 'UN/LOCODE')}</Label>\n <Input\n placeholder=\"CNSHA\"\n value={value?.unlocode || ''}\n onChange={(e) => updateField('unlocode', e.target.value.toUpperCase() || null)}\n disabled={disabled}\n maxLength={5}\n />\n </div>\n </div>\n\n <div className=\"space-y-2\">\n <Label>{t('shipment_tracking.location.country', 'Country Code')}</Label>\n <Input\n placeholder=\"CN\"\n value={value?.countryCode || ''}\n onChange={(e) => updateField('countryCode', e.target.value.toUpperCase() || null)}\n disabled={disabled}\n maxLength={2}\n />\n </div>\n\n {/* Advanced fields toggle */}\n <Button\n type=\"button\"\n variant=\"ghost\"\n size=\"sm\"\n className=\"w-full justify-between\"\n onClick={() => setAdvancedOpen(!advancedOpen)}\n >\n <span className=\"flex items-center gap-2\">\n <Building2 className=\"h-4 w-4\" />\n {t('shipment_tracking.location.advancedDetails', 'Facility & Coordinates')}\n </span>\n {advancedOpen ? (\n <ChevronUp className=\"h-4 w-4\" />\n ) : (\n <ChevronDown className=\"h-4 w-4\" />\n )}\n </Button>\n\n {/* Advanced fields: Facility, Address, Coordinates */}\n {advancedOpen && (\n <div className=\"space-y-4 pt-2\">\n {/* Facility Code */}\n <div className=\"grid grid-cols-2 gap-4\">\n <div className=\"space-y-2\">\n <Label>{t('shipment_tracking.location.facilityCode', 'Facility Code')}</Label>\n <Input\n placeholder=\"DCT\"\n value={value?.facilityCode || ''}\n onChange={(e) =>\n updateField('facilityCode', e.target.value.toUpperCase() || null)\n }\n disabled={disabled}\n />\n </div>\n <div className=\"space-y-2\">\n <Label>{t('shipment_tracking.location.facilityProvider', 'Provider')}</Label>\n <select\n className=\"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50\"\n value={value?.facilityCodeListProvider || ''}\n onChange={(e) =>\n updateField(\n 'facilityCodeListProvider',\n (e.target.value as 'SMDG' | 'BIC') || null\n )\n }\n disabled={disabled}\n >\n <option value=\"\">-</option>\n <option value=\"SMDG\">SMDG</option>\n <option value=\"BIC\">BIC</option>\n </select>\n </div>\n </div>\n\n {/* Address */}\n <div className=\"space-y-2\">\n <Label>{t('shipment_tracking.location.address', 'Address')}</Label>\n <Input\n placeholder=\"Terminal Road 123, Shanghai, China\"\n value={value?.address || ''}\n onChange={(e) => updateField('address', e.target.value || null)}\n disabled={disabled}\n />\n </div>\n\n {/* Coordinates */}\n <div className=\"grid grid-cols-2 gap-4\">\n <div className=\"space-y-2\">\n <Label className=\"flex items-center gap-1\">\n <Navigation className=\"h-3 w-3\" />\n {t('shipment_tracking.location.latitude', 'Latitude')}\n </Label>\n <Input\n type=\"number\"\n step=\"0.000001\"\n placeholder=\"31.2304\"\n value={value?.coords?.latitude ?? ''}\n onChange={(e) =>\n updateCoord('latitude', e.target.value ? parseFloat(e.target.value) : null)\n }\n disabled={disabled}\n />\n </div>\n <div className=\"space-y-2\">\n <Label className=\"flex items-center gap-1\">\n <Navigation className=\"h-3 w-3\" />\n {t('shipment_tracking.location.longitude', 'Longitude')}\n </Label>\n <Input\n type=\"number\"\n step=\"0.000001\"\n placeholder=\"121.4737\"\n value={value?.coords?.longitude ?? ''}\n onChange={(e) =>\n updateCoord('longitude', e.target.value ? parseFloat(e.target.value) : null)\n }\n disabled={disabled}\n />\n </div>\n </div>\n </div>\n )}\n </div>\n )\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|