Initial commit: Voiced invoice desktop app
Offline-first invoicing app for Test Vendor, built by Bongbetic. - Tauri v2 (Rust) + React/TypeScript + IBM Carbon Design System UI - SQLite (rusqlite) storage with a persistent invoice-number series - Guided first-run setup, pre-filled vendor/bank details - Fixed-amount or rate x quantity line items (per sec/min/hour/session/unit) - GST as CGST+SGST or IGST, Indian amount-in-words - Optional signature, with a computer-generated note as fallback - Print-ready PDF export via @react-pdf/renderer - Windows cross-compile via cargo-xwin (NSIS installer) Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
const PAN_RE = /^[A-Z]{5}[0-9]{4}[A-Z]$/;
|
||||
const IFSC_RE = /^[A-Z]{4}0[A-Z0-9]{6}$/;
|
||||
const GSTIN_RE = /^[0-9]{2}[A-Z]{5}[0-9]{4}[A-Z][1-9A-Z]Z[0-9A-Z]$/;
|
||||
const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
const PHONE_RE = /^[0-9+\-()\s]{6,16}$/;
|
||||
|
||||
const norm = (v: string) => v.trim().toUpperCase();
|
||||
|
||||
export function panError(value: string): string | undefined {
|
||||
if (!value.trim()) return undefined;
|
||||
return PAN_RE.test(norm(value)) ? undefined : "Enter a valid PAN, e.g. ABCDE1234F";
|
||||
}
|
||||
|
||||
export function ifscError(value: string): string | undefined {
|
||||
if (!value.trim()) return undefined;
|
||||
return IFSC_RE.test(norm(value)) ? undefined : "Enter a valid IFSC, e.g. TEST0000001";
|
||||
}
|
||||
|
||||
export function gstinError(value: string): string | undefined {
|
||||
const v = norm(value);
|
||||
if (!v || v === "NA") return undefined;
|
||||
return GSTIN_RE.test(v) ? undefined : "Enter a valid 15-character GSTIN";
|
||||
}
|
||||
|
||||
export function emailError(value: string): string | undefined {
|
||||
if (!value.trim()) return undefined;
|
||||
return EMAIL_RE.test(value.trim()) ? undefined : "Enter a valid email address";
|
||||
}
|
||||
|
||||
export function phoneError(value: string): string | undefined {
|
||||
if (!value.trim()) return undefined;
|
||||
return PHONE_RE.test(value.trim()) ? undefined : "Enter a valid phone number";
|
||||
}
|
||||
|
||||
export function accountError(value: string): string | undefined {
|
||||
if (!value.trim()) return undefined;
|
||||
return /^[0-9]{6,20}$/.test(value.trim()) ? undefined : "Account number should be 6–20 digits";
|
||||
}
|
||||
|
||||
export const isPan = (v: string) => PAN_RE.test(norm(v));
|
||||
export const isIfsc = (v: string) => IFSC_RE.test(norm(v));
|
||||
export const isGstin = (v: string) => GSTIN_RE.test(norm(v));
|
||||
Reference in New Issue
Block a user