import { clsx, type ClassValue } from "clsx"; import { twMerge } from "tailwind-merge"; import type { AvailableUseCase } from "@/types"; // ============================================================ // Tailwind class merging utility // ============================================================ export function cn(...inputs: ClassValue[]) { return twMerge(clsx(inputs)); } // ============================================================ // promptBuilder — mirrors Python promptBuilder() // ============================================================ export function promptBuilder( slicer_usecase: string, year: number, site: string, slicer_period: string, // e.g. "bulan 3" or "week 12" slicer_section: string, slicer_model: string, slicer_eqm: string ): string { const eqm = slicer_eqm.toUpperCase(); const model = slicer_model.toUpperCase(); const section = slicer_section.toUpperCase(); if (eqm !== "ALL") { return `Berikan report ${slicer_usecase} pada tahun ${year}, site ${site}, ${slicer_period}, equipment ${slicer_eqm}`; } else if (model !== "ALL") { return `Berikan report ${slicer_usecase} pada tahun ${year}, site ${site}, ${slicer_period}, section ${slicer_section} dan model ${slicer_model}`; } else if (section !== "ALL" && model === "ALL") { return `Berikan report ${slicer_usecase} pada tahun ${year}, site ${site}, ${slicer_period}, section ${slicer_section}, model ALL, dan equipment ALL`; } else { return `Berikan report ${slicer_usecase} pada tahun ${year}, site ${site}, ${slicer_period}, section ALL, model ALL, dan equipment ALL`; } } // ============================================================ // getWeekId — mirrors Python get_week_id() with saturday-friday scheme // ============================================================ export function getWeekId(date: Date, scheme: "saturday-friday" | "monday-sunday" | "sunday-saturday" = "saturday-friday"): number { let startOfWeek: Date; if (scheme === "monday-sunday") { const day = date.getDay(); // 0=Sun const diff = day === 0 ? -6 : 1 - day; startOfWeek = new Date(date); startOfWeek.setDate(date.getDate() + diff); } else if (scheme === "sunday-saturday") { const day = date.getDay(); startOfWeek = new Date(date); startOfWeek.setDate(date.getDate() - day); } else { // saturday-friday const day = date.getDay(); // 0=Sun,6=Sat const diff = (day + 1) % 7; // days since Saturday startOfWeek = new Date(date); startOfWeek.setDate(date.getDate() - diff); } const year = startOfWeek.getFullYear(); const firstDayOfYear = new Date(year, 0, 1); let firstWeekStart: Date; if (scheme === "saturday-friday") { const fd = firstDayOfYear.getDay(); const diff2 = (fd + 1) % 7; firstWeekStart = new Date(firstDayOfYear); firstWeekStart.setDate(firstDayOfYear.getDate() - diff2); if (firstWeekStart.getFullYear() < year) { const fd2 = firstDayOfYear.getDay(); firstWeekStart = new Date(firstDayOfYear); firstWeekStart.setDate(firstDayOfYear.getDate() + (7 - fd2) % 7); } } else { firstWeekStart = firstDayOfYear; } const msPerDay = 86400000; const weekNumber = Math.floor((startOfWeek.getTime() - firstWeekStart.getTime()) / (7 * msPerDay)) + 2; return parseInt(`${year}${String(weekNumber).padStart(2, "0")}`); } // ============================================================ // getCurrentWeek — returns current week number (1-52) // ============================================================ export function getCurrentWeek(): number { const now = new Date(); const weekId = getWeekId(now, "saturday-friday"); return parseInt(String(weekId).slice(-2)); } // ============================================================ // use_case_mapper_interface — mirrors Python mapper.py // ============================================================ export const useCaseMapperInterface: Record = { "pa performance": "pa performance", "bad actor": "pa performance", "pareto by frequency": "pareto", "pareto by duration": "pareto", "pareto by total equipment": "pareto", "inspection": "inspection", "backlog monitoring": "backlog", "planning": "planning", "execution and leadtime": "execution", }; export const useCaseOptions: AvailableUseCase[] = [ "pa performance", "bad actor", "pareto by frequency", "pareto by duration", "pareto by total equipment", "inspection", "backlog monitoring", "planning", "execution and leadtime", ]; // ============================================================ // Quick questions for Learning agent // ============================================================ export const quickQuestions = [ "Cara manual handling sparepart dengan berat lebih 18 kg?", "Cara mengeluarkan spare part dari peti kayu?", "Bagaimana cara recovery after rain yang efektif?", "Cara optimalisasi pemuatan hauler hingga vessel penuh?", "Apa saja daftar risiko bekerja di lapangan?" ]; // ============================================================ // Number of buffer messages to send to AI // ============================================================ export const N_BUFFER_MESSAGES = 10; // ============================================================ // Format a date string nicely // ============================================================ export function formatDate(dateStr: string): string { const date = new Date(dateStr); const now = new Date(); const diffMs = now.getTime() - date.getTime(); const diffDays = Math.floor(diffMs / 86400000); if (diffDays === 0) { return date.toLocaleTimeString("id-ID", { hour: "2-digit", minute: "2-digit" }); } else if (diffDays === 1) { return "Kemarin"; } else if (diffDays < 7) { return date.toLocaleDateString("id-ID", { weekday: "long" }); } else { return date.toLocaleDateString("id-ID", { day: "numeric", month: "short", year: "numeric" }); } } // ============================================================ // Generate short session title from first user message // ============================================================ export function generateSessionTitle(firstMessage: string): string { if (firstMessage.length <= 50) return firstMessage; return firstMessage.slice(0, 47) + "..."; } // ============================================================ // Whether this use case should hide Equipment dropdown // ============================================================ export function shouldHideEquipment(usecase: string): boolean { const lower = usecase.toLowerCase(); return lower === "bad actor" || lower === "pareto by total equipment"; }