import { useEffect, useMemo, useState } from "react";
import { toast } from "sonner";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faGithub, faGitlab } from "@fortawesome/free-brands-svg-icons";
import { faCodeBranch, faPen, faPlus, faTrash } from "@fortawesome/free-solid-svg-icons";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "../components/ui/card";
import { Button } from "../components/ui/button";
import { Input } from "../components/ui/input";
import { Label } from "../components/ui/label";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue
} from "../components/ui/select";
import { useLiveCounter } from "../providers/live-provider";
import { createJob, deleteJob, fetchJobs, Job, JobInput, updateJob } from "../api/jobs";
type FormState = {
_id?: string;
name: string;
repoUrl: string;
testCommand: string;
checkValue: string;
checkUnit: JobInput["checkUnit"];
};
const defaultForm: FormState = {
name: "",
repoUrl: "",
testCommand: "",
checkValue: "",
checkUnit: "dakika"
};
function RepoIcon({ repoUrl }: { repoUrl: string }) {
const lower = repoUrl.toLowerCase();
if (lower.includes("github.com")) {
return ;
}
if (lower.includes("gitlab.com")) {
return ;
}
if (lower.includes("gitea")) {
return (
Ge
);
}
return ;
}
export function JobsPage() {
const { value, running } = useLiveCounter();
const [jobs, setJobs] = useState([]);
const [loading, setLoading] = useState(false);
const [modalOpen, setModalOpen] = useState(false);
const [form, setForm] = useState(defaultForm);
const [saving, setSaving] = useState(false);
const [deletingId, setDeletingId] = useState(null);
const isEdit = useMemo(() => !!form._id, [form._id]);
const loadJobs = async () => {
setLoading(true);
try {
const data = await fetchJobs();
setJobs(data);
} catch (err) {
toast.error("Jobs alınamadı");
} finally {
setLoading(false);
}
};
useEffect(() => {
loadJobs();
}, []);
const handleOpenNew = () => {
setForm(defaultForm);
setModalOpen(true);
};
const handleSave = async () => {
setSaving(true);
try {
const payload: JobInput = {
name: form.name,
repoUrl: form.repoUrl,
testCommand: form.testCommand,
checkValue: Number(form.checkValue),
checkUnit: form.checkUnit
};
if (!payload.name || !payload.repoUrl || !payload.testCommand || !payload.checkValue) {
toast.error("Tüm alanları doldurun");
setSaving(false);
return;
}
if (Number.isNaN(payload.checkValue) || payload.checkValue <= 0) {
toast.error("Check Time değeri 1 veya daha büyük olmalı");
setSaving(false);
return;
}
if (isEdit && form._id) {
const updated = await updateJob(form._id, payload);
setJobs((prev) => prev.map((j) => (j._id === updated._id ? updated : j)));
toast.success("Job güncellendi");
} else {
const created = await createJob(payload);
setJobs((prev) => [created, ...prev]);
toast.success("Job oluşturuldu");
}
setModalOpen(false);
} catch (err) {
toast.error("İşlem sırasında hata oluştu");
} finally {
setSaving(false);
}
};
const handleDelete = async (id: string) => {
setDeletingId(id);
try {
await deleteJob(id);
setJobs((prev) => prev.filter((j) => j._id !== id));
toast.success("Job silindi");
} catch (err) {
toast.error("Silme sırasında hata oluştu");
} finally {
setDeletingId(null);
}
};
const handleEdit = (job: Job) => {
const { _id, name, repoUrl, testCommand, checkValue, checkUnit } = job;
setForm({ _id, name, repoUrl, testCommand, checkValue: String(checkValue), checkUnit });
setModalOpen(true);
};
const handleClose = () => {
setModalOpen(false);
};
return (
<>
Jobs
Home sayfasında başlatılan sayaç:{" "}
{value} ({running ? "çalışıyor" : "beklemede"})
{loading && (
Jobs yükleniyor...
)}
{!loading && jobs.length === 0 && (
Henüz job yok. Sağ üstten ekleyebilirsiniz.
)}
{!loading &&
jobs.map((job) => (
{job.name}
Repo:
{job.repoUrl}
Test:
{job.testCommand}
Kontrol:
{job.checkValue} {job.checkUnit}
))}
{modalOpen && (
{isEdit ? "Job Güncelle" : "Yeni Job"}
Detayları girin, Jobs listesi canlı olarak güncellenecek.
)}
>
);
}