- Job cards scanner: oil QR books litres + vehicle (no odo/photo), bundled onto the vehicle's job card (open job now, or the next job started the same day) - Fuel tab is diesel only; /api/clock/oil-out added - Users: Full / Clock-in user / Mechanic; mechanics see only Fuel + Job cards - Plant Register: QR code column (double-click to set), kept across re-seeds and used when matching scans Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
39 lines
1.9 KiB
TypeScript
39 lines
1.9 KiB
TypeScript
export const STARTER_PASSWORD = "mega2026";
|
|
export const SESSION_COOKIE = "mega_session";
|
|
|
|
const validEmail = (email: string) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email) && email.length <= 254;
|
|
|
|
export function validateLogin(email: string, password: string): string | null {
|
|
if (!validEmail(email.trim()) || !password) return "Enter your email and password.";
|
|
return null;
|
|
}
|
|
|
|
export function validateNewPassword(password: string, confirmation: string): string | null {
|
|
if (password.length < 8) return "Choose a password with at least 8 characters.";
|
|
if (password === STARTER_PASSWORD) return "Choose a password different from the starter password.";
|
|
if (password !== confirmation) return "The passwords do not match.";
|
|
return null;
|
|
}
|
|
|
|
export function validateNewUser(name: string, email: string): string | null {
|
|
if (!name.trim()) return "Enter the person's name.";
|
|
if (!validEmail(email.trim())) return "Enter a valid email address.";
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* "full" = the main app and the whole clock app.
|
|
* "clock" = clock-in user: the Plant Clock app only (all its tabs).
|
|
* "mechanic" = the Plant Clock app's Fuel and Job cards tabs only — no clock in/out scanner.
|
|
*/
|
|
export type UserAccess = "full" | "clock" | "mechanic";
|
|
export const USER_ACCESS: UserAccess[] = ["full", "clock", "mechanic"];
|
|
export const ACCESS_LABEL: Record<UserAccess, string> = { full: "Full", clock: "Clock-in user", mechanic: "Mechanic" };
|
|
export const parseAccess = (value: unknown): UserAccess => (value === "clock" || value === "mechanic" ? value : "full");
|
|
|
|
export function authDestination(session: { passwordChanged: boolean; access?: UserAccess } | null): string {
|
|
if (!session) return "/login";
|
|
if (!session.passwordChanged) return "/change-password";
|
|
// A clock-only user has no home in the main app: send them to the clock.
|
|
return session.access === "clock" || session.access === "mechanic" ? "/clock" : "/";
|
|
}
|