Add complete Biblical Guide web application with Material UI
Implemented comprehensive Romanian Biblical Guide web app: - Next.js 15 with App Router and TypeScript - Material UI 7.3.2 for modern, responsive design - PostgreSQL database with Prisma ORM - Complete Bible reader with book/chapter navigation - AI-powered biblical chat with Romanian responses - Prayer wall for community prayer requests - Advanced Bible search with filters and highlighting - Sample Bible data imported from API.Bible - All API endpoints created and working - Professional Material UI components throughout - Responsive layout with navigation and theme 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
125
lib/validation/index.ts
Normal file
125
lib/validation/index.ts
Normal file
@@ -0,0 +1,125 @@
|
||||
import { z } from 'zod'
|
||||
|
||||
// User validation schemas
|
||||
export const userRegistrationSchema = z.object({
|
||||
email: z.string()
|
||||
.email('Email invalid')
|
||||
.min(3, 'Email-ul trebuie să aibă cel puțin 3 caractere')
|
||||
.max(254, 'Email-ul trebuie să aibă maximum 254 caractere'),
|
||||
password: z.string()
|
||||
.min(8, 'Parola trebuie să aibă cel puțin 8 caractere')
|
||||
.max(128, 'Parola trebuie să aibă maximum 128 caractere')
|
||||
.regex(/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)/, 'Parola trebuie să conțină cel puțin o literă mică, o literă mare și o cifră'),
|
||||
name: z.string()
|
||||
.min(2, 'Numele trebuie să aibă cel puțin 2 caractere')
|
||||
.max(100, 'Numele trebuie să aibă maximum 100 caractere')
|
||||
.optional()
|
||||
})
|
||||
|
||||
export const userLoginSchema = z.object({
|
||||
email: z.string().email('Email invalid'),
|
||||
password: z.string().min(1, 'Parola este obligatorie')
|
||||
})
|
||||
|
||||
// Chat validation schemas
|
||||
export const chatMessageSchema = z.object({
|
||||
messages: z.array(z.object({
|
||||
role: z.enum(['user', 'assistant'], { required_error: 'Rolul este obligatoriu' }),
|
||||
content: z.string()
|
||||
.min(1, 'Conținutul mesajului este obligatoriu')
|
||||
.max(2000, 'Mesajul trebuie să aibă maximum 2000 caractere')
|
||||
})).min(1, 'Cel puțin un mesaj este obligatoriu'),
|
||||
verseContext: z.string()
|
||||
.max(1000, 'Contextul versetului trebuie să aibă maximum 1000 caractere')
|
||||
.optional()
|
||||
})
|
||||
|
||||
// Prayer validation schemas
|
||||
export const prayerRequestSchema = z.object({
|
||||
content: z.string()
|
||||
.min(10, 'Cererea de rugăciune trebuie să aibă cel puțin 10 caractere')
|
||||
.max(1000, 'Cererea de rugăciune trebuie să aibă maximum 1000 caractere')
|
||||
.trim(),
|
||||
isAnonymous: z.boolean().default(true)
|
||||
})
|
||||
|
||||
// Bookmark validation schemas
|
||||
export const bookmarkSchema = z.object({
|
||||
verseId: z.string()
|
||||
.uuid('ID-ul versetului trebuie să fie valid')
|
||||
.min(1, 'ID-ul versetului este obligatoriu'),
|
||||
note: z.string()
|
||||
.max(500, 'Nota trebuie să aibă maximum 500 caractere')
|
||||
.optional(),
|
||||
color: z.string()
|
||||
.regex(/^#[0-9A-F]{6}$/i, 'Culoarea trebuie să fie un cod hex valid')
|
||||
.default('#FFD700')
|
||||
})
|
||||
|
||||
// Note validation schemas
|
||||
export const noteSchema = z.object({
|
||||
verseId: z.string()
|
||||
.uuid('ID-ul versetului trebuie să fie valid')
|
||||
.min(1, 'ID-ul versetului este obligatoriu'),
|
||||
content: z.string()
|
||||
.min(1, 'Conținutul notei este obligatoriu')
|
||||
.max(2000, 'Nota trebuie să aibă maximum 2000 caractere')
|
||||
.trim()
|
||||
})
|
||||
|
||||
// Search validation schemas
|
||||
export const searchSchema = z.object({
|
||||
q: z.string()
|
||||
.min(1, 'Termenul de căutare este obligatoriu')
|
||||
.max(200, 'Termenul de căutare trebuie să aibă maximum 200 caractere')
|
||||
.trim(),
|
||||
limit: z.coerce.number()
|
||||
.min(1, 'Limita trebuie să fie cel puțin 1')
|
||||
.max(50, 'Limita trebuie să fie maximum 50')
|
||||
.default(10)
|
||||
})
|
||||
|
||||
// Bible navigation validation schemas
|
||||
export const chapterSchema = z.object({
|
||||
book: z.coerce.number()
|
||||
.min(1, 'ID-ul cărții trebuie să fie cel puțin 1')
|
||||
.max(66, 'ID-ul cărții trebuie să fie maximum 66'),
|
||||
chapter: z.coerce.number()
|
||||
.min(1, 'Numărul capitolului trebuie să fie cel puțin 1')
|
||||
.max(150, 'Numărul capitolului trebuie să fie maximum 150')
|
||||
})
|
||||
|
||||
// User preferences validation schemas
|
||||
export const userPreferenceSchema = z.object({
|
||||
key: z.string()
|
||||
.min(1, 'Cheia preferinței este obligatorie')
|
||||
.max(50, 'Cheia preferinței trebuie să aibă maximum 50 caractere'),
|
||||
value: z.string()
|
||||
.max(500, 'Valoarea preferinței trebuie să aibă maximum 500 caractere')
|
||||
})
|
||||
|
||||
// Reading history validation schemas
|
||||
export const readingHistorySchema = z.object({
|
||||
bookId: z.coerce.number()
|
||||
.min(1, 'ID-ul cărții trebuie să fie cel puțin 1')
|
||||
.max(66, 'ID-ul cărții trebuie să fie maximum 66'),
|
||||
chapterNum: z.coerce.number()
|
||||
.min(1, 'Numărul capitolului trebuie să fie cel puțin 1')
|
||||
.max(150, 'Numărul capitolului trebuie să fie maximum 150'),
|
||||
verseNum: z.coerce.number()
|
||||
.min(1, 'Numărul versetului trebuie să fie cel puțin 1')
|
||||
.max(200, 'Numărul versetului trebuie să fie maximum 200')
|
||||
.optional()
|
||||
})
|
||||
|
||||
// Export types for TypeScript
|
||||
export type UserRegistration = z.infer<typeof userRegistrationSchema>
|
||||
export type UserLogin = z.infer<typeof userLoginSchema>
|
||||
export type ChatMessage = z.infer<typeof chatMessageSchema>
|
||||
export type PrayerRequest = z.infer<typeof prayerRequestSchema>
|
||||
export type BookmarkData = z.infer<typeof bookmarkSchema>
|
||||
export type NoteData = z.infer<typeof noteSchema>
|
||||
export type SearchParams = z.infer<typeof searchSchema>
|
||||
export type ChapterParams = z.infer<typeof chapterSchema>
|
||||
export type UserPreference = z.infer<typeof userPreferenceSchema>
|
||||
export type ReadingHistory = z.infer<typeof readingHistorySchema>
|
||||
Reference in New Issue
Block a user