Files
screenclipper/apps/frontend/app/page.tsx
T
ayrisdevandClaude Sonnet 5 19fe430549 frontend: kanal detay sayfası (canlı durum + poll hatası + yayın geçmişi)
/channels/[id] rotası eklendi: dashboard'daki kanal adı artık oraya
link veriyor. Sayfa api-daemon'un /status'undan canlı durum ve son
poll hatasını (lastPollError, DB'de değil sadece bellekte tutuluyordu)
çekiyor, Prisma'dan da o kanala ait tüm StreamSession/RawSegment/
CandidateSegment geçmişini transkript önizlemesiyle listeliyor.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-30 17:34:15 +03:00

83 lines
2.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import Link from "next/link";
import { prisma } from "@streamclipper/db";
import { addChannel } from "./actions";
import { fetchChannelStatuses } from "../lib/apiDaemon";
export const dynamic = "force-dynamic";
export default async function DashboardPage() {
const [channels, statuses] = await Promise.all([
prisma.channel.findMany({
orderBy: { name: "asc" },
include: {
sessions: {
where: { endedAt: null },
orderBy: { startedAt: "desc" },
take: 1,
},
},
}),
fetchChannelStatuses(),
]);
return (
<>
<h1>Kanal Durumu</h1>
<form action={addChannel} className="card add-channel-form">
<input name="name" placeholder="Kanal adı" required />
<input name="youtubeHandle" placeholder="@handle" required />
<input name="channelId" placeholder="channel_id (UC...)" required />
<button type="submit">Kanal Ekle</button>
</form>
{channels.length === 0 ? (
<p className="empty">Henüz kanal eklenmedi.</p>
) : (
<table>
<thead>
<tr>
<th>Kanal</th>
<th>Durum</th>
<th>Kayıt</th>
<th>Son Kontrol</th>
</tr>
</thead>
<tbody>
{channels.map((c) => {
const recording = c.sessions.length > 0;
const status = statuses.get(c.id);
return (
<tr key={c.id}>
<td>
<Link href={`/channels/${c.id}`}>{c.name}</Link>{" "}
<span className="mono">{c.youtubeHandle}</span>
</td>
<td>
<span className={`badge ${c.isActive ? "ok" : "muted"}`}>
{c.isActive ? "Aktif" : "Pasif"}
</span>
</td>
<td>
<span className={`badge ${recording ? "warn" : "muted"}`}>
{recording ? "🔴 Kayıtta" : "—"}
</span>
{status?.lastPollError && (
<span className="badge err" style={{ marginLeft: "0.4rem" }}>
hata
</span>
)}
</td>
<td className="mono">
{c.lastCheckedAt ? new Date(c.lastCheckedAt).toLocaleString("tr-TR") : "—"}
</td>
</tr>
);
})}
</tbody>
</table>
)}
</>
);
}