Add dark mode styling to modals and form elements
- Add global CSS overrides for input, select, textarea in dark mode - Update MetersModal with dark mode classes - Update ConcentratorsModal with dark mode classes - Update ProjectsPage modal with dark mode classes - Update RolesPage modal with dark mode classes - Update ConfirmModal with dark mode styling - Update ProfileModal with dark mode styling - All form labels, inputs, selects, and buttons now properly styled Dark mode elements: - Modal backgrounds: zinc-900 with zinc-700 border - Inputs/selects: zinc-800 background, zinc-700 border - Labels: zinc-400 text color - Cancel buttons: zinc-800 hover background Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -56,22 +56,22 @@ export default function ConfirmModal({
|
|||||||
<div
|
<div
|
||||||
ref={panelRef}
|
ref={panelRef}
|
||||||
tabIndex={-1}
|
tabIndex={-1}
|
||||||
className="rounded-2xl bg-white border border-slate-200 shadow-xl overflow-hidden outline-none"
|
className="rounded-2xl bg-white dark:bg-zinc-900 border border-slate-200 dark:border-zinc-700 shadow-xl overflow-hidden outline-none"
|
||||||
>
|
>
|
||||||
<div className="px-6 py-4 border-b border-slate-200">
|
<div className="px-6 py-4 border-b border-slate-200 dark:border-zinc-700">
|
||||||
<div className="text-base font-semibold text-slate-900">{title}</div>
|
<div className="text-base font-semibold text-slate-900 dark:text-white">{title}</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="px-6 py-5">
|
<div className="px-6 py-5">
|
||||||
<p className="text-sm text-slate-700">{message}</p>
|
<p className="text-sm text-slate-700 dark:text-zinc-300">{message}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="px-6 py-4 border-t border-slate-200 flex justify-end gap-3">
|
<div className="px-6 py-4 border-t border-slate-200 dark:border-zinc-700 flex justify-end gap-3">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
disabled={loading}
|
disabled={loading}
|
||||||
className="rounded-xl px-4 py-2 text-sm font-medium border border-slate-200 bg-white text-slate-700 hover:bg-slate-100 transition disabled:opacity-60"
|
className="rounded-xl px-4 py-2 text-sm font-medium border border-slate-200 dark:border-zinc-700 bg-white dark:bg-zinc-800 text-slate-700 dark:text-zinc-300 hover:bg-slate-100 dark:hover:bg-zinc-700 transition disabled:opacity-60"
|
||||||
>
|
>
|
||||||
{cancelText}
|
{cancelText}
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -150,10 +150,10 @@ export default function ProfileModal({
|
|||||||
|
|
||||||
{/* Modal */}
|
{/* Modal */}
|
||||||
<div className="relative mx-auto mt-16 w-[min(860px,calc(100vw-32px))]">
|
<div className="relative mx-auto mt-16 w-[min(860px,calc(100vw-32px))]">
|
||||||
<div className="rounded-2xl bg-white shadow-xl border border-slate-200 overflow-hidden">
|
<div className="rounded-2xl bg-white dark:bg-zinc-900 shadow-xl border border-slate-200 dark:border-zinc-700 overflow-hidden">
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
<div className="px-6 py-4 border-b border-slate-200">
|
<div className="px-6 py-4 border-b border-slate-200 dark:border-zinc-700">
|
||||||
<div className="text-base font-semibold text-slate-900">
|
<div className="text-base font-semibold text-slate-900 dark:text-white">
|
||||||
Editar perfil
|
Editar perfil
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -162,9 +162,9 @@ export default function ProfileModal({
|
|||||||
<div className="p-6">
|
<div className="p-6">
|
||||||
<div className="grid grid-cols-1 md:grid-cols-[260px_1fr] gap-6">
|
<div className="grid grid-cols-1 md:grid-cols-[260px_1fr] gap-6">
|
||||||
{/* LEFT: Avatar */}
|
{/* LEFT: Avatar */}
|
||||||
<div className="rounded-2xl border border-slate-200 bg-slate-50 p-5">
|
<div className="rounded-2xl border border-slate-200 dark:border-zinc-700 bg-slate-50 dark:bg-zinc-800 p-5">
|
||||||
<div className="flex flex-col items-center text-center">
|
<div className="flex flex-col items-center text-center">
|
||||||
<div className="w-28 h-28 rounded-2xl bg-white border border-slate-200 overflow-hidden flex items-center justify-center">
|
<div className="w-28 h-28 rounded-2xl bg-white dark:bg-zinc-700 border border-slate-200 dark:border-zinc-600 overflow-hidden flex items-center justify-center">
|
||||||
{computedAvatarSrc ? (
|
{computedAvatarSrc ? (
|
||||||
<img
|
<img
|
||||||
src={computedAvatarSrc}
|
src={computedAvatarSrc}
|
||||||
@@ -172,17 +172,17 @@ export default function ProfileModal({
|
|||||||
className="w-full h-full object-cover"
|
className="w-full h-full object-cover"
|
||||||
/>
|
/>
|
||||||
) : (
|
) : (
|
||||||
<div className="w-full h-full flex items-center justify-center text-slate-700 font-semibold text-2xl">
|
<div className="w-full h-full flex items-center justify-center text-slate-700 dark:text-zinc-200 font-semibold text-2xl">
|
||||||
{initials}
|
{initials}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mt-4">
|
<div className="mt-4">
|
||||||
<div className="text-sm font-semibold text-slate-900 truncate max-w-[220px]">
|
<div className="text-sm font-semibold text-slate-900 dark:text-white truncate max-w-[220px]">
|
||||||
{name || "Usuario"}
|
{name || "Usuario"}
|
||||||
</div>
|
</div>
|
||||||
<div className="text-xs text-slate-500 truncate max-w-[220px]">
|
<div className="text-xs text-slate-500 dark:text-zinc-400 truncate max-w-[220px]">
|
||||||
{email || "correo@ejemplo.gob.mx"}
|
{email || "correo@ejemplo.gob.mx"}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -193,8 +193,8 @@ export default function ProfileModal({
|
|||||||
disabled={!onUploadAvatar}
|
disabled={!onUploadAvatar}
|
||||||
className={[
|
className={[
|
||||||
"mt-4 w-full rounded-xl px-4 py-2 text-sm font-medium",
|
"mt-4 w-full rounded-xl px-4 py-2 text-sm font-medium",
|
||||||
"border border-slate-200 bg-white text-slate-700",
|
"border border-slate-200 dark:border-zinc-700 bg-white dark:bg-zinc-800 text-slate-700 dark:text-zinc-300",
|
||||||
"hover:bg-slate-100 transition",
|
"hover:bg-slate-100 dark:hover:bg-zinc-700 transition",
|
||||||
!onUploadAvatar ? "opacity-50 cursor-not-allowed" : "",
|
!onUploadAvatar ? "opacity-50 cursor-not-allowed" : "",
|
||||||
].join(" ")}
|
].join(" ")}
|
||||||
>
|
>
|
||||||
@@ -212,8 +212,8 @@ export default function ProfileModal({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* RIGHT: Form */}
|
{/* RIGHT: Form */}
|
||||||
<div className="rounded-2xl border border-slate-200 p-5">
|
<div className="rounded-2xl border border-slate-200 dark:border-zinc-700 p-5">
|
||||||
<div className="text-xs font-semibold text-slate-500 uppercase tracking-wide">
|
<div className="text-xs font-semibold text-slate-500 dark:text-zinc-400 uppercase tracking-wide">
|
||||||
correo electrónico
|
correo electrónico
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -222,7 +222,7 @@ export default function ProfileModal({
|
|||||||
<input
|
<input
|
||||||
value={name}
|
value={name}
|
||||||
onChange={(e) => setName(e.target.value)}
|
onChange={(e) => setName(e.target.value)}
|
||||||
className="w-full rounded-xl border border-slate-200 bg-white px-4 py-2.5 text-sm text-slate-900 outline-none focus:ring-2 focus:ring-slate-200"
|
className="w-full rounded-xl border border-slate-200 dark:border-zinc-700 bg-white dark:bg-zinc-800 px-4 py-2.5 text-sm text-slate-900 dark:text-zinc-100 outline-none focus:ring-2 focus:ring-slate-200"
|
||||||
placeholder="Nombre del usuario"
|
placeholder="Nombre del usuario"
|
||||||
/>
|
/>
|
||||||
</Field>
|
</Field>
|
||||||
@@ -231,7 +231,7 @@ export default function ProfileModal({
|
|||||||
<input
|
<input
|
||||||
value={email}
|
value={email}
|
||||||
onChange={(e) => setEmail(e.target.value)}
|
onChange={(e) => setEmail(e.target.value)}
|
||||||
className="w-full rounded-xl border border-slate-200 bg-white px-4 py-2.5 text-sm text-slate-900 outline-none focus:ring-2 focus:ring-slate-200"
|
className="w-full rounded-xl border border-slate-200 dark:border-zinc-700 bg-white dark:bg-zinc-800 px-4 py-2.5 text-sm text-slate-900 dark:text-zinc-100 outline-none focus:ring-2 focus:ring-slate-200"
|
||||||
placeholder="correo@organismo.gob.mx"
|
placeholder="correo@organismo.gob.mx"
|
||||||
/>
|
/>
|
||||||
</Field>
|
</Field>
|
||||||
@@ -240,7 +240,7 @@ export default function ProfileModal({
|
|||||||
<input
|
<input
|
||||||
value={organismName}
|
value={organismName}
|
||||||
onChange={(e) => setOrganismName(e.target.value)}
|
onChange={(e) => setOrganismName(e.target.value)}
|
||||||
className="w-full rounded-xl border border-slate-200 bg-white px-4 py-2.5 text-sm text-slate-900 outline-none focus:ring-2 focus:ring-slate-200"
|
className="w-full rounded-xl border border-slate-200 dark:border-zinc-700 bg-white dark:bg-zinc-800 px-4 py-2.5 text-sm text-slate-900 dark:text-zinc-100 outline-none focus:ring-2 focus:ring-slate-200"
|
||||||
placeholder="Organismo operador"
|
placeholder="Organismo operador"
|
||||||
/>
|
/>
|
||||||
</Field>
|
</Field>
|
||||||
@@ -250,11 +250,11 @@ export default function ProfileModal({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Footer */}
|
{/* Footer */}
|
||||||
<div className="px-6 py-4 border-t border-slate-200 flex items-center justify-end gap-3">
|
<div className="px-6 py-4 border-t border-slate-200 dark:border-zinc-700 flex items-center justify-end gap-3">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={onClose}
|
onClick={onClose}
|
||||||
className="rounded-xl px-4 py-2 text-sm font-medium border border-slate-200 bg-white text-slate-700 hover:bg-slate-100 transition"
|
className="rounded-xl px-4 py-2 text-sm font-medium border border-slate-200 dark:border-zinc-700 bg-white dark:bg-zinc-800 text-slate-700 dark:text-zinc-300 hover:bg-slate-100 dark:hover:bg-zinc-700 transition"
|
||||||
disabled={loading}
|
disabled={loading}
|
||||||
>
|
>
|
||||||
Cancelar
|
Cancelar
|
||||||
@@ -283,7 +283,7 @@ export default function ProfileModal({
|
|||||||
function Field({ label, children }: { label: string; children: React.ReactNode }) {
|
function Field({ label, children }: { label: string; children: React.ReactNode }) {
|
||||||
return (
|
return (
|
||||||
<div className="grid grid-cols-[90px_1fr] items-center gap-3">
|
<div className="grid grid-cols-[90px_1fr] items-center gap-3">
|
||||||
<div className="text-sm font-medium text-slate-700">{label}</div>
|
<div className="text-sm font-medium text-slate-700 dark:text-zinc-300">{label}</div>
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -116,4 +116,37 @@ body:where(.dark *) {
|
|||||||
.dark [style*="background-color: #fff"],
|
.dark [style*="background-color: #fff"],
|
||||||
.dark [style*="backgroundColor: rgb(255, 255, 255)"] {
|
.dark [style*="backgroundColor: rgb(255, 255, 255)"] {
|
||||||
background-color: #18181b !important; /* zinc-900 */
|
background-color: #18181b !important; /* zinc-900 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dark mode form elements - global overrides */
|
||||||
|
.dark input:not([type="checkbox"]):not([type="radio"]),
|
||||||
|
.dark select,
|
||||||
|
.dark textarea {
|
||||||
|
background-color: #27272a !important; /* zinc-800 */
|
||||||
|
border-color: #3f3f46 !important; /* zinc-700 */
|
||||||
|
color: #fafafa !important; /* zinc-50 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark input::placeholder,
|
||||||
|
.dark textarea::placeholder {
|
||||||
|
color: #71717a !important; /* zinc-500 */
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark input:focus,
|
||||||
|
.dark select:focus,
|
||||||
|
.dark textarea:focus {
|
||||||
|
border-color: #3b82f6 !important; /* blue-500 */
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark select option {
|
||||||
|
background-color: #27272a; /* zinc-800 */
|
||||||
|
color: #fafafa; /* zinc-50 */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dark mode for modals */
|
||||||
|
.dark .modal-content,
|
||||||
|
.dark [class*="bg-white"][class*="rounded-xl"][class*="p-6"] {
|
||||||
|
background-color: #18181b !important; /* zinc-900 */
|
||||||
|
border: 1px solid #3f3f46 !important; /* zinc-700 */
|
||||||
}
|
}
|
||||||
@@ -281,18 +281,18 @@ export default function RolesPage() {
|
|||||||
{/* ADD/EDIT MODAL */}
|
{/* ADD/EDIT MODAL */}
|
||||||
{showModal && (
|
{showModal && (
|
||||||
<div className="fixed inset-0 bg-black/40 flex items-center justify-center z-50">
|
<div className="fixed inset-0 bg-black/40 flex items-center justify-center z-50">
|
||||||
<div className="bg-white rounded-xl p-6 w-96 space-y-4 shadow-xl">
|
<div className="bg-white dark:bg-zinc-900 dark:border dark:border-zinc-700 rounded-xl p-6 w-96 space-y-4 shadow-xl">
|
||||||
<h2 className="text-lg font-semibold text-gray-900">
|
<h2 className="text-lg font-semibold text-gray-900 dark:text-white">
|
||||||
{editingId ? "Edit Role" : "Add New Role"}
|
{editingId ? "Edit Role" : "Add New Role"}
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
<label className="block text-sm font-medium text-gray-700 dark:text-zinc-300 mb-1">
|
||||||
Name <span className="text-red-500">*</span>
|
Name <span className="text-red-500">*</span>
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
className="w-full border border-gray-300 px-3 py-2 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
|
className="w-full border border-gray-300 dark:border-zinc-700 dark:bg-zinc-800 dark:text-zinc-100 px-3 py-2 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500"
|
||||||
placeholder="e.g., ADMIN, USER, MANAGER"
|
placeholder="e.g., ADMIN, USER, MANAGER"
|
||||||
value={form.name}
|
value={form.name}
|
||||||
onChange={e => setForm({...form, name: e.target.value})}
|
onChange={e => setForm({...form, name: e.target.value})}
|
||||||
@@ -301,11 +301,11 @@ export default function RolesPage() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
<label className="block text-sm font-medium text-gray-700 dark:text-zinc-300 mb-1">
|
||||||
Description
|
Description
|
||||||
</label>
|
</label>
|
||||||
<textarea
|
<textarea
|
||||||
className="w-full border border-gray-300 px-3 py-2 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 resize-none"
|
className="w-full border border-gray-300 dark:border-zinc-700 dark:bg-zinc-800 dark:text-zinc-100 px-3 py-2 rounded-lg focus:outline-none focus:ring-2 focus:ring-blue-500 resize-none"
|
||||||
placeholder="Describe the role's purpose..."
|
placeholder="Describe the role's purpose..."
|
||||||
rows={3}
|
rows={3}
|
||||||
value={form.description}
|
value={form.description}
|
||||||
@@ -315,8 +315,8 @@ export default function RolesPage() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Note about permissions */}
|
{/* Note about permissions */}
|
||||||
<div className="bg-blue-50 border border-blue-200 rounded-lg p-3">
|
<div className="bg-blue-50 dark:bg-blue-900/30 border border-blue-200 dark:border-blue-800 rounded-lg p-3">
|
||||||
<p className="text-xs text-blue-800">
|
<p className="text-xs text-blue-800 dark:text-blue-300">
|
||||||
<strong>Note:</strong> Permissions can be configured after creating the role.
|
<strong>Note:</strong> Permissions can be configured after creating the role.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -331,7 +331,7 @@ export default function RolesPage() {
|
|||||||
setError(null);
|
setError(null);
|
||||||
}}
|
}}
|
||||||
disabled={loading}
|
disabled={loading}
|
||||||
className="px-4 py-2 text-gray-700 hover:bg-gray-100 rounded-lg transition disabled:opacity-50"
|
className="px-4 py-2 text-gray-700 dark:text-zinc-300 hover:bg-gray-100 dark:hover:bg-zinc-800 rounded-lg transition disabled:opacity-50"
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
@@ -43,17 +43,17 @@ export default function ConcentratorsModal({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="fixed inset-0 bg-black/40 flex items-center justify-center z-50">
|
<div className="fixed inset-0 bg-black/40 flex items-center justify-center z-50">
|
||||||
<div className="bg-white rounded-xl p-6 w-[500px] max-h-[90vh] overflow-y-auto space-y-4">
|
<div className="bg-white dark:bg-zinc-900 dark:border dark:border-zinc-700 rounded-xl p-6 w-[500px] max-h-[90vh] overflow-y-auto space-y-4">
|
||||||
<h2 className="text-lg font-semibold">{title}</h2>
|
<h2 className="text-lg font-semibold dark:text-white">{title}</h2>
|
||||||
|
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
<h3 className="text-sm font-semibold text-gray-700 border-b pb-2">
|
<h3 className="text-sm font-semibold text-gray-700 dark:text-zinc-200 border-b dark:border-zinc-700 pb-2">
|
||||||
Información del Concentrador
|
Información del Concentrador
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<div className="grid grid-cols-2 gap-3">
|
<div className="grid grid-cols-2 gap-3">
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm text-gray-600 mb-1">Serial *</label>
|
<label className="block text-sm text-gray-600 dark:text-zinc-400 mb-1">Serial *</label>
|
||||||
<input
|
<input
|
||||||
className={`w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent ${
|
className={`w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent ${
|
||||||
errors["serialNumber"] ? "border-red-500" : ""
|
errors["serialNumber"] ? "border-red-500" : ""
|
||||||
@@ -72,7 +72,7 @@ export default function ConcentratorsModal({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm text-gray-600 mb-1">Nombre *</label>
|
<label className="block text-sm text-gray-600 dark:text-zinc-400 mb-1">Nombre *</label>
|
||||||
<input
|
<input
|
||||||
className={`w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent ${
|
className={`w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent ${
|
||||||
errors["name"] ? "border-red-500" : ""
|
errors["name"] ? "border-red-500" : ""
|
||||||
@@ -90,7 +90,7 @@ export default function ConcentratorsModal({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm text-gray-600 mb-1">Proyecto *</label>
|
<label className="block text-sm text-gray-600 dark:text-zinc-400 mb-1">Proyecto *</label>
|
||||||
<select
|
<select
|
||||||
className={`w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent ${
|
className={`w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent ${
|
||||||
errors["projectId"] ? "border-red-500" : ""
|
errors["projectId"] ? "border-red-500" : ""
|
||||||
@@ -118,7 +118,7 @@ export default function ConcentratorsModal({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm text-gray-600 mb-1">Ubicación</label>
|
<label className="block text-sm text-gray-600 dark:text-zinc-400 mb-1">Ubicación</label>
|
||||||
<input
|
<input
|
||||||
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||||||
placeholder="Ubicación del concentrador (opcional)"
|
placeholder="Ubicación del concentrador (opcional)"
|
||||||
@@ -129,7 +129,7 @@ export default function ConcentratorsModal({
|
|||||||
|
|
||||||
<div className="grid grid-cols-2 gap-3">
|
<div className="grid grid-cols-2 gap-3">
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm text-gray-600 mb-1">Tipo *</label>
|
<label className="block text-sm text-gray-600 dark:text-zinc-400 mb-1">Tipo *</label>
|
||||||
<select
|
<select
|
||||||
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||||||
value={form.type ?? "LORA"}
|
value={form.type ?? "LORA"}
|
||||||
@@ -142,7 +142,7 @@ export default function ConcentratorsModal({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm text-gray-600 mb-1">Estado</label>
|
<label className="block text-sm text-gray-600 dark:text-zinc-400 mb-1">Estado</label>
|
||||||
<select
|
<select
|
||||||
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||||||
value={form.status ?? "ACTIVE"}
|
value={form.status ?? "ACTIVE"}
|
||||||
@@ -157,7 +157,7 @@ export default function ConcentratorsModal({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm text-gray-600 mb-1">Dirección IP</label>
|
<label className="block text-sm text-gray-600 dark:text-zinc-400 mb-1">Dirección IP</label>
|
||||||
<input
|
<input
|
||||||
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||||||
placeholder="192.168.1.100"
|
placeholder="192.168.1.100"
|
||||||
@@ -167,7 +167,7 @@ export default function ConcentratorsModal({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm text-gray-600 mb-1">Versión de Firmware</label>
|
<label className="block text-sm text-gray-600 dark:text-zinc-400 mb-1">Versión de Firmware</label>
|
||||||
<input
|
<input
|
||||||
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||||||
placeholder="v1.0.0"
|
placeholder="v1.0.0"
|
||||||
@@ -177,8 +177,8 @@ export default function ConcentratorsModal({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex justify-end gap-2 pt-3 border-t">
|
<div className="flex justify-end gap-2 pt-3 border-t dark:border-zinc-700">
|
||||||
<button onClick={onClose} className="px-4 py-2 rounded hover:bg-gray-100">
|
<button onClick={onClose} className="px-4 py-2 rounded hover:bg-gray-100 dark:hover:bg-zinc-800 dark:text-zinc-300">
|
||||||
Cancelar
|
Cancelar
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
|||||||
@@ -49,18 +49,18 @@ export default function MetersModal({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="fixed inset-0 bg-black/40 flex items-center justify-center z-50">
|
<div className="fixed inset-0 bg-black/40 flex items-center justify-center z-50">
|
||||||
<div className="bg-white rounded-xl p-6 w-[500px] max-h-[90vh] overflow-y-auto space-y-4">
|
<div className="bg-white dark:bg-zinc-900 dark:border dark:border-zinc-700 rounded-xl p-6 w-[500px] max-h-[90vh] overflow-y-auto space-y-4">
|
||||||
<h2 className="text-lg font-semibold">{title}</h2>
|
<h2 className="text-lg font-semibold dark:text-white">{title}</h2>
|
||||||
|
|
||||||
{/* FORM */}
|
{/* FORM */}
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
<h3 className="text-sm font-semibold text-gray-700 border-b pb-2">
|
<h3 className="text-sm font-semibold text-gray-700 dark:text-zinc-200 border-b dark:border-zinc-700 pb-2">
|
||||||
Información del Medidor
|
Información del Medidor
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<div className="grid grid-cols-2 gap-3">
|
<div className="grid grid-cols-2 gap-3">
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm text-gray-600 mb-1">Serial *</label>
|
<label className="block text-sm text-gray-600 dark:text-zinc-400 mb-1">Serial *</label>
|
||||||
<input
|
<input
|
||||||
className={`w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent ${
|
className={`w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent ${
|
||||||
errors["serialNumber"] ? "border-red-500" : ""
|
errors["serialNumber"] ? "border-red-500" : ""
|
||||||
@@ -79,7 +79,7 @@ export default function MetersModal({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm text-gray-600 mb-1">Meter ID</label>
|
<label className="block text-sm text-gray-600 dark:text-zinc-400 mb-1">Meter ID</label>
|
||||||
<input
|
<input
|
||||||
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||||||
placeholder="ID del medidor (opcional)"
|
placeholder="ID del medidor (opcional)"
|
||||||
@@ -90,7 +90,7 @@ export default function MetersModal({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm text-gray-600 mb-1">Nombre *</label>
|
<label className="block text-sm text-gray-600 dark:text-zinc-400 mb-1">Nombre *</label>
|
||||||
<input
|
<input
|
||||||
className={`w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent ${
|
className={`w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent ${
|
||||||
errors["name"] ? "border-red-500" : ""
|
errors["name"] ? "border-red-500" : ""
|
||||||
@@ -107,7 +107,7 @@ export default function MetersModal({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm text-gray-600 mb-1">Concentrador *</label>
|
<label className="block text-sm text-gray-600 dark:text-zinc-400 mb-1">Concentrador *</label>
|
||||||
<select
|
<select
|
||||||
className={`w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent ${
|
className={`w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent ${
|
||||||
errors["concentratorId"] ? "border-red-500" : ""
|
errors["concentratorId"] ? "border-red-500" : ""
|
||||||
@@ -135,7 +135,7 @@ export default function MetersModal({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm text-gray-600 mb-1">Ubicación</label>
|
<label className="block text-sm text-gray-600 dark:text-zinc-400 mb-1">Ubicación</label>
|
||||||
<input
|
<input
|
||||||
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||||||
placeholder="Ubicación del medidor (opcional)"
|
placeholder="Ubicación del medidor (opcional)"
|
||||||
@@ -146,7 +146,7 @@ export default function MetersModal({
|
|||||||
|
|
||||||
<div className="grid grid-cols-2 gap-3">
|
<div className="grid grid-cols-2 gap-3">
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm text-gray-600 mb-1">Tipo</label>
|
<label className="block text-sm text-gray-600 dark:text-zinc-400 mb-1">Tipo</label>
|
||||||
<select
|
<select
|
||||||
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||||||
value={form.type ?? "LORA"}
|
value={form.type ?? "LORA"}
|
||||||
@@ -159,7 +159,7 @@ export default function MetersModal({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm text-gray-600 mb-1">Estado</label>
|
<label className="block text-sm text-gray-600 dark:text-zinc-400 mb-1">Estado</label>
|
||||||
<select
|
<select
|
||||||
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||||||
value={form.status ?? "ACTIVE"}
|
value={form.status ?? "ACTIVE"}
|
||||||
@@ -175,7 +175,7 @@ export default function MetersModal({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm text-gray-600 mb-1">Fecha de Instalación</label>
|
<label className="block text-sm text-gray-600 dark:text-zinc-400 mb-1">Fecha de Instalación</label>
|
||||||
<input
|
<input
|
||||||
type="date"
|
type="date"
|
||||||
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||||||
@@ -192,13 +192,13 @@ export default function MetersModal({
|
|||||||
|
|
||||||
{isPruebaProject && (
|
{isPruebaProject && (
|
||||||
<div className="space-y-3">
|
<div className="space-y-3">
|
||||||
<h3 className="text-sm font-semibold text-gray-700 border-b pb-2">
|
<h3 className="text-sm font-semibold text-gray-700 dark:text-zinc-200 border-b dark:border-zinc-700 pb-2">
|
||||||
Información Técnica (Proyecto PRUEBA)
|
Información Técnica (Proyecto PRUEBA)
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<div className="grid grid-cols-2 gap-3">
|
<div className="grid grid-cols-2 gap-3">
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm text-gray-600 mb-1">Protocol</label>
|
<label className="block text-sm text-gray-600 dark:text-zinc-400 mb-1">Protocol</label>
|
||||||
<input
|
<input
|
||||||
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||||||
placeholder="ej: LoRaWAN"
|
placeholder="ej: LoRaWAN"
|
||||||
@@ -208,7 +208,7 @@ export default function MetersModal({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm text-gray-600 mb-1">Voltage (V)</label>
|
<label className="block text-sm text-gray-600 dark:text-zinc-400 mb-1">Voltage (V)</label>
|
||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
step="0.01"
|
step="0.01"
|
||||||
@@ -222,7 +222,7 @@ export default function MetersModal({
|
|||||||
|
|
||||||
<div className="grid grid-cols-2 gap-3">
|
<div className="grid grid-cols-2 gap-3">
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm text-gray-600 mb-1">Signal (dBm)</label>
|
<label className="block text-sm text-gray-600 dark:text-zinc-400 mb-1">Signal (dBm)</label>
|
||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||||||
@@ -233,7 +233,7 @@ export default function MetersModal({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm text-gray-600 mb-1">Current Flow</label>
|
<label className="block text-sm text-gray-600 dark:text-zinc-400 mb-1">Current Flow</label>
|
||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
step="0.0001"
|
step="0.0001"
|
||||||
@@ -247,7 +247,7 @@ export default function MetersModal({
|
|||||||
|
|
||||||
<div className="grid grid-cols-2 gap-3">
|
<div className="grid grid-cols-2 gap-3">
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm text-gray-600 mb-1">Total Flow Reverse</label>
|
<label className="block text-sm text-gray-600 dark:text-zinc-400 mb-1">Total Flow Reverse</label>
|
||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
step="0.0001"
|
step="0.0001"
|
||||||
@@ -259,7 +259,7 @@ export default function MetersModal({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm text-gray-600 mb-1">Leakage Status</label>
|
<label className="block text-sm text-gray-600 dark:text-zinc-400 mb-1">Leakage Status</label>
|
||||||
<select
|
<select
|
||||||
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||||||
value={form.leakageStatus ?? ""}
|
value={form.leakageStatus ?? ""}
|
||||||
@@ -276,7 +276,7 @@ export default function MetersModal({
|
|||||||
|
|
||||||
<div className="grid grid-cols-2 gap-3">
|
<div className="grid grid-cols-2 gap-3">
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm text-gray-600 mb-1">Burst Status</label>
|
<label className="block text-sm text-gray-600 dark:text-zinc-400 mb-1">Burst Status</label>
|
||||||
<select
|
<select
|
||||||
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||||||
value={form.burstStatus ?? ""}
|
value={form.burstStatus ?? ""}
|
||||||
@@ -291,7 +291,7 @@ export default function MetersModal({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm text-gray-600 mb-1">Manufacturer</label>
|
<label className="block text-sm text-gray-600 dark:text-zinc-400 mb-1">Manufacturer</label>
|
||||||
<input
|
<input
|
||||||
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||||||
placeholder="ej: Kamstrup"
|
placeholder="ej: Kamstrup"
|
||||||
@@ -303,7 +303,7 @@ export default function MetersModal({
|
|||||||
|
|
||||||
<div className="grid grid-cols-2 gap-3">
|
<div className="grid grid-cols-2 gap-3">
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm text-gray-600 mb-1">Latitude</label>
|
<label className="block text-sm text-gray-600 dark:text-zinc-400 mb-1">Latitude</label>
|
||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
step="0.00000001"
|
step="0.00000001"
|
||||||
@@ -315,7 +315,7 @@ export default function MetersModal({
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm text-gray-600 mb-1">Longitude</label>
|
<label className="block text-sm text-gray-600 dark:text-zinc-400 mb-1">Longitude</label>
|
||||||
<input
|
<input
|
||||||
type="number"
|
type="number"
|
||||||
step="0.00000001"
|
step="0.00000001"
|
||||||
@@ -330,8 +330,8 @@ export default function MetersModal({
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{/* ACTIONS */}
|
{/* ACTIONS */}
|
||||||
<div className="flex justify-end gap-2 pt-3 border-t">
|
<div className="flex justify-end gap-2 pt-3 border-t dark:border-zinc-700">
|
||||||
<button onClick={onClose} className="px-4 py-2 rounded hover:bg-gray-100">
|
<button onClick={onClose} className="px-4 py-2 rounded hover:bg-gray-100 dark:hover:bg-zinc-800 dark:text-zinc-300">
|
||||||
Cancelar
|
Cancelar
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
|
|||||||
@@ -291,13 +291,13 @@ export default function ProjectsPage() {
|
|||||||
{/* MODAL */}
|
{/* MODAL */}
|
||||||
{showModal && (
|
{showModal && (
|
||||||
<div className="fixed inset-0 bg-black/40 flex items-center justify-center z-50">
|
<div className="fixed inset-0 bg-black/40 flex items-center justify-center z-50">
|
||||||
<div className="bg-white rounded-xl p-6 w-[450px] space-y-4">
|
<div className="bg-white dark:bg-zinc-900 dark:border dark:border-zinc-700 rounded-xl p-6 w-[450px] space-y-4">
|
||||||
<h2 className="text-lg font-semibold">
|
<h2 className="text-lg font-semibold dark:text-white">
|
||||||
{editingId ? "Editar Proyecto" : "Agregar Proyecto"}
|
{editingId ? "Editar Proyecto" : "Agregar Proyecto"}
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm text-gray-600 mb-1">Nombre *</label>
|
<label className="block text-sm text-gray-600 dark:text-zinc-400 mb-1">Nombre *</label>
|
||||||
<input
|
<input
|
||||||
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||||||
placeholder="Nombre del proyecto"
|
placeholder="Nombre del proyecto"
|
||||||
@@ -307,7 +307,7 @@ export default function ProjectsPage() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm text-gray-600 mb-1">Area *</label>
|
<label className="block text-sm text-gray-600 dark:text-zinc-400 mb-1">Area *</label>
|
||||||
<input
|
<input
|
||||||
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||||||
placeholder="Nombre del area"
|
placeholder="Nombre del area"
|
||||||
@@ -317,7 +317,7 @@ export default function ProjectsPage() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm text-gray-600 mb-1">Descripción</label>
|
<label className="block text-sm text-gray-600 dark:text-zinc-400 mb-1">Descripción</label>
|
||||||
<textarea
|
<textarea
|
||||||
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||||||
placeholder="Descripción del proyecto (opcional)"
|
placeholder="Descripción del proyecto (opcional)"
|
||||||
@@ -328,7 +328,7 @@ export default function ProjectsPage() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm text-gray-600 mb-1">Ubicación</label>
|
<label className="block text-sm text-gray-600 dark:text-zinc-400 mb-1">Ubicación</label>
|
||||||
<input
|
<input
|
||||||
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||||||
placeholder="Ubicación (opcional)"
|
placeholder="Ubicación (opcional)"
|
||||||
@@ -338,7 +338,7 @@ export default function ProjectsPage() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm text-gray-600 mb-1">Tipo de Toma</label>
|
<label className="block text-sm text-gray-600 dark:text-zinc-400 mb-1">Tipo de Toma</label>
|
||||||
<select
|
<select
|
||||||
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||||||
value={form.meterTypeId ?? ""}
|
value={form.meterTypeId ?? ""}
|
||||||
@@ -359,7 +359,7 @@ export default function ProjectsPage() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<label className="block text-sm text-gray-600 mb-1">Estado</label>
|
<label className="block text-sm text-gray-600 dark:text-zinc-400 mb-1">Estado</label>
|
||||||
<select
|
<select
|
||||||
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
className="w-full border px-3 py-2 rounded focus:ring-2 focus:ring-blue-500 focus:border-transparent"
|
||||||
value={form.status ?? "ACTIVE"}
|
value={form.status ?? "ACTIVE"}
|
||||||
@@ -371,10 +371,10 @@ export default function ProjectsPage() {
|
|||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="flex justify-end gap-2 pt-3 border-t">
|
<div className="flex justify-end gap-2 pt-3 border-t dark:border-zinc-700">
|
||||||
<button
|
<button
|
||||||
onClick={() => setShowModal(false)}
|
onClick={() => setShowModal(false)}
|
||||||
className="px-4 py-2 rounded hover:bg-gray-100"
|
className="px-4 py-2 rounded hover:bg-gray-100 dark:hover:bg-zinc-800 dark:text-zinc-300"
|
||||||
>
|
>
|
||||||
Cancelar
|
Cancelar
|
||||||
</button>
|
</button>
|
||||||
|
|||||||
Reference in New Issue
Block a user