Files
helpdesk/frontend/src/app/(app)/tickets/new/page.tsx
T

136 lines
4.5 KiB
TypeScript

"use client";
import { useEffect, useState } from "react";
import { useRouter } from "next/navigation";
import { createTicket, getGroups, type Group } from "@/lib/api";
import Link from "next/link";
export default function NewTicketPage() {
const router = useRouter();
const [loading, setLoading] = useState(false);
const [error, setError] = useState("");
const [title, setTitle] = useState("");
const [description, setDescription] = useState("");
const [groups, setGroups] = useState<Group[]>([]);
const [groupId, setGroupId] = useState("");
useEffect(() => {
getGroups().then(setGroups).catch(() => []);
}, []);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setError("");
if (!groupId) {
setError("Debes seleccionar un departamento");
return;
}
setLoading(true);
try {
// La prioridad siempre es Media al crear: la ajusta el equipo después.
const result = await createTicket({ title, description, priority: "Medium", groupId: Number(groupId) });
router.push(`/tickets/${result.id}`);
} catch (err: unknown) {
setError(err instanceof Error ? err.message : "Error al crear el ticket");
} finally {
setLoading(false);
}
};
return (
<div>
<div className="page-header">
<div>
<Link href="/tickets" className="text-decoration-none text-muted" style={{ fontSize: "0.85rem" }}>
<i className="bi bi-arrow-left me-1"></i>Volver a tickets
</Link>
<h1 className="mt-1">Nuevo Ticket</h1>
</div>
</div>
<div className="row">
<div className="col-12">
<div className="card">
<div className="card-body p-4">
{error && (
<div className="alert alert-danger py-2" role="alert">
<i className="bi bi-exclamation-circle me-2"></i>
{error}
</div>
)}
<form onSubmit={handleSubmit}>
<div className="mb-3">
<label className="form-label fw-semibold">Asunto</label>
<input
type="text"
className="form-control"
placeholder="Describe brevemente el problema o solicitud"
value={title}
onChange={(e) => setTitle(e.target.value)}
required
autoFocus
/>
</div>
<div className="mb-3">
<label className="form-label fw-semibold">Descripción</label>
<textarea
className="form-control"
rows={6}
placeholder="Proporciona detalles sobre el problema, pasos para reproducir, etc."
value={description}
onChange={(e) => setDescription(e.target.value)}
required
></textarea>
</div>
<div className="mb-4">
<label className="form-label fw-semibold">Departamento</label>
<select
className="form-select"
value={groupId}
onChange={(e) => setGroupId(e.target.value)}
required
>
<option value="">Seleccionar departamento...</option>
{groups.map((g) => (
<option key={g.id} value={g.id}>
{g.name}
</option>
))}
</select>
</div>
<div className="d-flex gap-2">
<button
type="submit"
className="btn btn-primary px-4"
disabled={loading}
>
{loading ? (
<>
<span className="spinner-border spinner-border-sm me-2" role="status"></span>
Creando...
</>
) : (
<>
<i className="bi bi-plus-lg me-2"></i>
Crear Ticket
</>
)}
</button>
<Link href="/tickets" className="btn btn-outline-secondary">
Cancelar
</Link>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
);
}