refactor(admin): move approve/reject/delete dialogs onto shared Modal
This commit is contained in:
@@ -4,6 +4,7 @@ import { useState, useEffect, useCallback } from "react";
|
|||||||
import { useTranslations, useFormatter } from "next-intl";
|
import { useTranslations, useFormatter } from "next-intl";
|
||||||
import type { PiecedTenant, TenantRequest } from "@/types";
|
import type { PiecedTenant, TenantRequest } from "@/types";
|
||||||
import { StatusBadge } from "@/components/ui/status-badge";
|
import { StatusBadge } from "@/components/ui/status-badge";
|
||||||
|
import { Modal } from "@/components/ui/modal";
|
||||||
import { formatDateTime, formatRelative } from "@/lib/format";
|
import { formatDateTime, formatRelative } from "@/lib/format";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
|
|
||||||
@@ -794,13 +795,20 @@ export function AdminPanel({ initialTenants }: AdminPanelProps) {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{/* ───── APPROVE MODAL ───── */}
|
{/* ───── APPROVE MODAL ───── */}
|
||||||
{approveModal &&
|
<Modal
|
||||||
(() => {
|
open={!!approveModal}
|
||||||
const req = requests.find((r) => r.id === approveModal);
|
onClose={() => {
|
||||||
const isReapprove = req?.status === "rejected";
|
setApproveModal(null);
|
||||||
return (
|
setActionError("");
|
||||||
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm">
|
}}
|
||||||
<div className="bg-surface-1 border border-border rounded-xl p-6 max-w-md w-full mx-4 shadow-2xl">
|
ariaLabel={t("approveTitle")}
|
||||||
|
>
|
||||||
|
{approveModal &&
|
||||||
|
(() => {
|
||||||
|
const req = requests.find((r) => r.id === approveModal);
|
||||||
|
const isReapprove = req?.status === "rejected";
|
||||||
|
return (
|
||||||
|
<>
|
||||||
<h3 className="font-display text-lg font-semibold text-text-primary mb-2">
|
<h3 className="font-display text-lg font-semibold text-text-primary mb-2">
|
||||||
{t("approveTitle")}
|
{t("approveTitle")}
|
||||||
</h3>
|
</h3>
|
||||||
@@ -838,15 +846,23 @@ export function AdminPanel({ initialTenants }: AdminPanelProps) {
|
|||||||
{actionLoading === approveModal ? "…" : t("confirmApprove")}
|
{actionLoading === approveModal ? "…" : t("confirmApprove")}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</>
|
||||||
</div>
|
);
|
||||||
);
|
})()}
|
||||||
})()}
|
</Modal>
|
||||||
|
|
||||||
{/* ───── REJECT MODAL ───── */}
|
{/* ───── REJECT MODAL ───── */}
|
||||||
{rejectModal && (
|
<Modal
|
||||||
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm">
|
open={!!rejectModal}
|
||||||
<div className="bg-surface-1 border border-border rounded-xl p-6 max-w-md w-full mx-4 shadow-2xl">
|
onClose={() => {
|
||||||
|
setRejectModal(null);
|
||||||
|
setRejectNotes("");
|
||||||
|
setActionError("");
|
||||||
|
}}
|
||||||
|
ariaLabel={t("rejectTitle")}
|
||||||
|
>
|
||||||
|
{rejectModal && (
|
||||||
|
<>
|
||||||
<h3 className="font-display text-lg font-semibold text-text-primary mb-4">
|
<h3 className="font-display text-lg font-semibold text-text-primary mb-4">
|
||||||
{t("rejectTitle")}
|
{t("rejectTitle")}
|
||||||
</h3>
|
</h3>
|
||||||
@@ -870,6 +886,7 @@ export function AdminPanel({ initialTenants }: AdminPanelProps) {
|
|||||||
onClick={() => {
|
onClick={() => {
|
||||||
setRejectModal(null);
|
setRejectModal(null);
|
||||||
setRejectNotes("");
|
setRejectNotes("");
|
||||||
|
setActionError("");
|
||||||
}}
|
}}
|
||||||
className="px-4 py-2 text-sm text-text-secondary hover:text-text-primary transition-colors"
|
className="px-4 py-2 text-sm text-text-secondary hover:text-text-primary transition-colors"
|
||||||
>
|
>
|
||||||
@@ -883,14 +900,21 @@ export function AdminPanel({ initialTenants }: AdminPanelProps) {
|
|||||||
{actionLoading === rejectModal ? "…" : t("confirmReject")}
|
{actionLoading === rejectModal ? "…" : t("confirmReject")}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</>
|
||||||
</div>
|
)}
|
||||||
)}
|
</Modal>
|
||||||
|
|
||||||
{/* ───── DELETE MODAL ───── */}
|
{/* ───── DELETE MODAL ───── */}
|
||||||
{deleteModal && (
|
<Modal
|
||||||
<div className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm">
|
open={!!deleteModal}
|
||||||
<div className="bg-surface-1 border border-border rounded-xl p-6 max-w-md w-full mx-4 shadow-2xl">
|
onClose={() => {
|
||||||
|
setDeleteModal(null);
|
||||||
|
setActionError("");
|
||||||
|
}}
|
||||||
|
ariaLabel={t("deleteTitle")}
|
||||||
|
>
|
||||||
|
{deleteModal && (
|
||||||
|
<>
|
||||||
<h3 className="font-display text-lg font-semibold text-text-primary mb-2">
|
<h3 className="font-display text-lg font-semibold text-text-primary mb-2">
|
||||||
{t("deleteTitle")}
|
{t("deleteTitle")}
|
||||||
</h3>
|
</h3>
|
||||||
@@ -907,7 +931,10 @@ export function AdminPanel({ initialTenants }: AdminPanelProps) {
|
|||||||
)}
|
)}
|
||||||
<div className="flex gap-2 justify-end">
|
<div className="flex gap-2 justify-end">
|
||||||
<button
|
<button
|
||||||
onClick={() => setDeleteModal(null)}
|
onClick={() => {
|
||||||
|
setDeleteModal(null);
|
||||||
|
setActionError("");
|
||||||
|
}}
|
||||||
className="px-4 py-2 text-sm text-text-secondary hover:text-text-primary transition-colors"
|
className="px-4 py-2 text-sm text-text-secondary hover:text-text-primary transition-colors"
|
||||||
>
|
>
|
||||||
{t("cancelAction")}
|
{t("cancelAction")}
|
||||||
@@ -920,9 +947,9 @@ export function AdminPanel({ initialTenants }: AdminPanelProps) {
|
|||||||
{actionLoading === deleteModal ? "…" : t("confirmDelete")}
|
{actionLoading === deleteModal ? "…" : t("confirmDelete")}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</>
|
||||||
</div>
|
)}
|
||||||
)}
|
</Modal>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user