fix: resolve permission fallback bug, remove debug code, and cleanup duplication

Logic Errors
------------
- Sidebar: fix permissions fallback so a user with no permissions gets
  zero access instead of falling back to the full nav list
  (user?.permissions ?? [] instead of ?? navSections.flatMap(...))
- carMaintanance.service / UseCarsMaintanance: add pagination to the
  maintenance records fetch instead of loading the entire list at once
- api.ts: redact sensitive fields (password, token) before logging the
  request body in console.debug, to avoid leaking credentials/PII

Code Flow Problems
-------------------
- OrderFormModal: remove leftover console.log/debug statements and the
  redundant onClick handler on the submit button
- auth: remove the unused src/service/auth.service.ts (axios) and keep
  only src/services/auth.service.ts (fetch); fix useAuth.ts import path
  from
This commit is contained in:
m7amedez5511
2026-07-19 14:57:48 +03:00
parent bbde177f4a
commit 538111d726
82 changed files with 1441 additions and 2261 deletions

View File

@@ -2,9 +2,8 @@
import { useCallback, useEffect, useRef, useState } from "react";
import { useParams, useRouter } from "next/navigation";
import { Spinner } from "@/src/Components/UI";
import { ConfirmDialog, Spinner } from "@/src/Components/UI";
import { TripFormModal } from "@/src/Components/Trip/Tripformmodal";
import { TripDeleteModal } from "@/src/Components/Trip/Tripdeletemodal";
import { TripReportPanel } from "@/src/Components/Trip_Report/Tripreportpanel";
import { tripService } from "@/src/services/trip.service";
import { getStoredToken } from "@/src/lib/auth";
@@ -206,44 +205,42 @@ export default function TripDetailPage() {
// ── Load trip ─────────────────────────────────────────────────────────────
const loadTrip = useCallback(async () => {
if (!tripId) return;
setLoading(true);
setError(null);
try {
const token = getStoredToken();
const res = await tripService.getById(tripId, token);
setTrip((res as unknown as { data: Trip }).data);
} catch (err: unknown) {
setError(err instanceof Error ? err.message : "تعذّر تحميل بيانات الرحلة.");
} finally {
setLoading(false);
}
}, [tripId]);
if (!tripId) return;
setLoading(true);
setError(null);
try {
const token = getStoredToken();
const data = await tripService.getById(tripId, token);
setTrip(data);
} catch (err: unknown) {
setError(err instanceof Error ? err.message : "تعذّر تحميل بيانات الرحلة.");
} finally {
setLoading(false);
}
}, [tripId]);
useEffect(() => {
queueMicrotask(loadTrip);
}, [loadTrip]);
// ── Edit submit ───────────────────────────────────────────────────────────
const handleEditSubmit = useCallback(
async (
payload: CreateTripPayload | UpdateTripPayload,
): Promise<boolean> => {
if (!trip) return false;
try {
const token = getStoredToken();
const res = await tripService.update(trip.id, payload as UpdateTripPayload, token);
const updated = (res as unknown as { data: Trip }).data;
setTrip(updated);
notify({ type: "success", message: "تم تحديث بيانات الرحلة بنجاح." });
return true;
} catch (err) {
notify({ type: "error", message: extractApiMessage(err, "تعذّر تحديث الرحلة.") });
return false;
}
},
[trip, notify],
);
async (
payload: CreateTripPayload | UpdateTripPayload,
): Promise<boolean> => {
if (!trip) return false;
try {
const token = getStoredToken();
const updated = await tripService.update(trip.id, payload as UpdateTripPayload, token);
setTrip(updated);
notify({ type: "success", message: "تم تحديث بيانات الرحلة بنجاح." });
return true;
} catch (err) {
notify({ type: "error", message: extractApiMessage(err, "تعذّر تحديث الرحلة.") });
return false;
}
},
[trip, notify],
);
// ── Delete confirm ────────────────────────────────────────────────────────
const handleConfirmDelete = useCallback(async () => {
@@ -558,14 +555,14 @@ export default function TripDetailPage() {
)}
{/* ── Delete modal ── */}
{deleteOpen && (
<TripDeleteModal
trip={trip}
deleting={deleting}
onCancel={() => setDeleteOpen(false)}
onConfirm={handleConfirmDelete}
/>
)}
<ConfirmDialog
open={deleteOpen}
loading={deleting}
onCancel={() => setDeleteOpen(false)}
onConfirm={handleConfirmDelete}
title="حذف الرحلة"
description={`هل أنت متأكد من حذف رحلة ${trip.title} (${trip.tripNumber})؟ لا يمكن التراجع عن هذا الإجراء.`}
/>
</>
);
}

View File

@@ -31,10 +31,8 @@ export default function ArchivedTripDetailPage() {
setError(null);
try {
const token = getStoredToken();
// Archived trips must go through the archived endpoint —
// the normal /trip/:id endpoint won't return soft-deleted trips.
const res = await tripService.getArchivedById(tripId, token);
if (!cancelled) setTrip((res as unknown as { data: Trip }).data);
const data = await tripService.getArchivedById(tripId, token);
if (!cancelled) setTrip(data);
} catch {
if (!cancelled) setError("لم يتم العثور على هذه الرحلة في الأرشيف.");
} finally {
@@ -54,7 +52,6 @@ export default function ArchivedTripDetailPage() {
);
}
// Edge case: invalid/missing/unreachable trip ID
if (error || !trip) {
return (
<EmptyState

View File

@@ -4,10 +4,8 @@ import { useCallback, useEffect, useState } from "react";
import { useRouter } from "next/navigation";
import { useTrips } from "@/src/hooks/useTrip";
import { TripFormModal } from "@/src/Components/Trip/Tripformmodal";
import { TripDeleteModal } from "@/src/Components/Trip/Tripdeletemodal";
import { ArchivedTripList } from "@/src/Components/Trip/archive/ArchivedTripList";
import { Alert, Spinner, ArchiveButton } from "@/src/Components/UI";
import { Toast } from "@/src/Components/UI/Toast";
import { Alert, Spinner, ArchiveButton, ConfirmDialog , Toast } from "@/src/Components/UI";
import type {
Trip,
TripStatus,
@@ -748,14 +746,14 @@ export default function TripsPage() {
)}
{/* ── Delete modal ── */}
{deleteTarget && (
<TripDeleteModal
trip={deleteTarget}
deleting={deleting}
onCancel={() => setDeleteTarget(null)}
onConfirm={handleConfirmDelete}
/>
)}
<ConfirmDialog
open={!!deleteTarget}
loading={deleting}
onCancel={() => setDeleteTarget(null)}
onConfirm={handleConfirmDelete}
title="حذف الرحلة"
description={`هل أنت متأكد من حذف رحلة ${deleteTarget?.title ?? ""} (${deleteTarget?.tripNumber ?? ""})؟ لا يمكن التراجع عن هذا الإجراء.`}
/>
{/* ── Archive browser modal ── */}
{archiveOpen && (
@@ -768,4 +766,4 @@ export default function TripsPage() {
<Toast notification={notification} onDismiss={dismissNotification} />
</div>
);
}
}