2025-12-16 16:48:47 +00:00
|
|
|
import { type ChangeEvent, type FormEvent, useEffect, useState } from "react";
|
|
|
|
|
import toast from "react-hot-toast";
|
|
|
|
|
import api from "../Api";
|
2025-12-16 16:54:33 +00:00
|
|
|
import { HeaderActions } from "./header/HeaderActions";
|
|
|
|
|
import { HeaderBrand } from "./header/HeaderBrand";
|
|
|
|
|
import { ProfileModal } from "./header/ProfileModal";
|
|
|
|
|
import { ServerModal } from "./header/ServerModal";
|
2025-12-16 16:48:47 +00:00
|
|
|
import type { Applications, DatabaseType, ServersType } from "../types/enums";
|
|
|
|
|
import type { User } from "../types/User";
|
2025-12-16 16:54:33 +00:00
|
|
|
import type { ProfileFormState, ServerFormState } from "./header/types";
|
2025-12-16 16:34:06 +00:00
|
|
|
|
2025-12-16 16:48:47 +00:00
|
|
|
type ModalType = "addServer" | "editProfile" | null;
|
|
|
|
|
|
|
|
|
|
interface HeaderProps {
|
|
|
|
|
currentUser: User | null;
|
|
|
|
|
userError: string | null;
|
|
|
|
|
onServerCreated?: () => Promise<void> | void;
|
|
|
|
|
onProfileUpdated?: (user: User) => void;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const defaultServerForm: ServerFormState = {
|
|
|
|
|
name: "",
|
|
|
|
|
ip: "",
|
|
|
|
|
port: "",
|
|
|
|
|
user: "",
|
|
|
|
|
password: "",
|
|
|
|
|
type: "PRODUCTION",
|
|
|
|
|
application: "ASTERISK",
|
|
|
|
|
dbType: "MYSQL",
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const defaultProfileForm: ProfileFormState = {
|
|
|
|
|
firstName: "",
|
|
|
|
|
lastName: "",
|
|
|
|
|
email: "",
|
|
|
|
|
password: "",
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const serverTypeOptions: ServersType[] = ["PRODUCTION", "HOMOLOGATION", "DATABASE"];
|
|
|
|
|
const applicationOptions: Applications[] = ["ASTERISK", "HITMANAGER", "HITMANAGER_V2", "OMNIHIT", "HITPHONE"];
|
|
|
|
|
const databaseOptions: DatabaseType[] = ["MYSQL", "POSTGRESQL", "SQLSERVER", "ORACLE", "REDIS", "MONGODB", "MARIADB", "NONE"];
|
|
|
|
|
|
|
|
|
|
export const Header = ({ currentUser, userError, onServerCreated, onProfileUpdated }: HeaderProps) => {
|
2025-12-16 16:34:06 +00:00
|
|
|
const [isMenuOpen, setMenuOpen] = useState(false);
|
2025-12-16 16:48:47 +00:00
|
|
|
const [activeModal, setActiveModal] = useState<ModalType>(null);
|
|
|
|
|
const [serverForm, setServerForm] = useState<ServerFormState>(defaultServerForm);
|
|
|
|
|
const [profileForm, setProfileForm] = useState<ProfileFormState>(defaultProfileForm);
|
|
|
|
|
const [serverLoading, setServerLoading] = useState(false);
|
|
|
|
|
const [profileLoading, setProfileLoading] = useState(false);
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (currentUser) {
|
|
|
|
|
setProfileForm((prev) => ({
|
|
|
|
|
...prev,
|
|
|
|
|
firstName: currentUser.firstName ?? "",
|
|
|
|
|
lastName: currentUser.lastName ?? "",
|
|
|
|
|
email: currentUser.email ?? "",
|
|
|
|
|
}));
|
|
|
|
|
}
|
|
|
|
|
}, [currentUser]);
|
2025-12-16 16:34:06 +00:00
|
|
|
|
|
|
|
|
const toggleMenu = () => setMenuOpen((prev) => !prev);
|
2025-12-16 16:48:47 +00:00
|
|
|
const openModal = (modal: ModalType) => {
|
|
|
|
|
setMenuOpen(false);
|
|
|
|
|
setActiveModal(modal);
|
|
|
|
|
};
|
|
|
|
|
const closeModal = () => {
|
|
|
|
|
setActiveModal(null);
|
|
|
|
|
setServerForm(defaultServerForm);
|
|
|
|
|
setProfileForm((prev) => ({ ...prev, password: "" }));
|
|
|
|
|
};
|
|
|
|
|
|
2025-12-16 16:54:33 +00:00
|
|
|
const handleServerFormChange = (event: ChangeEvent<HTMLInputElement | HTMLSelectElement>) => {
|
|
|
|
|
const { name, value } = event.target;
|
2025-12-16 16:48:47 +00:00
|
|
|
setServerForm((prev) => ({ ...prev, [name]: value }));
|
|
|
|
|
};
|
|
|
|
|
|
2025-12-16 16:54:33 +00:00
|
|
|
const handleProfileFormChange = (event: ChangeEvent<HTMLInputElement>) => {
|
|
|
|
|
const { name, value } = event.target;
|
2025-12-16 16:48:47 +00:00
|
|
|
setProfileForm((prev) => ({ ...prev, [name]: value }));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleServerSubmit = async (event: FormEvent) => {
|
|
|
|
|
event.preventDefault();
|
|
|
|
|
setServerLoading(true);
|
|
|
|
|
try {
|
|
|
|
|
await api.post("/api/servers", {
|
|
|
|
|
...serverForm,
|
|
|
|
|
port: Number(serverForm.port),
|
|
|
|
|
});
|
|
|
|
|
toast.success("Servidor criado com sucesso!");
|
|
|
|
|
setServerForm(defaultServerForm);
|
|
|
|
|
setActiveModal(null);
|
|
|
|
|
if (onServerCreated) {
|
|
|
|
|
await Promise.resolve(onServerCreated());
|
|
|
|
|
}
|
|
|
|
|
} catch (err: any) {
|
|
|
|
|
const message = err?.response?.data?.message || "Falha ao criar servidor.";
|
|
|
|
|
toast.error(message);
|
|
|
|
|
} finally {
|
|
|
|
|
setServerLoading(false);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const handleProfileSubmit = async (event: FormEvent) => {
|
|
|
|
|
event.preventDefault();
|
|
|
|
|
if (!currentUser) {
|
|
|
|
|
toast.error("Usuário não identificado.");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
setProfileLoading(true);
|
|
|
|
|
try {
|
|
|
|
|
const { data } = await api.put<User>(`/api/users/${currentUser.id}`, {
|
|
|
|
|
firstName: profileForm.firstName,
|
|
|
|
|
lastName: profileForm.lastName,
|
|
|
|
|
email: profileForm.email,
|
|
|
|
|
password: profileForm.password,
|
|
|
|
|
});
|
|
|
|
|
toast.success("Perfil atualizado com sucesso!");
|
|
|
|
|
setProfileForm((prev) => ({ ...prev, password: "" }));
|
|
|
|
|
setActiveModal(null);
|
|
|
|
|
onProfileUpdated?.(data);
|
|
|
|
|
} catch (err: any) {
|
|
|
|
|
const message = err?.response?.data?.message || "Falha ao atualizar o perfil.";
|
|
|
|
|
toast.error(message);
|
|
|
|
|
} finally {
|
|
|
|
|
setProfileLoading(false);
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
2025-12-16 16:34:06 +00:00
|
|
|
return (
|
2025-12-16 16:48:47 +00:00
|
|
|
<>
|
|
|
|
|
<header className={Styles.wrapper}>
|
2025-12-16 16:54:33 +00:00
|
|
|
<HeaderBrand />
|
|
|
|
|
<HeaderActions
|
|
|
|
|
isMenuOpen={isMenuOpen}
|
|
|
|
|
onToggleMenu={toggleMenu}
|
|
|
|
|
onAddServer={() => openModal("addServer")}
|
|
|
|
|
onEditProfile={() => openModal("editProfile")}
|
|
|
|
|
/>
|
2025-12-16 16:48:47 +00:00
|
|
|
</header>
|
|
|
|
|
|
2025-12-16 16:54:33 +00:00
|
|
|
<ServerModal
|
|
|
|
|
isOpen={activeModal === "addServer"}
|
|
|
|
|
form={serverForm}
|
|
|
|
|
loading={serverLoading}
|
|
|
|
|
onClose={closeModal}
|
|
|
|
|
onChange={handleServerFormChange}
|
|
|
|
|
onSubmit={handleServerSubmit}
|
|
|
|
|
serverTypeOptions={serverTypeOptions}
|
|
|
|
|
applicationOptions={applicationOptions}
|
|
|
|
|
databaseOptions={databaseOptions}
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
<ProfileModal
|
|
|
|
|
isOpen={activeModal === "editProfile"}
|
|
|
|
|
currentUser={currentUser}
|
|
|
|
|
userError={userError}
|
|
|
|
|
form={profileForm}
|
|
|
|
|
loading={profileLoading}
|
|
|
|
|
onClose={closeModal}
|
|
|
|
|
onChange={handleProfileFormChange}
|
|
|
|
|
onSubmit={handleProfileSubmit}
|
|
|
|
|
/>
|
2025-12-16 16:48:47 +00:00
|
|
|
</>
|
2025-12-16 16:34:06 +00:00
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
const Styles = {
|
|
|
|
|
wrapper: "flex items-center justify-between rounded-xl border border-cardBorder bg-card px-6 py-4 shadow-sm",
|
|
|
|
|
};
|