119 lines
3.2 KiB
TypeScript
Executable File
119 lines
3.2 KiB
TypeScript
Executable File
|
|
export enum UserRole {
|
|
ADMIN = 'ADMIN',
|
|
STUDENT = 'STUDENT',
|
|
TEACHER = 'TEACHER',
|
|
GURU_BK = 'GURU_BK'
|
|
}
|
|
|
|
export interface User {
|
|
id: string;
|
|
name: string;
|
|
nis?: string; // Student ID
|
|
className?: string; // Class/Grade e.g. "XII RPL 1"
|
|
shift?: 'PAGI' | 'SIANG'; // Shift assignment
|
|
role: UserRole;
|
|
registeredFace?: string; // Base64 or URL of registered face photo
|
|
faceDescriptor?: string; // JSON serialized 128-d face descriptor for local comparison
|
|
createdAt: number;
|
|
isSetup?: boolean; // Flag for first-time admin setup
|
|
}
|
|
|
|
export interface StaffUser {
|
|
id: string;
|
|
username: string;
|
|
name: string;
|
|
role: 'ADMIN' | 'TEACHER' | 'GURU_BK';
|
|
phone?: string;
|
|
assignedClasses?: string[];
|
|
is_active: boolean;
|
|
created_at?: string;
|
|
}
|
|
|
|
export interface LeaveRequest {
|
|
id: string;
|
|
studentId: string;
|
|
studentName: string;
|
|
studentNis?: string;
|
|
studentClass?: string;
|
|
requestType: 'SAKIT' | 'IZIN' | 'DISPEN';
|
|
requestDate: string;
|
|
reason: string;
|
|
photoEvidence?: string;
|
|
status: 'PENDING' | 'APPROVED' | 'REJECTED';
|
|
reviewedBy?: string;
|
|
reviewedByName?: string;
|
|
reviewedAt?: string;
|
|
rejectionReason?: string;
|
|
createdAt?: string;
|
|
}
|
|
|
|
export interface AttendanceRecord {
|
|
id: string;
|
|
userId: string;
|
|
userName: string;
|
|
nis?: string;
|
|
className?: string;
|
|
timestamp: number;
|
|
dateStr: string; // YYYY-MM-DD
|
|
timeStr: string; // HH:MM
|
|
location: {
|
|
lat: number;
|
|
lng: number;
|
|
distance: number;
|
|
};
|
|
photoEvidence: string; // Base64
|
|
status: 'PRESENT' | 'LATE' | 'REGISTRATION' | 'ALFA' | 'SAKIT' | 'IZIN' | 'DISPEN'; // Added DISPEN
|
|
aiVerification?: string;
|
|
parentPhone?: string; // Added field for Parent/Guardian Phone
|
|
}
|
|
|
|
export interface AppSettings {
|
|
schoolName: string;
|
|
schoolLat: number;
|
|
schoolLng: number;
|
|
allowedRadiusMeters: number;
|
|
|
|
// Double Shift Configuration (Now using HH:mm strings)
|
|
morningStart: string; // e.g., "07:00"
|
|
morningEnd: string; // e.g., "12:00"
|
|
afternoonStart: string; // e.g., "12:30"
|
|
afternoonEnd: string; // e.g., "16:00"
|
|
|
|
allowedDays: number[]; // Legacy support (0=Sunday, etc)
|
|
activeDates: string[]; // Specific dates e.g., ['2024-03-01', '2024-03-02']
|
|
googleScriptUrl?: string; // URL for Google Apps Script Web App
|
|
fonnteToken?: string; // Fonnte WhatsApp API Token
|
|
|
|
// New Periodical Settings
|
|
availableClasses?: string[]; // List of classes e.g. ["X-1", "X-2"]
|
|
semester?: 'Ganjil' | 'Genap';
|
|
academicYear?: string; // e.g. "2023/2024"
|
|
// Security & Accuracy
|
|
faceMatchThreshold?: number; // 0.1 - 0.7 (Lower = Stricter, Default 0.45)
|
|
|
|
// Auto-Rekap Alfa Schedule
|
|
autoRekapAlfaTime?: string; // e.g., "19:00"
|
|
}
|
|
|
|
export const DEFAULT_SETTINGS: AppSettings = {
|
|
schoolName: 'SMA Negeri 1 Abiansemal',
|
|
schoolLat: -8.5107893,
|
|
schoolLng: 115.2142912,
|
|
allowedRadiusMeters: 100,
|
|
|
|
// Default Shifts (Updated format from screenshot)
|
|
morningStart: "07:00",
|
|
morningEnd: "12:00",
|
|
afternoonStart: "12:30",
|
|
afternoonEnd: "16:00",
|
|
|
|
allowedDays: [1, 2, 3, 4, 5, 6], // Mon-Sat
|
|
activeDates: [],
|
|
academicYear: '2023/2024',
|
|
semester: 'Ganjil',
|
|
googleScriptUrl: 'https://script.google.com/macros/s/AKfycbzYZbBdDzfXX80EM-1fTl35r0xWJCXeDROk0tjZYd-TtpH74uVTjMYLY1qy7QUkTM9_aw/exec',
|
|
faceMatchThreshold: 0.45,
|
|
autoRekapAlfaTime: '19:00'
|
|
};
|