forked from RiseUP/riseup-squad21
Sidebar atualizada
This commit is contained in:
parent
ad9e7214cb
commit
c74c77c8be
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
import type React from "react";
|
import type React from "react";
|
||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import DoctorLayout from "@/components/doctor-layout";
|
|
||||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Clock, Calendar as CalendarIcon, MapPin, Phone, User, X, RefreshCw } from "lucide-react";
|
import { Clock, Calendar as CalendarIcon, MapPin, Phone, User, X, RefreshCw } from "lucide-react";
|
||||||
@ -12,6 +11,7 @@ import { toast } from "sonner";
|
|||||||
// IMPORTAR O COMPONENTE CALENDÁRIO DA SHADCN
|
// IMPORTAR O COMPONENTE CALENDÁRIO DA SHADCN
|
||||||
import { Calendar } from "@/components/ui/calendar";
|
import { Calendar } from "@/components/ui/calendar";
|
||||||
import { format } from "date-fns"; // Usaremos o date-fns para formatação e comparação de datas
|
import { format } from "date-fns"; // Usaremos o date-fns para formatação e comparação de datas
|
||||||
|
import Sidebar from "@/components/Sidebar";
|
||||||
|
|
||||||
const APPOINTMENTS_STORAGE_KEY = "clinic-appointments";
|
const APPOINTMENTS_STORAGE_KEY = "clinic-appointments";
|
||||||
|
|
||||||
@ -141,7 +141,7 @@ export default function DoctorAppointmentsPage() {
|
|||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DoctorLayout>
|
<Sidebar>
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
<div>
|
<div>
|
||||||
<h1 className="text-3xl font-bold text-gray-900">Agenda Médica Centralizada</h1>
|
<h1 className="text-3xl font-bold text-gray-900">Agenda Médica Centralizada</h1>
|
||||||
@ -267,6 +267,6 @@ export default function DoctorAppointmentsPage() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</DoctorLayout>
|
</Sidebar>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -14,6 +14,7 @@ import { AvailabilityService } from "@/services/availabilityApi.mjs";
|
|||||||
import { exceptionsService } from "@/services/exceptionApi.mjs";
|
import { exceptionsService } from "@/services/exceptionApi.mjs";
|
||||||
import { doctorsService } from "@/services/doctorsApi.mjs";
|
import { doctorsService } from "@/services/doctorsApi.mjs";
|
||||||
import { usersService } from "@/services/usersApi.mjs";
|
import { usersService } from "@/services/usersApi.mjs";
|
||||||
|
import Sidebar from "@/components/Sidebar";
|
||||||
|
|
||||||
type Availability = {
|
type Availability = {
|
||||||
id: string;
|
id: string;
|
||||||
@ -231,7 +232,7 @@ export default function PatientDashboard() {
|
|||||||
}, [availability]);
|
}, [availability]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DoctorLayout>
|
<Sidebar>
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
<div>
|
<div>
|
||||||
<h1 className="text-3xl font-bold text-gray-900">Dashboard</h1>
|
<h1 className="text-3xl font-bold text-gray-900">Dashboard</h1>
|
||||||
@ -409,6 +410,6 @@ export default function PatientDashboard() {
|
|||||||
</AlertDialogContent>
|
</AlertDialogContent>
|
||||||
</AlertDialog>
|
</AlertDialog>
|
||||||
</div>
|
</div>
|
||||||
</DoctorLayout>
|
</Sidebar>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,14 +3,12 @@
|
|||||||
import type React from "react";
|
import type React from "react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import DoctorLayout from "@/components/doctor-layout";
|
|
||||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { Label } from "@/components/ui/label";
|
import { Label } from "@/components/ui/label";
|
||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||||
import { Clock, Calendar as CalendarIcon, MapPin, Phone, User, X, RefreshCw } from "lucide-react";
|
import { Calendar as CalendarIcon, RefreshCw } from "lucide-react";
|
||||||
import { Badge } from "@/components/ui/badge";
|
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import { toast } from "@/hooks/use-toast";
|
import { toast } from "@/hooks/use-toast";
|
||||||
import { exceptionsService } from "@/services/exceptionApi.mjs";
|
import { exceptionsService } from "@/services/exceptionApi.mjs";
|
||||||
@ -19,6 +17,7 @@ import { exceptionsService } from "@/services/exceptionApi.mjs";
|
|||||||
import { Calendar } from "@/components/ui/calendar";
|
import { Calendar } from "@/components/ui/calendar";
|
||||||
import { format } from "date-fns"; // Usaremos o date-fns para formatação e comparação de datas
|
import { format } from "date-fns"; // Usaremos o date-fns para formatação e comparação de datas
|
||||||
import { doctorsService } from "@/services/doctorsApi.mjs";
|
import { doctorsService } from "@/services/doctorsApi.mjs";
|
||||||
|
import Sidebar from "@/components/Sidebar";
|
||||||
|
|
||||||
type Doctor = {
|
type Doctor = {
|
||||||
id: string;
|
id: string;
|
||||||
@ -147,7 +146,7 @@ export default function ExceptionPage() {
|
|||||||
const displayDate = selectedCalendarDate ? new Date(selectedCalendarDate).toLocaleDateString("pt-BR", { weekday: "long", day: "2-digit", month: "long" }) : "Selecione uma data";
|
const displayDate = selectedCalendarDate ? new Date(selectedCalendarDate).toLocaleDateString("pt-BR", { weekday: "long", day: "2-digit", month: "long" }) : "Selecione uma data";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DoctorLayout>
|
<Sidebar>
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
<div>
|
<div>
|
||||||
<h1 className="text-3xl font-bold text-gray-900">Adicione exceções</h1>
|
<h1 className="text-3xl font-bold text-gray-900">Adicione exceções</h1>
|
||||||
@ -254,6 +253,6 @@ export default function ExceptionPage() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</DoctorLayout>
|
</Sidebar>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -7,7 +7,6 @@ import { Button } from "@/components/ui/button";
|
|||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { Label } from "@/components/ui/label";
|
import { Label } from "@/components/ui/label";
|
||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||||
import DoctorLayout from "@/components/doctor-layout";
|
|
||||||
|
|
||||||
import { AvailabilityService } from "@/services/availabilityApi.mjs";
|
import { AvailabilityService } from "@/services/availabilityApi.mjs";
|
||||||
import { usersService } from "@/services/usersApi.mjs";
|
import { usersService } from "@/services/usersApi.mjs";
|
||||||
@ -17,9 +16,10 @@ import { toast } from "@/hooks/use-toast";
|
|||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import { Card, CardHeader, CardTitle, CardDescription, CardContent } from "@/components/ui/card";
|
import { Card, CardHeader, CardTitle, CardDescription, CardContent } from "@/components/ui/card";
|
||||||
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu";
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu";
|
||||||
import { Eye, Edit, Calendar, Trash2 } from "lucide-react";
|
import { Edit, Trash2 } from "lucide-react";
|
||||||
import { AvailabilityEditModal } from "@/components/ui/availability-edit-modal";
|
import { AvailabilityEditModal } from "@/components/ui/availability-edit-modal";
|
||||||
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from "@/components/ui/alert-dialog";
|
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from "@/components/ui/alert-dialog";
|
||||||
|
import Sidebar from "@/components/Sidebar";
|
||||||
|
|
||||||
// ... (Interfaces de tipo omitidas para brevidade, pois não foram alteradas)
|
// ... (Interfaces de tipo omitidas para brevidade, pois não foram alteradas)
|
||||||
|
|
||||||
@ -323,7 +323,7 @@ export default function AvailabilityPage() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DoctorLayout>
|
<Sidebar>
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div>
|
<div>
|
||||||
@ -506,6 +506,6 @@ export default function AvailabilityPage() {
|
|||||||
onSubmit={handleEdit}
|
onSubmit={handleEdit}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
</DoctorLayout>
|
</Sidebar>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -12,7 +12,7 @@ import { Textarea } from "@/components/ui/textarea";
|
|||||||
import { Checkbox } from "@/components/ui/checkbox";
|
import { Checkbox } from "@/components/ui/checkbox";
|
||||||
import { ArrowLeft, Save } from "lucide-react";
|
import { ArrowLeft, Save } from "lucide-react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import DoctorLayout from "@/components/doctor-layout";
|
import Sidebar from "@/components/Sidebar";
|
||||||
|
|
||||||
// Mock data - in a real app, this would come from an API
|
// Mock data - in a real app, this would come from an API
|
||||||
const mockDoctors = [
|
const mockDoctors = [
|
||||||
@ -124,7 +124,7 @@ export default function EditarMedicoPage() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DoctorLayout>
|
<Sidebar>
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
<div className="flex items-center gap-4">
|
<div className="flex items-center gap-4">
|
||||||
<Link href="/medicos">
|
<Link href="/medicos">
|
||||||
@ -512,6 +512,6 @@ export default function EditarMedicoPage() {
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</DoctorLayout>
|
</Sidebar>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,6 @@
|
|||||||
|
|
||||||
import { useParams, useRouter } from "next/navigation";
|
import { useParams, useRouter } from "next/navigation";
|
||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import DoctorLayout from "@/components/doctor-layout";
|
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
@ -17,6 +16,7 @@ import { format } from "date-fns";
|
|||||||
import TiptapEditor from "@/components/ui/tiptap-editor";
|
import TiptapEditor from "@/components/ui/tiptap-editor";
|
||||||
import { Skeleton } from "@/components/ui/skeleton";
|
import { Skeleton } from "@/components/ui/skeleton";
|
||||||
import { reportsApi } from "@/services/reportsApi.mjs";
|
import { reportsApi } from "@/services/reportsApi.mjs";
|
||||||
|
import Sidebar from "@/components/Sidebar";
|
||||||
|
|
||||||
export default function EditarLaudoPage() {
|
export default function EditarLaudoPage() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -108,7 +108,7 @@ export default function EditarLaudoPage() {
|
|||||||
|
|
||||||
if (loading) {
|
if (loading) {
|
||||||
return (
|
return (
|
||||||
<DoctorLayout>
|
<Sidebar>
|
||||||
<div className="container mx-auto p-4">
|
<div className="container mx-auto p-4">
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
@ -130,12 +130,12 @@ export default function EditarLaudoPage() {
|
|||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
</DoctorLayout>
|
</Sidebar>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DoctorLayout>
|
<Sidebar>
|
||||||
<div className="container mx-auto p-4">
|
<div className="container mx-auto p-4">
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
@ -232,6 +232,6 @@ export default function EditarLaudoPage() {
|
|||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
</DoctorLayout>
|
</Sidebar>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -18,6 +18,7 @@ import TiptapEditor from "@/components/ui/tiptap-editor";
|
|||||||
|
|
||||||
import { reportsApi } from "@/services/reportsApi.mjs";
|
import { reportsApi } from "@/services/reportsApi.mjs";
|
||||||
import DoctorLayout from "@/components/doctor-layout";
|
import DoctorLayout from "@/components/doctor-layout";
|
||||||
|
import Sidebar from "@/components/Sidebar";
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@ -97,7 +98,7 @@ export default function NovoLaudoPage() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DoctorLayout>
|
<Sidebar>
|
||||||
<div className="container mx-auto p-4">
|
<div className="container mx-auto p-4">
|
||||||
<Card>
|
<Card>
|
||||||
<CardHeader>
|
<CardHeader>
|
||||||
@ -189,6 +190,6 @@ export default function NovoLaudoPage() {
|
|||||||
</CardContent>
|
</CardContent>
|
||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
</DoctorLayout>
|
</Sidebar>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -8,7 +8,7 @@ import Link from 'next/link';
|
|||||||
import { useParams } from 'next/navigation';
|
import { useParams } from 'next/navigation';
|
||||||
import { api } from '@/services/api.mjs';
|
import { api } from '@/services/api.mjs';
|
||||||
import { reportsApi } from '@/services/reportsApi.mjs';
|
import { reportsApi } from '@/services/reportsApi.mjs';
|
||||||
import DoctorLayout from '@/components/doctor-layout';
|
import Sidebar from '@/components/Sidebar';
|
||||||
|
|
||||||
export default function LaudosPage() {
|
export default function LaudosPage() {
|
||||||
const [patient, setPatient] = useState(null);
|
const [patient, setPatient] = useState(null);
|
||||||
@ -49,7 +49,7 @@ export default function LaudosPage() {
|
|||||||
const paginate = (pageNumber) => setCurrentPage(pageNumber);
|
const paginate = (pageNumber) => setCurrentPage(pageNumber);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DoctorLayout>
|
<Sidebar>
|
||||||
<div className="container mx-auto p-4">
|
<div className="container mx-auto p-4">
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<p>Carregando...</p>
|
<p>Carregando...</p>
|
||||||
@ -123,6 +123,6 @@ export default function LaudosPage() {
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</DoctorLayout>
|
</Sidebar>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -9,7 +9,7 @@ import { Textarea } from "@/components/ui/textarea";
|
|||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||||
import { Upload, Plus, X, ChevronDown } from "lucide-react";
|
import { Upload, Plus, X, ChevronDown } from "lucide-react";
|
||||||
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible";
|
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "@/components/ui/collapsible";
|
||||||
import DoctorLayout from "@/components/doctor-layout";
|
import Sidebar from "@/components/Sidebar";
|
||||||
|
|
||||||
export default function NovoMedicoPage() {
|
export default function NovoMedicoPage() {
|
||||||
const [anexosOpen, setAnexosOpen] = useState(false);
|
const [anexosOpen, setAnexosOpen] = useState(false);
|
||||||
@ -24,7 +24,7 @@ export default function NovoMedicoPage() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DoctorLayout>
|
<Sidebar>
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div>
|
<div>
|
||||||
@ -466,6 +466,6 @@ export default function NovoMedicoPage() {
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</DoctorLayout>
|
</Sidebar>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,25 +2,14 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useEffect, useState, useCallback } from "react";
|
import { useEffect, useState, useCallback } from "react";
|
||||||
import DoctorLayout from "@/components/doctor-layout";
|
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import {
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu";
|
||||||
DropdownMenu,
|
|
||||||
DropdownMenuContent,
|
|
||||||
DropdownMenuItem,
|
|
||||||
DropdownMenuTrigger,
|
|
||||||
} from "@/components/ui/dropdown-menu";
|
|
||||||
import { Eye, Edit, Calendar, Trash2, Loader2 } from "lucide-react";
|
import { Eye, Edit, Calendar, Trash2, Loader2 } from "lucide-react";
|
||||||
import { api } from "@/services/api.mjs";
|
import { api } from "@/services/api.mjs";
|
||||||
import { PatientDetailsModal } from "@/components/ui/patient-details-modal";
|
import { PatientDetailsModal } from "@/components/ui/patient-details-modal";
|
||||||
import {
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||||
Select,
|
|
||||||
SelectContent,
|
|
||||||
SelectItem,
|
|
||||||
SelectTrigger,
|
|
||||||
SelectValue,
|
|
||||||
} from "@/components/ui/select";
|
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
|
import Sidebar from "@/components/Sidebar";
|
||||||
|
|
||||||
interface Paciente {
|
interface Paciente {
|
||||||
id: string;
|
id: string;
|
||||||
@ -171,7 +160,7 @@ export default function PacientesPage() {
|
|||||||
}, [fetchPacientes]);
|
}, [fetchPacientes]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DoctorLayout>
|
<Sidebar>
|
||||||
<div className="space-y-6 px-2 sm:px-4 md:px-6">
|
<div className="space-y-6 px-2 sm:px-4 md:px-6">
|
||||||
{/* Cabeçalho */}
|
{/* Cabeçalho */}
|
||||||
<div className="flex flex-wrap items-center justify-between gap-3">
|
<div className="flex flex-wrap items-center justify-between gap-3">
|
||||||
@ -363,6 +352,6 @@ export default function PacientesPage() {
|
|||||||
isOpen={isModalOpen}
|
isOpen={isModalOpen}
|
||||||
onClose={handleCloseModal}
|
onClose={handleCloseModal}
|
||||||
/>
|
/>
|
||||||
</DoctorLayout>
|
</Sidebar>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -1,7 +1,7 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import FinancierLayout from "@/components/finance-layout";
|
import Sidebar from "@/components/Sidebar";
|
||||||
|
|
||||||
interface Paciente {
|
interface Paciente {
|
||||||
id: string;
|
id: string;
|
||||||
@ -14,43 +14,10 @@ interface Paciente {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function PacientesPage() {
|
export default function PacientesPage() {
|
||||||
const [pacientes, setPacientes] = useState<Paciente[]>([]);
|
|
||||||
const [loading, setLoading] = useState(true);
|
|
||||||
const [error, setError] = useState<string | null>(null);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
async function fetchPacientes() {
|
|
||||||
try {
|
|
||||||
setLoading(true);
|
|
||||||
setError(null);
|
|
||||||
const res = await fetch("https://mock.apidog.com/m1/1053378-0-default/pacientes");
|
|
||||||
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
||||||
const json = await res.json();
|
|
||||||
const items = Array.isArray(json?.data) ? json.data : [];
|
|
||||||
|
|
||||||
const mapped = items.map((p: any) => ({
|
|
||||||
id: String(p.id ?? ""),
|
|
||||||
nome: p.nome ?? "",
|
|
||||||
telefone: p?.contato?.celular ?? p?.contato?.telefone1 ?? p?.telefone ?? "",
|
|
||||||
cidade: p?.endereco?.cidade ?? p?.cidade ?? "",
|
|
||||||
estado: p?.endereco?.estado ?? p?.estado ?? "",
|
|
||||||
ultimoAtendimento: p.ultimo_atendimento ?? p.ultimoAtendimento ?? "",
|
|
||||||
proximoAtendimento: p.proximo_atendimento ?? p.proximoAtendimento ?? "",
|
|
||||||
}));
|
|
||||||
|
|
||||||
setPacientes(mapped);
|
|
||||||
} catch (e: any) {
|
|
||||||
setError(e?.message || "Erro ao carregar pacientes");
|
|
||||||
} finally {
|
|
||||||
setLoading(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fetchPacientes();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<FinancierLayout>
|
<Sidebar>
|
||||||
<div></div>
|
<div></div>
|
||||||
</FinancierLayout>
|
</Sidebar>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import Link from "next/link";
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import { usersService } from "services/usersApi.mjs";
|
import { usersService } from "services/usersApi.mjs";
|
||||||
import { doctorsService } from "services/doctorsApi.mjs";
|
import { doctorsService } from "services/doctorsApi.mjs";
|
||||||
|
import Sidebar from "@/components/Sidebar";
|
||||||
|
|
||||||
export default function ManagerDashboard() {
|
export default function ManagerDashboard() {
|
||||||
// 🔹 Estados para usuários
|
// 🔹 Estados para usuários
|
||||||
@ -55,7 +56,7 @@ export default function ManagerDashboard() {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ManagerLayout>
|
<Sidebar>
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
{/* Cabeçalho */}
|
{/* Cabeçalho */}
|
||||||
<div>
|
<div>
|
||||||
@ -185,6 +186,6 @@ export default function ManagerDashboard() {
|
|||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ManagerLayout>
|
</Sidebar>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,25 +1,16 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import React, { useEffect, useState, useCallback, useMemo } from "react"
|
import React, { useEffect, useState, useCallback, useMemo } from "react"
|
||||||
import ManagerLayout from "@/components/manager-layout";
|
|
||||||
import Link from "next/link"
|
import Link from "next/link"
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import { Button } from "@/components/ui/button"
|
import { Button } from "@/components/ui/button"
|
||||||
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"
|
||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
|
||||||
import { Plus, Edit, Trash2, Eye, Calendar, Filter, Loader2 } from "lucide-react"
|
import { Edit, Trash2, Eye, Calendar, Filter, Loader2 } from "lucide-react"
|
||||||
import {
|
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from "@/components/ui/alert-dialog"
|
||||||
AlertDialog,
|
|
||||||
AlertDialogAction,
|
|
||||||
AlertDialogCancel,
|
|
||||||
AlertDialogContent,
|
|
||||||
AlertDialogDescription,
|
|
||||||
AlertDialogFooter,
|
|
||||||
AlertDialogHeader,
|
|
||||||
AlertDialogTitle,
|
|
||||||
} from "@/components/ui/alert-dialog"
|
|
||||||
|
|
||||||
import { doctorsService } from "services/doctorsApi.mjs";
|
import { doctorsService } from "services/doctorsApi.mjs";
|
||||||
|
import Sidebar from "@/components/Sidebar";
|
||||||
|
|
||||||
|
|
||||||
interface Doctor {
|
interface Doctor {
|
||||||
@ -193,7 +184,7 @@ export default function DoctorsPage() {
|
|||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ManagerLayout>
|
<Sidebar>
|
||||||
<div className="space-y-6 px-2 sm:px-4 md:px-6">
|
<div className="space-y-6 px-2 sm:px-4 md:px-6">
|
||||||
|
|
||||||
{/* Cabeçalho */}
|
{/* Cabeçalho */}
|
||||||
@ -430,6 +421,6 @@ export default function DoctorsPage() {
|
|||||||
</AlertDialogContent>
|
</AlertDialogContent>
|
||||||
</AlertDialog>
|
</AlertDialog>
|
||||||
</div>
|
</div>
|
||||||
</ManagerLayout>
|
</Sidebar>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -13,9 +13,8 @@ import { Checkbox } from "@/components/ui/checkbox";
|
|||||||
import { ArrowLeft, Save, Trash2, Paperclip, Upload } from "lucide-react";
|
import { ArrowLeft, Save, Trash2, Paperclip, Upload } from "lucide-react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useToast } from "@/hooks/use-toast";
|
import { useToast } from "@/hooks/use-toast";
|
||||||
import SecretaryLayout from "@/components/secretary-layout";
|
|
||||||
import { patientsService } from "@/services/patientsApi.mjs";
|
import { patientsService } from "@/services/patientsApi.mjs";
|
||||||
import { json } from "stream/consumers";
|
import Sidebar from "@/components/Sidebar";
|
||||||
|
|
||||||
export default function EditarPacientePage() {
|
export default function EditarPacientePage() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -247,7 +246,7 @@ export default function EditarPacientePage() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SecretaryLayout>
|
<Sidebar>
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
<div className="flex items-center gap-4">
|
<div className="flex items-center gap-4">
|
||||||
<Link href="/manager/pacientes">
|
<Link href="/manager/pacientes">
|
||||||
@ -677,6 +676,6 @@ export default function EditarPacientePage() {
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</SecretaryLayout>
|
</Sidebar>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,10 +6,10 @@ import Link from "next/link";
|
|||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu";
|
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu";
|
||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||||
import { Plus, Edit, Trash2, Eye, Calendar, Filter, Loader2 } from "lucide-react";
|
import { Edit, Trash2, Eye, Calendar, Filter, Loader2 } from "lucide-react";
|
||||||
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from "@/components/ui/alert-dialog";
|
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from "@/components/ui/alert-dialog";
|
||||||
import { patientsService } from "@/services/patientsApi.mjs";
|
import { patientsService } from "@/services/patientsApi.mjs";
|
||||||
import ManagerLayout from "@/components/manager-layout";
|
import Sidebar from "@/components/Sidebar";
|
||||||
|
|
||||||
// Defina o tamanho da página.
|
// Defina o tamanho da página.
|
||||||
const PAGE_SIZE = 5;
|
const PAGE_SIZE = 5;
|
||||||
@ -145,7 +145,7 @@ export default function PacientesPage() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ManagerLayout>
|
<Sidebar>
|
||||||
<div className="space-y-6 px-2 sm:px-4 md:px-8">
|
<div className="space-y-6 px-2 sm:px-4 md:px-8">
|
||||||
{/* Header (Responsividade OK) */}
|
{/* Header (Responsividade OK) */}
|
||||||
<div className="flex flex-col md:flex-row md:items-center md:justify-between gap-4">
|
<div className="flex flex-col md:flex-row md:items-center md:justify-between gap-4">
|
||||||
@ -449,6 +449,6 @@ export default function PacientesPage() {
|
|||||||
</AlertDialogContent>
|
</AlertDialogContent>
|
||||||
</AlertDialog>
|
</AlertDialog>
|
||||||
</div>
|
</div>
|
||||||
</ManagerLayout>
|
</Sidebar>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -8,7 +8,7 @@ import { Input } from "@/components/ui/input"
|
|||||||
import { Label } from "@/components/ui/label"
|
import { Label } from "@/components/ui/label"
|
||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
|
||||||
import { Save, Loader2, ArrowLeft } from "lucide-react"
|
import { Save, Loader2, ArrowLeft } from "lucide-react"
|
||||||
import ManagerLayout from "@/components/manager-layout"
|
import Sidebar from "@/components/Sidebar"
|
||||||
|
|
||||||
// Mock user service for demonstration. Replace with your actual API service.
|
// Mock user service for demonstration. Replace with your actual API service.
|
||||||
const usersService = {
|
const usersService = {
|
||||||
@ -155,17 +155,17 @@ export default function EditarUsuarioPage() {
|
|||||||
|
|
||||||
if (loading) {
|
if (loading) {
|
||||||
return (
|
return (
|
||||||
<ManagerLayout>
|
<Sidebar>
|
||||||
<div className="flex justify-center items-center h-full w-full py-16">
|
<div className="flex justify-center items-center h-full w-full py-16">
|
||||||
<Loader2 className="w-8 h-8 animate-spin text-green-600" />
|
<Loader2 className="w-8 h-8 animate-spin text-green-600" />
|
||||||
<p className="ml-2 text-gray-600">Carregando dados do usuário...</p>
|
<p className="ml-2 text-gray-600">Carregando dados do usuário...</p>
|
||||||
</div>
|
</div>
|
||||||
</ManagerLayout>
|
</Sidebar>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ManagerLayout>
|
<Sidebar>
|
||||||
<div className="w-full max-w-2xl mx-auto space-y-6 p-4 md:p-8">
|
<div className="w-full max-w-2xl mx-auto space-y-6 p-4 md:p-8">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div>
|
<div>
|
||||||
@ -274,6 +274,6 @@ export default function EditarUsuarioPage() {
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</ManagerLayout>
|
</Sidebar>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -10,10 +10,9 @@ import { Input } from "@/components/ui/input";
|
|||||||
import { Label } from "@/components/ui/label";
|
import { Label } from "@/components/ui/label";
|
||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||||
import { Save, Loader2, Pause } from "lucide-react";
|
import { Save, Loader2, Pause } from "lucide-react";
|
||||||
import ManagerLayout from "@/components/manager-layout";
|
|
||||||
import { usersService } from "@/services/usersApi.mjs";
|
import { usersService } from "@/services/usersApi.mjs";
|
||||||
import { doctorsService } from "@/services/doctorsApi.mjs"; // Importação adicionada
|
import { doctorsService } from "@/services/doctorsApi.mjs";
|
||||||
import { login } from "services/api.mjs";
|
import Sidebar from "@/components/Sidebar";
|
||||||
|
|
||||||
interface UserFormData {
|
interface UserFormData {
|
||||||
email: string;
|
email: string;
|
||||||
@ -145,7 +144,7 @@ export default function NovoUsuarioPage() {
|
|||||||
const isMedico = formData.papel === "medico";
|
const isMedico = formData.papel === "medico";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ManagerLayout>
|
<Sidebar>
|
||||||
<div className="w-full h-full p-4 md:p-8 flex justify-center items-start">
|
<div className="w-full h-full p-4 md:p-8 flex justify-center items-start">
|
||||||
<div className="w-full max-w-screen-lg space-y-8">
|
<div className="w-full max-w-screen-lg space-y-8">
|
||||||
<div className="flex items-center justify-between border-b pb-4">
|
<div className="flex items-center justify-between border-b pb-4">
|
||||||
@ -250,6 +249,6 @@ export default function NovoUsuarioPage() {
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ManagerLayout>
|
</Sidebar>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,28 +2,14 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import React, { useEffect, useState, useCallback } from "react";
|
import React, { useEffect, useState, useCallback } from "react";
|
||||||
import ManagerLayout from "@/components/manager-layout";
|
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import {
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||||
Select,
|
|
||||||
SelectContent,
|
|
||||||
SelectItem,
|
|
||||||
SelectTrigger,
|
|
||||||
SelectValue,
|
|
||||||
} from "@/components/ui/select";
|
|
||||||
import { Plus, Eye, Filter, Loader2 } from "lucide-react";
|
import { Plus, Eye, Filter, Loader2 } from "lucide-react";
|
||||||
import {
|
import { AlertDialog, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from "@/components/ui/alert-dialog";
|
||||||
AlertDialog,
|
|
||||||
AlertDialogCancel,
|
|
||||||
AlertDialogContent,
|
|
||||||
AlertDialogDescription,
|
|
||||||
AlertDialogFooter,
|
|
||||||
AlertDialogHeader,
|
|
||||||
AlertDialogTitle,
|
|
||||||
} from "@/components/ui/alert-dialog";
|
|
||||||
import { api, login } from "services/api.mjs";
|
import { api, login } from "services/api.mjs";
|
||||||
import { usersService } from "services/usersApi.mjs";
|
import { usersService } from "services/usersApi.mjs";
|
||||||
|
import Sidebar from "@/components/Sidebar";
|
||||||
|
|
||||||
interface FlatUser {
|
interface FlatUser {
|
||||||
id: string;
|
id: string;
|
||||||
@ -192,7 +178,7 @@ export default function UsersPage() {
|
|||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ManagerLayout>
|
<Sidebar>
|
||||||
<div className="space-y-6 px-2 sm:px-4 md:px-8">
|
<div className="space-y-6 px-2 sm:px-4 md:px-8">
|
||||||
|
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
@ -424,6 +410,6 @@ export default function UsersPage() {
|
|||||||
</AlertDialogContent>
|
</AlertDialogContent>
|
||||||
</AlertDialog>
|
</AlertDialog>
|
||||||
</div>
|
</div>
|
||||||
</ManagerLayout>
|
</Sidebar>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -1,7 +1,6 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import PatientLayout from "@/components/patient-layout";
|
|
||||||
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
|
import { Card, CardContent, CardHeader, CardTitle, CardDescription } from "@/components/ui/card";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Badge } from "@/components/ui/badge";
|
import { Badge } from "@/components/ui/badge";
|
||||||
@ -10,6 +9,7 @@ import { toast } from "sonner";
|
|||||||
|
|
||||||
import { appointmentsService } from "@/services/appointmentsApi.mjs";
|
import { appointmentsService } from "@/services/appointmentsApi.mjs";
|
||||||
import { usersService } from "@/services/usersApi.mjs";
|
import { usersService } from "@/services/usersApi.mjs";
|
||||||
|
import Sidebar from "@/components/Sidebar";
|
||||||
|
|
||||||
// Tipagem correta para o usuário
|
// Tipagem correta para o usuário
|
||||||
interface UserProfile {
|
interface UserProfile {
|
||||||
@ -129,7 +129,7 @@ export default function PatientAppointmentsPage() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PatientLayout>
|
<Sidebar>
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
<div className="flex justify-between items-center">
|
<div className="flex justify-between items-center">
|
||||||
<div>
|
<div>
|
||||||
@ -185,6 +185,6 @@ export default function PatientAppointmentsPage() {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</PatientLayout>
|
</Sidebar>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -3,10 +3,11 @@ import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/com
|
|||||||
import { Button } from "@/components/ui/button"
|
import { Button } from "@/components/ui/button"
|
||||||
import { Calendar, Clock, User, Plus } from "lucide-react"
|
import { Calendar, Clock, User, Plus } from "lucide-react"
|
||||||
import Link from "next/link"
|
import Link from "next/link"
|
||||||
|
import Sidebar from "@/components/Sidebar"
|
||||||
|
|
||||||
export default function PatientDashboard() {
|
export default function PatientDashboard() {
|
||||||
return (
|
return (
|
||||||
<PatientLayout>
|
<Sidebar>
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
<div>
|
<div>
|
||||||
<h1 className="text-3xl font-bold text-gray-900">Dashboard</h1>
|
<h1 className="text-3xl font-bold text-gray-900">Dashboard</h1>
|
||||||
@ -108,6 +109,6 @@ export default function PatientDashboard() {
|
|||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</PatientLayout>
|
</Sidebar>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import { Input } from "@/components/ui/input"
|
|||||||
import { Label } from "@/components/ui/label"
|
import { Label } from "@/components/ui/label"
|
||||||
import { Textarea } from "@/components/ui/textarea"
|
import { Textarea } from "@/components/ui/textarea"
|
||||||
import { User, Mail, Phone, Calendar, FileText } from "lucide-react"
|
import { User, Mail, Phone, Calendar, FileText } from "lucide-react"
|
||||||
|
import Sidebar from "@/components/Sidebar"
|
||||||
|
|
||||||
interface PatientData {
|
interface PatientData {
|
||||||
name: string
|
name: string
|
||||||
@ -50,7 +51,7 @@ export default function PatientProfile() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PatientLayout>
|
<Sidebar>
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
<div className="flex justify-between items-center">
|
<div className="flex justify-between items-center">
|
||||||
<div>
|
<div>
|
||||||
@ -217,6 +218,6 @@ export default function PatientProfile() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</PatientLayout>
|
</Sidebar>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,13 +1,13 @@
|
|||||||
"use client"
|
"use client"
|
||||||
|
|
||||||
import { useState, useEffect } from "react"
|
import { useState, useEffect } from "react"
|
||||||
import PatientLayout from "@/components/patient-layout"
|
|
||||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card"
|
||||||
import { Badge } from "@/components/ui/badge"
|
import { Badge } from "@/components/ui/badge"
|
||||||
import { Button } from "@/components/ui/button"
|
import { Button } from "@/components/ui/button"
|
||||||
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "@/components/ui/dialog"
|
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "@/components/ui/dialog"
|
||||||
import { toast } from "@/hooks/use-toast"
|
import { toast } from "@/hooks/use-toast"
|
||||||
import { FileText, Download, Eye, Calendar, User, X } from "lucide-react"
|
import { FileText, Download, Eye, Calendar, User, X } from "lucide-react"
|
||||||
|
import Sidebar from "@/components/Sidebar"
|
||||||
|
|
||||||
interface Report {
|
interface Report {
|
||||||
id: string
|
id: string
|
||||||
@ -287,7 +287,7 @@ export default function ReportsPage() {
|
|||||||
const pendingReports = reports.filter((report) => report.status === "pendente")
|
const pendingReports = reports.filter((report) => report.status === "pendente")
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PatientLayout>
|
<Sidebar>
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
<div>
|
<div>
|
||||||
<h1 className="text-3xl font-bold text-gray-900">Meus Laudos</h1>
|
<h1 className="text-3xl font-bold text-gray-900">Meus Laudos</h1>
|
||||||
@ -536,6 +536,6 @@ export default function ReportsPage() {
|
|||||||
</DialogContent>
|
</DialogContent>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
</div>
|
</div>
|
||||||
</PatientLayout>
|
</Sidebar>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -8,8 +8,7 @@ import { Calendar as CalendarShadcn } from "@/components/ui/calendar";
|
|||||||
import { format, addDays } from "date-fns";
|
import { format, addDays } from "date-fns";
|
||||||
|
|
||||||
import { useState, useEffect, useCallback, useRef } from "react";
|
import { useState, useEffect, useCallback, useRef } from "react";
|
||||||
import { Calendar, Clock, User, StickyNote } from "lucide-react";
|
import { Calendar, User, StickyNote } from "lucide-react";
|
||||||
import PatientLayout from "@/components/patient-layout";
|
|
||||||
import {
|
import {
|
||||||
Card,
|
Card,
|
||||||
CardContent,
|
CardContent,
|
||||||
@ -27,6 +26,7 @@ import {
|
|||||||
} from "@/components/ui/select";
|
} from "@/components/ui/select";
|
||||||
import { Textarea } from "@/components/ui/textarea";
|
import { Textarea } from "@/components/ui/textarea";
|
||||||
import { toast } from "@/hooks/use-toast";
|
import { toast } from "@/hooks/use-toast";
|
||||||
|
import Sidebar from "@/components/Sidebar";
|
||||||
|
|
||||||
|
|
||||||
interface Doctor {
|
interface Doctor {
|
||||||
@ -363,7 +363,7 @@ export default function ScheduleAppointment() {
|
|||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<PatientLayout>
|
<Sidebar>
|
||||||
<div className="max-w-6xl mx-auto space-y-4 px-4">
|
<div className="max-w-6xl mx-auto space-y-4 px-4">
|
||||||
<h1 className="text-2xl font-semibold">Agendar Consulta</h1>
|
<h1 className="text-2xl font-semibold">Agendar Consulta</h1>
|
||||||
|
|
||||||
@ -550,6 +550,6 @@ export default function ScheduleAppointment() {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</PatientLayout>
|
</Sidebar>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,20 +1,17 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import SecretaryLayout from "@/components/secretary-layout";
|
|
||||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Badge } from "@/components/ui/badge";
|
import { Badge } from "@/components/ui/badge";
|
||||||
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog";
|
import { Dialog } from "@/components/ui/dialog";
|
||||||
import { Input } from "@/components/ui/input";
|
|
||||||
import { Label } from "@/components/ui/label";
|
|
||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
|
||||||
import { Calendar, Clock, MapPin, Phone, User, Trash2, Pencil } from "lucide-react";
|
import { Calendar, Clock, MapPin, Phone, User, Trash2, Pencil } from "lucide-react";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { appointmentsService } from "@/services/appointmentsApi.mjs";
|
import { appointmentsService } from "@/services/appointmentsApi.mjs";
|
||||||
import { patientsService } from "@/services/patientsApi.mjs";
|
import { patientsService } from "@/services/patientsApi.mjs";
|
||||||
import { doctorsService } from "@/services/doctorsApi.mjs";
|
import { doctorsService } from "@/services/doctorsApi.mjs";
|
||||||
|
import Sidebar from "@/components/Sidebar";
|
||||||
|
|
||||||
export default function SecretaryAppointments() {
|
export default function SecretaryAppointments() {
|
||||||
const [appointments, setAppointments] = useState<any[]>([]);
|
const [appointments, setAppointments] = useState<any[]>([]);
|
||||||
@ -144,7 +141,7 @@ export default function SecretaryAppointments() {
|
|||||||
const appointmentStatuses = ["requested", "confirmed", "checked_in", "completed", "cancelled", "no_show"];
|
const appointmentStatuses = ["requested", "confirmed", "checked_in", "completed", "cancelled", "no_show"];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SecretaryLayout>
|
<Sidebar>
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
<div className="flex justify-between items-center">
|
<div className="flex justify-between items-center">
|
||||||
<div>
|
<div>
|
||||||
@ -225,6 +222,6 @@ export default function SecretaryAppointments() {
|
|||||||
<Dialog open={deleteModal} onOpenChange={setDeleteModal}>
|
<Dialog open={deleteModal} onOpenChange={setDeleteModal}>
|
||||||
{/* ... (código do modal de deleção) ... */}
|
{/* ... (código do modal de deleção) ... */}
|
||||||
</Dialog>
|
</Dialog>
|
||||||
</SecretaryLayout>
|
</Sidebar>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -1,10 +1,6 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import SecretaryLayout from "@/components/secretary-layout";
|
import { Card, CardContent, CardDescription,
|
||||||
import {
|
|
||||||
Card,
|
|
||||||
CardContent,
|
|
||||||
CardDescription,
|
|
||||||
CardHeader,
|
CardHeader,
|
||||||
CardTitle,
|
CardTitle,
|
||||||
} from "@/components/ui/card";
|
} from "@/components/ui/card";
|
||||||
@ -14,6 +10,7 @@ import Link from "next/link";
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import { patientsService } from "@/services/patientsApi.mjs";
|
import { patientsService } from "@/services/patientsApi.mjs";
|
||||||
import { appointmentsService } from "@/services/appointmentsApi.mjs";
|
import { appointmentsService } from "@/services/appointmentsApi.mjs";
|
||||||
|
import Sidebar from "@/components/Sidebar";
|
||||||
|
|
||||||
export default function SecretaryDashboard() {
|
export default function SecretaryDashboard() {
|
||||||
// Estados
|
// Estados
|
||||||
@ -100,7 +97,7 @@ export default function SecretaryDashboard() {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SecretaryLayout>
|
<Sidebar>
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
{/* Cabeçalho */}
|
{/* Cabeçalho */}
|
||||||
<div>
|
<div>
|
||||||
@ -299,6 +296,6 @@ export default function SecretaryDashboard() {
|
|||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</SecretaryLayout>
|
</Sidebar>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -13,9 +13,8 @@ import { Checkbox } from "@/components/ui/checkbox";
|
|||||||
import { ArrowLeft, Save, Trash2, Paperclip, Upload } from "lucide-react";
|
import { ArrowLeft, Save, Trash2, Paperclip, Upload } from "lucide-react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { useToast } from "@/hooks/use-toast";
|
import { useToast } from "@/hooks/use-toast";
|
||||||
import SecretaryLayout from "@/components/secretary-layout";
|
|
||||||
import { patientsService } from "@/services/patientsApi.mjs";
|
import { patientsService } from "@/services/patientsApi.mjs";
|
||||||
import { json } from "stream/consumers";
|
import Sidebar from "@/components/Sidebar";
|
||||||
|
|
||||||
export default function EditarPacientePage() {
|
export default function EditarPacientePage() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -247,7 +246,7 @@ export default function EditarPacientePage() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SecretaryLayout>
|
<Sidebar>
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
<div className="flex items-center gap-4">
|
<div className="flex items-center gap-4">
|
||||||
<Link href="/secretary/pacientes">
|
<Link href="/secretary/pacientes">
|
||||||
@ -677,6 +676,6 @@ export default function EditarPacientePage() {
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</SecretaryLayout>
|
</Sidebar>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
// Caminho: app/(manager)/usuario/novo/page.tsx
|
|
||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
@ -7,13 +6,9 @@ import Link from "next/link";
|
|||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
import { Label } from "@/components/ui/label";
|
import { Label } from "@/components/ui/label";
|
||||||
// O Select foi removido pois não é mais necessário
|
|
||||||
import { Save, Loader2 } from "lucide-react";
|
import { Save, Loader2 } from "lucide-react";
|
||||||
import ManagerLayout from "@/components/manager-layout";
|
|
||||||
// Os imports originais foram mantidos, como solicitado
|
|
||||||
import { usersService } from "services/usersApi.mjs";
|
import { usersService } from "services/usersApi.mjs";
|
||||||
import { doctorsService } from "services/doctorsApi.mjs";
|
import Sidebar from "@/components/Sidebar";
|
||||||
import { login } from "services/api.mjs";
|
|
||||||
|
|
||||||
// Interface simplificada para refletir apenas os campos necessários
|
// Interface simplificada para refletir apenas os campos necessários
|
||||||
interface UserFormData {
|
interface UserFormData {
|
||||||
@ -97,7 +92,7 @@ export default function NovoUsuarioPage() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ManagerLayout>
|
<Sidebar>
|
||||||
<div className="w-full h-full p-4 md:p-8 flex justify-center items-start">
|
<div className="w-full h-full p-4 md:p-8 flex justify-center items-start">
|
||||||
<div className="w-full max-w-screen-lg space-y-8">
|
<div className="w-full max-w-screen-lg space-y-8">
|
||||||
<div className="flex items-center justify-between border-b pb-4">
|
<div className="flex items-center justify-between border-b pb-4">
|
||||||
@ -167,6 +162,6 @@ export default function NovoUsuarioPage() {
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ManagerLayout>
|
</Sidebar>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -8,8 +8,8 @@ import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigge
|
|||||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||||
import { Plus, Edit, Trash2, Eye, Calendar, Filter, Loader2 } from "lucide-react";
|
import { Plus, Edit, Trash2, Eye, Calendar, Filter, Loader2 } from "lucide-react";
|
||||||
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from "@/components/ui/alert-dialog";
|
import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from "@/components/ui/alert-dialog";
|
||||||
import SecretaryLayout from "@/components/secretary-layout";
|
|
||||||
import { patientsService } from "@/services/patientsApi.mjs";
|
import { patientsService } from "@/services/patientsApi.mjs";
|
||||||
|
import Sidebar from "@/components/Sidebar";
|
||||||
|
|
||||||
// Defina o tamanho da página.
|
// Defina o tamanho da página.
|
||||||
const PAGE_SIZE = 5;
|
const PAGE_SIZE = 5;
|
||||||
@ -145,7 +145,7 @@ export default function PacientesPage() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<SecretaryLayout>
|
<Sidebar>
|
||||||
<div className="space-y-6 px-2 sm:px-4 md:px-8">
|
<div className="space-y-6 px-2 sm:px-4 md:px-8">
|
||||||
{/* Header (Responsividade OK) */}
|
{/* Header (Responsividade OK) */}
|
||||||
<div className="flex flex-col md:flex-row md:items-center md:justify-between gap-4">
|
<div className="flex flex-col md:flex-row md:items-center md:justify-between gap-4">
|
||||||
@ -457,6 +457,6 @@ export default function PacientesPage() {
|
|||||||
</AlertDialogContent>
|
</AlertDialogContent>
|
||||||
</AlertDialog>
|
</AlertDialog>
|
||||||
</div>
|
</div>
|
||||||
</SecretaryLayout>
|
</Sidebar>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -2,7 +2,6 @@
|
|||||||
import type React from "react";
|
import type React from "react";
|
||||||
import { useState, useEffect } from "react";
|
import { useState, useEffect } from "react";
|
||||||
import { useRouter } from "next/navigation";
|
import { useRouter } from "next/navigation";
|
||||||
import SecretaryLayout from "@/components/secretary-layout";
|
|
||||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
@ -15,6 +14,7 @@ import { doctorsService } from "@/services/doctorsApi.mjs";
|
|||||||
import { appointmentsService } from "@/services/appointmentsApi.mjs";
|
import { appointmentsService } from "@/services/appointmentsApi.mjs";
|
||||||
import { usersService } from "@/services/usersApi.mjs";
|
import { usersService } from "@/services/usersApi.mjs";
|
||||||
import { toast } from "sonner"; // Para notificações
|
import { toast } from "sonner"; // Para notificações
|
||||||
|
import Sidebar from "@/components/Sidebar";
|
||||||
|
|
||||||
export default function ScheduleAppointment() {
|
export default function ScheduleAppointment() {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@ -153,7 +153,7 @@ export default function ScheduleAppointment() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<SecretaryLayout>
|
<Sidebar>
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
<div>
|
<div>
|
||||||
<h1 className="text-3xl font-bold text-gray-900">Agendar Consulta</h1>
|
<h1 className="text-3xl font-bold text-gray-900">Agendar Consulta</h1>
|
||||||
@ -350,6 +350,6 @@ export default function ScheduleAppointment() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</SecretaryLayout>
|
</Sidebar>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
320
components/Sidebar.tsx
Normal file
320
components/Sidebar.tsx
Normal file
@ -0,0 +1,320 @@
|
|||||||
|
// Caminho: [seu-caminho]/ManagerLayout.tsx
|
||||||
|
"use client";
|
||||||
|
|
||||||
|
import type React from "react";
|
||||||
|
import { useState, useEffect } from "react";
|
||||||
|
import { useRouter, usePathname } from "next/navigation";
|
||||||
|
import Link from "next/link";
|
||||||
|
import Cookies from "js-cookie"; // Mantido apenas para a limpeza de segurança no logout
|
||||||
|
import { api } from "@/services/api.mjs";
|
||||||
|
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { Input } from "@/components/ui/input";
|
||||||
|
import { Badge } from "@/components/ui/badge";
|
||||||
|
import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
|
||||||
|
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from "@/components/ui/dialog";
|
||||||
|
import { Search, Bell, Calendar, User, LogOut, ChevronLeft, ChevronRight, Home } from "lucide-react";
|
||||||
|
import SidebarUserSection from "@/components/ui/userToolTip";
|
||||||
|
|
||||||
|
interface UserData {
|
||||||
|
id: string;
|
||||||
|
email: string;
|
||||||
|
app_metadata: {
|
||||||
|
user_role: string;
|
||||||
|
};
|
||||||
|
user_metadata: {
|
||||||
|
cpf: string;
|
||||||
|
email_verified: boolean;
|
||||||
|
full_name: string;
|
||||||
|
phone_mobile: string;
|
||||||
|
role: string;
|
||||||
|
};
|
||||||
|
identities: {
|
||||||
|
identity_id: string;
|
||||||
|
id: string;
|
||||||
|
user_id: string;
|
||||||
|
provider: string;
|
||||||
|
}[];
|
||||||
|
is_anonymous: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
interface MenuItem {
|
||||||
|
href: string;
|
||||||
|
icon: React.ElementType;
|
||||||
|
label: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
type Role = "manager" | "doctor" | "secretary" | "patient" | "admin";
|
||||||
|
|
||||||
|
interface SidebarProps {
|
||||||
|
children: React.ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function Sidebar({ children }: SidebarProps) {
|
||||||
|
const [userData, setUserData] = useState<UserData>();
|
||||||
|
const [role, setRole] = useState<string>();
|
||||||
|
const [sidebarCollapsed, setSidebarCollapsed] = useState(false);
|
||||||
|
const [showLogoutDialog, setShowLogoutDialog] = useState(false);
|
||||||
|
const router = useRouter();
|
||||||
|
const pathname = usePathname();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const userInfoString = localStorage.getItem("user_info");
|
||||||
|
// --- ALTERAÇÃO 1: Buscando o token no localStorage ---
|
||||||
|
const token = localStorage.getItem("token");
|
||||||
|
|
||||||
|
if (userInfoString && token) {
|
||||||
|
const userInfo = JSON.parse(userInfoString);
|
||||||
|
|
||||||
|
setUserData({
|
||||||
|
id: userInfo.id ?? "",
|
||||||
|
email: userInfo.email ?? "",
|
||||||
|
app_metadata: {
|
||||||
|
user_role: userInfo.app_metadata?.user_role ?? "patient",
|
||||||
|
},
|
||||||
|
user_metadata: {
|
||||||
|
cpf: userInfo.user_metadata?.cpf ?? "",
|
||||||
|
email_verified: userInfo.user_metadata?.email_verified ?? false,
|
||||||
|
full_name: userInfo.user_metadata?.full_name ?? "",
|
||||||
|
phone_mobile: userInfo.user_metadata?.phone_mobile ?? "",
|
||||||
|
role: userInfo.user_metadata?.role ?? "",
|
||||||
|
},
|
||||||
|
identities:
|
||||||
|
userInfo.identities?.map((identity: any) => ({
|
||||||
|
identity_id: identity.identity_id ?? "",
|
||||||
|
id: identity.id ?? "",
|
||||||
|
user_id: identity.user_id ?? "",
|
||||||
|
provider: identity.provider ?? "",
|
||||||
|
})) ?? [],
|
||||||
|
is_anonymous: userInfo.is_anonymous ?? false,
|
||||||
|
});
|
||||||
|
setRole(userInfo.user_metadata?.role)
|
||||||
|
} else {
|
||||||
|
// O redirecionamento para /login já estava correto. Ótimo!
|
||||||
|
router.push("/login");
|
||||||
|
}
|
||||||
|
}, [router]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
|
||||||
|
|
||||||
|
const handleResize = () => {
|
||||||
|
if (window.innerWidth < 1024) {
|
||||||
|
setSidebarCollapsed(true);
|
||||||
|
} else {
|
||||||
|
setSidebarCollapsed(false);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
handleResize();
|
||||||
|
window.addEventListener("resize", handleResize);
|
||||||
|
return () => window.removeEventListener("resize", handleResize);
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const handleLogout = () => setShowLogoutDialog(true);
|
||||||
|
|
||||||
|
// --- ALTERAÇÃO 2: A função de logout agora é MUITO mais simples ---
|
||||||
|
const confirmLogout = async () => {
|
||||||
|
try {
|
||||||
|
// Chama a função centralizada para fazer o logout no servidor
|
||||||
|
await api.logout();
|
||||||
|
} catch (error) {
|
||||||
|
// O erro já é logado dentro da função api.logout, não precisamos fazer nada aqui
|
||||||
|
} finally {
|
||||||
|
// A responsabilidade do componente é apenas limpar o estado local e redirecionar
|
||||||
|
localStorage.removeItem("user_info");
|
||||||
|
localStorage.removeItem("token");
|
||||||
|
Cookies.remove("access_token"); // Limpeza de segurança
|
||||||
|
|
||||||
|
setShowLogoutDialog(false);
|
||||||
|
router.push("/"); // Redireciona para a home
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const cancelLogout = () => setShowLogoutDialog(false);
|
||||||
|
|
||||||
|
const SetMenuItems = (role: any) => {
|
||||||
|
const patientItems: MenuItem[] = [
|
||||||
|
{ href: "/patient/dashboard", icon: Home, label: "Dashboard" },
|
||||||
|
{ href: "/patient/schedule", icon: Home, label: "Agendar Consulta" },
|
||||||
|
{ href: "/patient/appointments", icon: Home, label: "Minhas Consultas" },
|
||||||
|
{ href: "/patient/reports", icon: Home, label: "Meus Laudos" },
|
||||||
|
{ href: "/patient/profile", icon: Home, label: "Meus Dados" },
|
||||||
|
]
|
||||||
|
|
||||||
|
const doctorItems: MenuItem[] = [
|
||||||
|
{ href: "/doctor/dashboard", icon: Home, label: "Dashboard" },
|
||||||
|
{ href: "/doctor/medicos", icon: User, label: "Gestão de Pacientes" },
|
||||||
|
{ href: "/doctor/consultas", icon: Calendar, label: "Consultas" },
|
||||||
|
{ href: "/doctor/disponibilidade", icon: User, label: "Disponibilidade" },
|
||||||
|
]
|
||||||
|
|
||||||
|
const secretaryItems: MenuItem[] = [
|
||||||
|
{ href: "/secretary/dashboard", icon: Home, label: "Dashboard" },
|
||||||
|
{ href: "/secretary/appointments", icon: Calendar, label: "Consultas" },
|
||||||
|
{ href: "/secretary/schedule", icon: Calendar, label: "Agendar Consulta" },
|
||||||
|
{ href: "/secretary/pacientes", icon: User, label: "Gestão de Pacientes" },
|
||||||
|
]
|
||||||
|
|
||||||
|
const managerItems: MenuItem[] = [
|
||||||
|
{ href: "/manager/dashboard", icon: Home, label: "Dashboard" },
|
||||||
|
{ href: "#", icon: Calendar, label: "Relatórios gerenciais" },
|
||||||
|
{ href: "/manager/usuario", icon: User, label: "Gestão de Usuários" },
|
||||||
|
{ href: "/manager/home", icon: User, label: "Gestão de Médicos" },
|
||||||
|
{ href: "/manager/pacientes", icon: User, label: "Gestão de Pacientes" },
|
||||||
|
{ href: "/doctor/consultas", icon: Calendar, label: "Consultas" }, //adicionar botão de voltar pra pagina anterior
|
||||||
|
]
|
||||||
|
|
||||||
|
let menuItems: MenuItem[];
|
||||||
|
switch (role) {
|
||||||
|
case "manager":
|
||||||
|
menuItems = managerItems;
|
||||||
|
break;
|
||||||
|
case "admin":
|
||||||
|
menuItems = managerItems;
|
||||||
|
break;
|
||||||
|
case "doctor":
|
||||||
|
menuItems = doctorItems;
|
||||||
|
break;
|
||||||
|
case "secretary":
|
||||||
|
menuItems = secretaryItems;
|
||||||
|
break;
|
||||||
|
case "patient":
|
||||||
|
menuItems = patientItems;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
menuItems = patientItems;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return menuItems;
|
||||||
|
}
|
||||||
|
|
||||||
|
const menuItems = SetMenuItems(role)
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
const menuItems = [
|
||||||
|
{ href: "/manager/dashboard", icon: Home, label: "Dashboard" },
|
||||||
|
{ href: "#", icon: Calendar, label: "Relatórios gerenciais" },
|
||||||
|
{ href: "/manager/usuario", icon: User, label: "Gestão de Usuários" },
|
||||||
|
{ href: "/manager/home", icon: User, label: "Gestão de Médicos" },
|
||||||
|
{ href: "/manager/pacientes", icon: User, label: "Gestão de Pacientes" },
|
||||||
|
{ href: "#", icon: User, label: "Disponibilidade" },
|
||||||
|
{ href: "#", icon: Calendar, label: "Consultas" },
|
||||||
|
{ href: "#", icon: Calendar, label: "Agendar Consulta S" },
|
||||||
|
{ href: "#", icon: Home, label: "Agendar Consulta P" },
|
||||||
|
{ href: "#", icon: Home, label: "Minhas Consultas" },
|
||||||
|
{ href: "#", icon: Home, label: "Meus Laudos" },
|
||||||
|
{ href: "#", icon: Home, label: "Meus Dados" },
|
||||||
|
]; */
|
||||||
|
|
||||||
|
if (!userData) {
|
||||||
|
return (
|
||||||
|
<div className="flex h-screen w-full items-center justify-center">
|
||||||
|
Carregando...
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="min-h-screen bg-gray-50 flex">
|
||||||
|
<div
|
||||||
|
className={`bg-white border-r border-gray-200 transition-all duration-300 fixed top-0 h-screen flex flex-col z-30 ${
|
||||||
|
sidebarCollapsed ? "w-16" : "w-64"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<div className="p-4 border-b border-gray-200 flex items-center justify-between">
|
||||||
|
{!sidebarCollapsed && (
|
||||||
|
<div className="flex items-center gap-2">
|
||||||
|
<div className="w-8 h-8 bg-blue-600 rounded-lg flex items-center justify-center">
|
||||||
|
<div className="w-4 h-4 bg-white rounded-sm"></div>
|
||||||
|
</div>
|
||||||
|
<span className="font-semibold text-gray-900">MedConnect</span>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<Button
|
||||||
|
variant="ghost"
|
||||||
|
size="sm"
|
||||||
|
onClick={() => setSidebarCollapsed(!sidebarCollapsed)}
|
||||||
|
className="p-1"
|
||||||
|
>
|
||||||
|
{sidebarCollapsed ? (
|
||||||
|
<ChevronRight className="w-4 h-4" />
|
||||||
|
) : (
|
||||||
|
<ChevronLeft className="w-4 h-4" />
|
||||||
|
)}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<nav className="flex-1 p-2 overflow-y-auto">
|
||||||
|
{menuItems.map((item) => {
|
||||||
|
const Icon = item.icon;
|
||||||
|
const isActive = pathname === item.href;
|
||||||
|
return (
|
||||||
|
<Link key={item.label} href={item.href}>
|
||||||
|
<div
|
||||||
|
className={`flex items-center gap-3 px-3 py-2 rounded-lg mb-1 transition-colors ${
|
||||||
|
isActive
|
||||||
|
? "bg-blue-50 text-blue-600 border-r-2 border-blue-600"
|
||||||
|
: "text-gray-600 hover:bg-gray-50"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<Icon className="w-5 h-5 flex-shrink-0" />
|
||||||
|
{!sidebarCollapsed && (
|
||||||
|
<span className="font-medium">{item.label}</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</nav>
|
||||||
|
<SidebarUserSection
|
||||||
|
userData={userData}
|
||||||
|
sidebarCollapsed={false}
|
||||||
|
handleLogout={handleLogout}
|
||||||
|
isActive={role === "patient"? false: true}>
|
||||||
|
</SidebarUserSection>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
className={`flex-1 flex flex-col transition-all duration-300 w-full ${
|
||||||
|
sidebarCollapsed ? "ml-16" : "ml-64"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<header className="bg-white border-b border-gray-200 px-4 md:px-6 py-4 flex items-center justify-between">
|
||||||
|
<div className="flex items-center gap-4 flex-1 max-w-md"></div>
|
||||||
|
<div className="flex items-center gap-4 ml-auto">
|
||||||
|
<Button variant="ghost" size="sm" className="relative">
|
||||||
|
<Bell className="w-5 h-5" />
|
||||||
|
<Badge className="absolute -top-1 -right-1 w-5 h-5 p-0 flex items-center justify-center bg-red-500 text-white text-xs">
|
||||||
|
1
|
||||||
|
</Badge>
|
||||||
|
</Button> {/* tira essas divs e muda o header para bg-gray-50 */}
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
<main className="flex-1 p-4 md:p-6">{children}</main>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Dialog open={showLogoutDialog} onOpenChange={setShowLogoutDialog}>
|
||||||
|
<DialogContent className="sm:max-w-md">
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle>Confirmar Saída</DialogTitle>
|
||||||
|
<DialogDescription>
|
||||||
|
Deseja realmente sair do sistema? Você precisará fazer login
|
||||||
|
novamente para acessar sua conta.
|
||||||
|
</DialogDescription>
|
||||||
|
</DialogHeader>
|
||||||
|
<DialogFooter className="flex gap-2">
|
||||||
|
<Button variant="outline" onClick={cancelLogout}>
|
||||||
|
Cancelar
|
||||||
|
</Button>
|
||||||
|
<Button variant="destructive" onClick={confirmLogout}>
|
||||||
|
<LogOut className="mr-2 h-4 w-4" />
|
||||||
|
Sair
|
||||||
|
</Button>
|
||||||
|
</DialogFooter>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
125
components/ui/userToolTip.tsx
Normal file
125
components/ui/userToolTip.tsx
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
"use client";
|
||||||
|
|
||||||
|
import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar";
|
||||||
|
import { Button } from "@/components/ui/button";
|
||||||
|
import { Home, LogOut } from "lucide-react";
|
||||||
|
import {
|
||||||
|
Popover,
|
||||||
|
PopoverTrigger,
|
||||||
|
PopoverContent,
|
||||||
|
} from "@/components/ui/popover";
|
||||||
|
import { usePathname } from "next/navigation";
|
||||||
|
import Link from "next/link";
|
||||||
|
|
||||||
|
interface UserData {
|
||||||
|
user_metadata: {
|
||||||
|
full_name: string;
|
||||||
|
};
|
||||||
|
app_metadata: {
|
||||||
|
user_role: string;
|
||||||
|
};
|
||||||
|
email: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
userData: UserData;
|
||||||
|
sidebarCollapsed: boolean;
|
||||||
|
handleLogout: () => void;
|
||||||
|
isActive: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function SidebarUserSection({
|
||||||
|
userData,
|
||||||
|
sidebarCollapsed,
|
||||||
|
handleLogout,
|
||||||
|
isActive,
|
||||||
|
}: Props) {
|
||||||
|
const pathname = usePathname();
|
||||||
|
const menuItems: any[] = [
|
||||||
|
{ href: "/patient/schedule", icon: Home, label: "Agendar Consulta" },
|
||||||
|
{ href: "/patient/appointments", icon: Home, label: "Minhas Consultas" },
|
||||||
|
{ href: "/patient/reports", icon: Home, label: "Meus Laudos" },
|
||||||
|
{ href: "/patient/profile", icon: Home, label: "Meus Dados" },
|
||||||
|
]
|
||||||
|
return (
|
||||||
|
<div className="border-t p-4 mt-auto">
|
||||||
|
{/* POPUP DE INFORMAÇÕES DO USUÁRIO */}
|
||||||
|
<Popover>
|
||||||
|
<PopoverTrigger asChild>
|
||||||
|
<div
|
||||||
|
className={`flex items-center space-x-3 mb-4 p-2 rounded-md transition-colors ${
|
||||||
|
isActive
|
||||||
|
? "cursor-pointer hover:bg-gray-100"
|
||||||
|
: "cursor-default pointer-events-none"
|
||||||
|
}`}>
|
||||||
|
<Avatar>
|
||||||
|
<AvatarImage src="/placeholder.svg?height=40&width=40" />
|
||||||
|
<AvatarFallback>
|
||||||
|
{userData.user_metadata.full_name
|
||||||
|
.split(" ")
|
||||||
|
.map((n) => n[0])
|
||||||
|
.join("")}
|
||||||
|
</AvatarFallback>
|
||||||
|
</Avatar>
|
||||||
|
|
||||||
|
{!sidebarCollapsed && (
|
||||||
|
<div className="flex-1 min-w-0">
|
||||||
|
<p className="text-sm font-medium text-gray-900 truncate">
|
||||||
|
{userData.user_metadata.full_name}
|
||||||
|
</p>
|
||||||
|
<p className="text-xs text-gray-500 truncate">
|
||||||
|
{userData.app_metadata.user_role}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</PopoverTrigger>
|
||||||
|
|
||||||
|
{/* Card flutuante */}
|
||||||
|
<PopoverContent
|
||||||
|
align="center"
|
||||||
|
side="top"
|
||||||
|
className="w-64 p-4 shadow-lg border bg-white"
|
||||||
|
>
|
||||||
|
<nav>
|
||||||
|
{menuItems.map((item) => {
|
||||||
|
const Icon = item.icon;
|
||||||
|
const isActive = pathname === item.href;
|
||||||
|
return (
|
||||||
|
<Link key={item.label} href={item.href}>
|
||||||
|
<div
|
||||||
|
className={`flex items-center gap-3 px-3 py-2 rounded-lg mb-1 transition-colors ${
|
||||||
|
isActive
|
||||||
|
? "bg-blue-50 text-blue-600 border-r-2 border-blue-600"
|
||||||
|
: "text-gray-600 hover:bg-gray-50"
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<Icon className="w-5 h-5 flex-shrink-0" />
|
||||||
|
{!sidebarCollapsed && (
|
||||||
|
<span className="font-medium">{item.label}</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</nav>
|
||||||
|
</PopoverContent>
|
||||||
|
</Popover>
|
||||||
|
|
||||||
|
{/* Botão de sair */}
|
||||||
|
<Button
|
||||||
|
variant="outline"
|
||||||
|
size="sm"
|
||||||
|
className={
|
||||||
|
sidebarCollapsed
|
||||||
|
? "w-full bg-transparent flex justify-center items-center p-2"
|
||||||
|
: "w-full bg-transparent"
|
||||||
|
}
|
||||||
|
onClick={handleLogout}
|
||||||
|
>
|
||||||
|
<LogOut className={sidebarCollapsed ? "h-5 w-5" : "mr-2 h-4 w-4"} />
|
||||||
|
{!sidebarCollapsed && "Sair"}
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user