File size: 6,704 Bytes
1ed65e9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4827fe0
1928d7f
 
 
 
1ed65e9
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
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<AvailableUseCase, string> = {
  "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";
}