import { redirect } from "next/navigation"; import { applyTeam } from "@/actions/applications"; import { ContentCard, EmptyState } from "@/components/public/ui"; import { auth } from "@/lib/auth"; import { prisma } from "@/lib/prisma"; import { siteSettings } from "@/lib/services/site-settings"; export const dynamic = "force-dynamic"; // Canonical Habbo badge image CDN (same base used by the profile page). const BADGE_IMG_BASE = "https://images.habbo.com/c_images/album1584"; export default async function ApplyTeamPage() { const session = await auth(); if (!session?.user?.id) redirect("/login"); const userId = Number(session.user.id); const hotelName = (await siteSettings.get("hotel_name", "Atom")) ?? "Atom"; // ── Teams open for application ────────────────────────────── // The Prisma slice exposes teams directly (no separate team-position table // with position_kind), so the team application concept lists website_teams. // Hidden ranks are excluded from the public apply page. const teams = await prisma.websiteTeams .findMany({ where: { hiddenRank: false }, orderBy: { rankName: "asc" }, }) .catch(() => []); // Teams this user has already applied to. Team applications reuse the staff // applications table with rank_id carrying the team id (the team flag). const myApps = await prisma.websiteStaffApplications .findMany({ where: { userId }, select: { rankId: true } }) .catch(() => []); const appliedTeamIds = new Set(myApps.map((a) => a.rankId)); return (
{teams.length === 0 ? ( There are currently no open team positions. Please come back later to check for new openings. Thank you! ) : (
{teams.map((team) => { const teamId = Number(team.id); const alreadyApplied = appliedTeamIds.has(teamId); return (
{team.badge ? ( /* eslint-disable-next-line @next/next/no-img-element */ {team.rankName} ) : ( 🤝 )}

{team.rankName}

{team.jobDescription ? (

{team.jobDescription}

) : null}
{alreadyApplied ? ( ) : (
{/* The team id is the application's rank flag; the applicant is re-read from the session inside the action. */}