Add complete project files
This commit is contained in:
18
lib/i18n.ts
Executable file
18
lib/i18n.ts
Executable file
@@ -0,0 +1,18 @@
|
||||
// TODO: Implement internationalization
|
||||
// This file is a placeholder for future i18n implementation
|
||||
// Consider using next-intl or react-i18next for multi-language support
|
||||
|
||||
export const defaultLocale = 'en';
|
||||
export const supportedLocales = ['en'] as const;
|
||||
|
||||
export type Locale = typeof supportedLocales[number];
|
||||
|
||||
export function getLocaleFromPath(pathname: string): Locale {
|
||||
// TODO: Implement locale detection from pathname
|
||||
return defaultLocale;
|
||||
}
|
||||
|
||||
export function getLocalizedPath(pathname: string, locale: Locale): string {
|
||||
// TODO: Implement localized path generation
|
||||
return pathname;
|
||||
}
|
||||
30
lib/utils.ts
Executable file
30
lib/utils.ts
Executable file
@@ -0,0 +1,30 @@
|
||||
import { type ClassValue, clsx } from 'clsx';
|
||||
import { twMerge } from 'tailwind-merge';
|
||||
|
||||
export function cn(...inputs: ClassValue[]) {
|
||||
return twMerge(clsx(inputs));
|
||||
}
|
||||
|
||||
export function formatPhoneNumber(phone: string): string {
|
||||
const cleaned = phone.replace(/\D/g, '');
|
||||
const match = cleaned.match(/^(\d{3})(\d{3})(\d{4})$/);
|
||||
if (match) {
|
||||
return `(${match[1]}) ${match[2]}-${match[3]}`;
|
||||
}
|
||||
return phone;
|
||||
}
|
||||
|
||||
export function formatCurrency(amount: number): string {
|
||||
return new Intl.NumberFormat('en-US', {
|
||||
style: 'currency',
|
||||
currency: 'USD',
|
||||
}).format(amount);
|
||||
}
|
||||
|
||||
export function slugify(text: string): string {
|
||||
return text
|
||||
.toLowerCase()
|
||||
.replace(/[^\w\s-]/g, '')
|
||||
.replace(/[\s_-]+/g, '-')
|
||||
.replace(/^-+|-+$/g, '');
|
||||
}
|
||||
22
lib/validations.ts
Executable file
22
lib/validations.ts
Executable file
@@ -0,0 +1,22 @@
|
||||
import { z } from 'zod';
|
||||
|
||||
export const contactFormSchema = z.object({
|
||||
name: z.string().min(2, 'Name must be at least 2 characters'),
|
||||
email: z.string().email('Please enter a valid email address'),
|
||||
phone: z.string().optional(),
|
||||
message: z.string().min(10, 'Message must be at least 10 characters'),
|
||||
});
|
||||
|
||||
export const serviceSchema = z.object({
|
||||
id: z.string(),
|
||||
title: z.string(),
|
||||
description: z.string(),
|
||||
slug: z.string(),
|
||||
image: z.string(),
|
||||
heroImage: z.string(),
|
||||
detailImage: z.string(),
|
||||
features: z.array(z.string()),
|
||||
});
|
||||
|
||||
export type ContactFormData = z.infer<typeof contactFormSchema>;
|
||||
export type Service = z.infer<typeof serviceSchema>;
|
||||
Reference in New Issue
Block a user