chore: remove cashed

This commit is contained in:
Wikid82
2025-11-24 18:22:01 +00:00
parent 9c842e7eab
commit 6feff3e8ce
289 changed files with 39795 additions and 0 deletions

6
frontend/src/utils/cn.ts Normal file
View File

@@ -0,0 +1,6 @@
import { type ClassValue, clsx } from 'clsx'
import { twMerge } from 'tailwind-merge'
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}

View File

@@ -0,0 +1,80 @@
export interface PasswordStrength {
score: number; // 0-4
label: string;
color: string; // Tailwind color class prefix (e.g., 'red', 'yellow', 'green')
feedback: string[];
}
export function calculatePasswordStrength(password: string): PasswordStrength {
let score = 0;
const feedback: string[] = [];
if (!password) {
return {
score: 0,
label: 'Empty',
color: 'gray',
feedback: [],
};
}
// Length check
if (password.length < 8) {
feedback.push('Too short (min 8 chars)');
} else {
score += 1;
}
if (password.length >= 12) {
score += 1;
}
// Complexity checks
const hasLower = /[a-z]/.test(password);
const hasUpper = /[A-Z]/.test(password);
const hasNumber = /\d/.test(password);
const hasSpecial = /[^A-Za-z0-9]/.test(password);
const varietyCount = [hasLower, hasUpper, hasNumber, hasSpecial].filter(Boolean).length;
if (varietyCount >= 3) {
score += 1;
}
if (varietyCount === 4) {
score += 1;
}
// Penalties
if (varietyCount < 2 && password.length >= 8) {
feedback.push('Add more variety (uppercase, numbers, symbols)');
}
// Cap score at 4
score = Math.min(score, 4);
// Determine label and color
let label = 'Very Weak';
let color = 'red';
switch (score) {
case 0:
case 1:
label = 'Weak';
color = 'red';
break;
case 2:
label = 'Fair';
color = 'yellow';
break;
case 3:
label = 'Good';
color = 'green';
break;
case 4:
label = 'Strong';
color = 'green';
break;
}
return { score, label, color, feedback };
}

View File

@@ -0,0 +1,29 @@
type ToastType = 'success' | 'error' | 'info' | 'warning'
export interface Toast {
id: number
message: string
type: ToastType
}
let toastId = 0
export const toastCallbacks = new Set<(toast: Toast) => void>()
export const toast = {
success: (message: string) => {
const id = ++toastId
toastCallbacks.forEach(callback => callback({ id, message, type: 'success' }))
},
error: (message: string) => {
const id = ++toastId
toastCallbacks.forEach(callback => callback({ id, message, type: 'error' }))
},
info: (message: string) => {
const id = ++toastId
toastCallbacks.forEach(callback => callback({ id, message, type: 'info' }))
},
warning: (message: string) => {
const id = ++toastId
toastCallbacks.forEach(callback => callback({ id, message, type: 'warning' }))
},
}

View File

@@ -0,0 +1,4 @@
export const isValidEmail = (email: string): boolean => {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
return emailRegex.test(email)
}