change sqlite user table column id to increment int ids
This commit is contained in:
parent
0f224287fd
commit
dad13c9cfb
|
|
@ -0,0 +1,103 @@
|
||||||
|
|
||||||
|
import Link from 'next/link';
|
||||||
|
import { Button } from '@/components/ui/button';
|
||||||
|
import ToyList from '@/components/toys/ToyList';
|
||||||
|
import { getToysByOwner, getOwnerProfile, getAllToys } from '@/data/operations';
|
||||||
|
import { getI18n, getStaticParams as getLocaleStaticParams } from '@/locales/server';
|
||||||
|
import { Home, UserCircle } from 'lucide-react';
|
||||||
|
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
|
||||||
|
import { ToyBrick } from 'lucide-react';
|
||||||
|
import { Avatar, AvatarImage, AvatarFallback } from "@/components/ui/avatar";
|
||||||
|
|
||||||
|
interface OwnerToysPageProps {
|
||||||
|
params: { ownerId: string; locale: string };
|
||||||
|
}
|
||||||
|
|
||||||
|
export default async function OwnerToysPage({ params }: OwnerToysPageProps) {
|
||||||
|
const t = await getI18n();
|
||||||
|
const ownerId = Number(params.ownerId);
|
||||||
|
const ownerToys = getToysByOwner(ownerId);
|
||||||
|
const ownerProfile = getOwnerProfile(ownerId);
|
||||||
|
|
||||||
|
const ownerNameFromToys = ownerToys.length > 0 ? ownerToys[0].ownerName : undefined;
|
||||||
|
|
||||||
|
let displayOwnerName = ownerProfile?.name || ownerNameFromToys || t('owner_toys.unknown_owner');
|
||||||
|
|
||||||
|
const pageTitle = displayOwnerName !== t('owner_toys.unknown_owner')
|
||||||
|
? t('owner_toys.title_specific', { ownerName: displayOwnerName })
|
||||||
|
: t('owner_toys.title_generic');
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="space-y-8">
|
||||||
|
<div className="flex flex-col sm:flex-row justify-between items-start sm:items-center gap-4">
|
||||||
|
<h1 className="text-3xl font-bold font-headline text-primary">{pageTitle}</h1>
|
||||||
|
<Link href={`/${params.locale}/`} passHref>
|
||||||
|
<Button variant="outline" className="w-full sm:w-auto">
|
||||||
|
<Home className="mr-2 h-4 w-4" />
|
||||||
|
{t('owner_toys.back_to_home')}
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{ownerProfile && (
|
||||||
|
<Card className="mb-8 shadow-lg border-accent/30">
|
||||||
|
<CardHeader>
|
||||||
|
<div className="flex flex-col sm:flex-row items-center gap-4">
|
||||||
|
<Avatar className="h-20 w-20 sm:h-24 sm:w-24 border-2 border-accent">
|
||||||
|
<AvatarImage src={ownerProfile.avatarUrl} alt={displayOwnerName} data-ai-hint="owner avatar" />
|
||||||
|
<AvatarFallback className="text-3xl bg-muted">
|
||||||
|
{displayOwnerName ? displayOwnerName.split(' ').map(n => n[0]).join('').toUpperCase() : <UserCircle />}
|
||||||
|
</AvatarFallback>
|
||||||
|
</Avatar>
|
||||||
|
<div className="text-center sm:text-left">
|
||||||
|
<CardTitle className="text-2xl font-headline text-accent">
|
||||||
|
{t('owner_toys.about_owner', { ownerName: displayOwnerName })}
|
||||||
|
</CardTitle>
|
||||||
|
{ownerNameFromToys && ownerNameFromToys !== displayOwnerName && (
|
||||||
|
<CardDescription>{t('toy_details.owner')}: {ownerNameFromToys}</CardDescription>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
|
<p className="text-foreground/80 leading-relaxed">{ownerProfile.bio}</p>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{ownerToys.length > 0 ? (
|
||||||
|
<ToyList toys={ownerToys} t={t} />
|
||||||
|
) : (
|
||||||
|
<Card className="text-center py-12 shadow-md">
|
||||||
|
<CardHeader>
|
||||||
|
<ToyBrick className="h-16 w-16 mx-auto text-muted-foreground mb-4" />
|
||||||
|
<CardTitle>
|
||||||
|
{displayOwnerName !== t('owner_toys.unknown_owner')
|
||||||
|
? t('owner_toys.no_toys_listed_by', { ownerName: displayOwnerName })
|
||||||
|
: t('owner_toys.owner_not_found')}
|
||||||
|
</CardTitle>
|
||||||
|
{displayOwnerName !== t('owner_toys.unknown_owner') && <CardDescription>{t('home.explore_toys')}</CardDescription>}
|
||||||
|
</CardHeader>
|
||||||
|
<CardContent>
|
||||||
|
<Link href={`/${params.locale}/`} passHref>
|
||||||
|
<Button size="lg">
|
||||||
|
{t('home.explore_toys')}
|
||||||
|
</Button>
|
||||||
|
</Link>
|
||||||
|
</CardContent>
|
||||||
|
</Card>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function generateStaticParams() {
|
||||||
|
const localeParams = getLocaleStaticParams();
|
||||||
|
const allToys = getAllToys();
|
||||||
|
const ownerIds = Array.from(new Set(allToys.map(toy => toy.ownerId)));
|
||||||
|
const ownerParams = ownerIds.map(id => ({ ownerId: String(id) }));
|
||||||
|
|
||||||
|
return localeParams.flatMap(lang =>
|
||||||
|
ownerParams.map(owner => ({ ...lang, ...owner }))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
@ -13,7 +13,8 @@ interface EditUserPageProps {
|
||||||
|
|
||||||
export default async function EditUserPage({ params }: EditUserPageProps) {
|
export default async function EditUserPage({ params }: EditUserPageProps) {
|
||||||
const t = await getI18n();
|
const t = await getI18n();
|
||||||
const userData = getUserById(params.id);
|
const userId = Number(params.id);
|
||||||
|
const userData = getUserById(userId);
|
||||||
|
|
||||||
if (!userData) {
|
if (!userData) {
|
||||||
return (
|
return (
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ export default function AdminUserManagementPage() {
|
||||||
}, [t, toast]);
|
}, [t, toast]);
|
||||||
|
|
||||||
|
|
||||||
const handleDeleteUser = async (userId: string) => {
|
const handleDeleteUser = async (userId: number) => {
|
||||||
setIsDeleting(true);
|
setIsDeleting(true);
|
||||||
const result = await deleteUser(userId);
|
const result = await deleteUser(userId);
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
|
|
|
||||||
|
|
@ -17,20 +17,20 @@ import { ArrowLeft, Send, Loader2, AlertTriangle, ToyBrick } from 'lucide-react'
|
||||||
import { useToast } from '@/hooks/use-toast';
|
import { useToast } from '@/hooks/use-toast';
|
||||||
import { format } from 'date-fns';
|
import { format } from 'date-fns';
|
||||||
|
|
||||||
// Assume current user is 'user1' for mock purposes
|
// Assume current user is 'user1' (ID: 1) for mock purposes
|
||||||
const currentUserId = 'user1';
|
const currentUserId = 1;
|
||||||
const currentUserProfiles: Record<string, { name: string; avatarInitial: string; avatarUrl?: string }> = {
|
const currentUserProfiles: Record<number, { name: string; avatarInitial: string; avatarUrl?: string }> = {
|
||||||
'user1': { name: 'Alice Wonderland', avatarInitial: 'AW', avatarUrl: 'https://placehold.co/40x40.png?text=AW' }, // Logged in user
|
1: { name: 'Alice Wonderland', avatarInitial: 'AW', avatarUrl: 'https://placehold.co/40x40.png?text=AW' }, // Logged in user
|
||||||
'user2': { name: 'Bob The Builder', avatarInitial: 'BT', avatarUrl: 'https://placehold.co/40x40.png?text=BT' },
|
2: { name: 'Bob The Builder', avatarInitial: 'BT', avatarUrl: 'https://placehold.co/40x40.png?text=BT' },
|
||||||
'user3': { name: 'Carol Danvers', avatarInitial: 'CD', avatarUrl: 'https://placehold.co/40x40.png?text=CD' },
|
3: { name: 'Carol Danvers', avatarInitial: 'CD', avatarUrl: 'https://placehold.co/40x40.png?text=CD' },
|
||||||
'user4': { name: 'Charlie Brown', avatarInitial: 'CB', avatarUrl: 'https://placehold.co/40x40.png?text=CB' },
|
4: { name: 'Charlie Brown', avatarInitial: 'CB', avatarUrl: 'https://placehold.co/40x40.png?text=CB' },
|
||||||
'user5': { name: 'Diana Prince', avatarInitial: 'DP', avatarUrl: 'https://placehold.co/40x40.png?text=DP' },
|
5: { name: 'Diana Prince', avatarInitial: 'DP', avatarUrl: 'https://placehold.co/40x40.png?text=DP' },
|
||||||
'user6': { name: 'Edward Nigma', avatarInitial: 'EN', avatarUrl: 'https://placehold.co/40x40.png?text=EN' },
|
6: { name: 'Edward Nigma', avatarInitial: 'EN', avatarUrl: 'https://placehold.co/40x40.png?text=EN' },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// Helper function to get the other participant in a conversation
|
// Helper function to get the other participant in a conversation
|
||||||
const getOtherParticipant = (request: RentalRequest, currentUserId: string) => {
|
const getOtherParticipant = (request: RentalRequest, currentUserId: number) => {
|
||||||
if (request.toy.ownerId === currentUserId) {
|
if (request.toy.ownerId === currentUserId) {
|
||||||
return { id: request.requesterId, name: request.requesterName };
|
return { id: request.requesterId, name: request.requesterName };
|
||||||
}
|
}
|
||||||
|
|
@ -238,5 +238,3 @@ export default function MessageDetailPage({ params }: { params: { id: string } }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -9,10 +9,10 @@ import Link from "next/link";
|
||||||
import { MessageSquareQuote, ToyBrick } from "lucide-react";
|
import { MessageSquareQuote, ToyBrick } from "lucide-react";
|
||||||
import { format } from 'date-fns';
|
import { format } from 'date-fns';
|
||||||
|
|
||||||
const currentUserId = 'user1'; // Assume this is the logged-in user's ID
|
const currentUserId = 1; // Assume this is the logged-in user's ID
|
||||||
|
|
||||||
// Helper function to get the other participant in a conversation
|
// Helper function to get the other participant in a conversation
|
||||||
const getOtherParticipant = (request: RentalRequest, currentUserId: string) => {
|
const getOtherParticipant = (request: RentalRequest, currentUserId: number) => {
|
||||||
if (request.toy.ownerId === currentUserId) {
|
if (request.toy.ownerId === currentUserId) {
|
||||||
return { id: request.requesterId, name: request.requesterName };
|
return { id: request.requesterId, name: request.requesterName };
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ import type { Toy } from "@/types";
|
||||||
import { Badge } from "@/components/ui/badge";
|
import { Badge } from "@/components/ui/badge";
|
||||||
import { getI18n } from "@/locales/server";
|
import { getI18n } from "@/locales/server";
|
||||||
|
|
||||||
const currentUserId = 'user1';
|
const currentUserId = 1;
|
||||||
|
|
||||||
export default async function MyToysPage() {
|
export default async function MyToysPage() {
|
||||||
const t = await getI18n();
|
const t = await getI18n();
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import type { Locale } from "@/locales/server";
|
||||||
import { Badge } from "@/components/ui/badge";
|
import { Badge } from "@/components/ui/badge";
|
||||||
import { format } from 'date-fns';
|
import { format } from 'date-fns';
|
||||||
|
|
||||||
const currentUserId = 'user1'; // Assume this is the logged-in user's ID
|
const currentUserId = 1; // Assume this is the logged-in user's ID
|
||||||
|
|
||||||
export default async function RentalHistoryPage({ params }: { params: { locale: Locale } }) {
|
export default async function RentalHistoryPage({ params }: { params: { locale: Locale } }) {
|
||||||
const t = await getI18n();
|
const t = await getI18n();
|
||||||
|
|
@ -112,4 +112,3 @@ function RentalHistoryItemCard({ item, t, locale }: RentalHistoryItemCardProps)
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,55 +4,53 @@ import { ListOrdered, Check, X, MessageSquareText } from "lucide-react";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
import type { Toy } from "@/types";
|
import type { Toy, RentalRequest } from "@/types";
|
||||||
import { mockToys } from "@/lib/mockData";
|
import { getAllToys } from "@/data/operations";
|
||||||
import { Badge } from "@/components/ui/badge";
|
import { Badge } from "@/components/ui/badge";
|
||||||
import { getI18n } from "@/locales/server";
|
import { getI18n } from "@/locales/server";
|
||||||
|
|
||||||
interface RentalRequest {
|
// This is still mock data. In a real app, this would come from the database.
|
||||||
id: string;
|
function getMockRequests(): RentalRequest[] {
|
||||||
toy: Toy;
|
const allToys = getAllToys();
|
||||||
requesterName: string;
|
const myToys = allToys.filter(t => t.ownerId === 1);
|
||||||
requesterId: string;
|
|
||||||
requestedDates: string; // e.g., "Aug 5, 2024 - Aug 10, 2024"
|
if (myToys.length === 0) return [];
|
||||||
status: 'pending' | 'approved' | 'declined';
|
|
||||||
message?: string;
|
const rentalRequests: RentalRequest[] = [
|
||||||
dataAiHint?: string;
|
{
|
||||||
|
id: 'req1',
|
||||||
|
toy: myToys[0],
|
||||||
|
requesterName: 'Charlie Brown',
|
||||||
|
requesterId: 4,
|
||||||
|
requestedDates: 'August 10, 2024 - August 17, 2024',
|
||||||
|
status: 'pending',
|
||||||
|
message: 'My son would love to play with these for his birthday week! We are very careful with toys and will ensure it is returned in perfect condition. Could we possibly pick it up on the 9th evening?',
|
||||||
|
dataAiHint: myToys[0]?.category.toLowerCase(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'req2',
|
||||||
|
toy: myToys.length > 1 ? myToys[1] : myToys[0],
|
||||||
|
requesterName: 'Diana Prince',
|
||||||
|
requesterId: 5,
|
||||||
|
requestedDates: 'September 1, 2024 - September 5, 2024',
|
||||||
|
status: 'approved',
|
||||||
|
dataAiHint: (myToys.length > 1 ? myToys[1] : myToys[0])?.category.toLowerCase(),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 'req3',
|
||||||
|
toy: myToys[0],
|
||||||
|
requesterName: 'Edward Nigma',
|
||||||
|
requesterId: 6,
|
||||||
|
requestedDates: 'July 20, 2024 - July 22, 2024',
|
||||||
|
status: 'declined',
|
||||||
|
message: 'Looking for a weekend rental.',
|
||||||
|
dataAiHint: myToys[0]?.category.toLowerCase(),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
return rentalRequests;
|
||||||
}
|
}
|
||||||
|
|
||||||
const rentalRequests: RentalRequest[] = [
|
const currentUserToyRequests = getMockRequests();
|
||||||
{
|
|
||||||
id: 'req1',
|
|
||||||
toy: mockToys[0],
|
|
||||||
requesterName: 'Charlie Brown',
|
|
||||||
requesterId: 'user4',
|
|
||||||
requestedDates: 'August 10, 2024 - August 17, 2024',
|
|
||||||
status: 'pending',
|
|
||||||
message: 'My son would love to play with these for his birthday week! We are very careful with toys and will ensure it is returned in perfect condition. Could we possibly pick it up on the 9th evening?',
|
|
||||||
dataAiHint: mockToys[0]?.category.toLowerCase(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'req2',
|
|
||||||
toy: mockToys[3],
|
|
||||||
requesterName: 'Diana Prince',
|
|
||||||
requesterId: 'user5',
|
|
||||||
requestedDates: 'September 1, 2024 - September 5, 2024',
|
|
||||||
status: 'approved',
|
|
||||||
dataAiHint: mockToys[3]?.category.toLowerCase(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
id: 'req3',
|
|
||||||
toy: mockToys[0],
|
|
||||||
requesterName: 'Edward Nigma',
|
|
||||||
requesterId: 'user6',
|
|
||||||
requestedDates: 'July 20, 2024 - July 22, 2024',
|
|
||||||
status: 'declined',
|
|
||||||
message: 'Looking for a weekend rental.',
|
|
||||||
dataAiHint: mockToys[0]?.category.toLowerCase(),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
const currentUserToyRequests = rentalRequests.filter(req => req.toy.ownerId === 'user1');
|
|
||||||
|
|
||||||
|
|
||||||
export default async function RentalRequestsPage() {
|
export default async function RentalRequestsPage() {
|
||||||
|
|
@ -167,4 +165,3 @@ function RequestItemCard({ request, t }: RequestItemCardProps) {
|
||||||
</Card>
|
</Card>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
|
|
||||||
import db from '@/lib/db';
|
import db from '@/lib/db';
|
||||||
import type { User } from '@/types';
|
import type { User } from '@/types';
|
||||||
import { randomUUID } from 'crypto';
|
|
||||||
import { revalidatePath } from 'next/cache';
|
import { revalidatePath } from 'next/cache';
|
||||||
import { getAllUsers as dbGetAllUsers, getUserById } from '@/data/operations';
|
import { getAllUsers as dbGetAllUsers, getUserById } from '@/data/operations';
|
||||||
|
|
||||||
|
|
@ -25,22 +24,22 @@ export async function registerUser(data: { name: string; nickname?: string; emai
|
||||||
if (existingUser) {
|
if (existingUser) {
|
||||||
return { success: false, message: 'An account with this email already exists.' };
|
return { success: false, message: 'An account with this email already exists.' };
|
||||||
}
|
}
|
||||||
|
|
||||||
const newUser: User = {
|
|
||||||
id: `user-${randomUUID()}`,
|
|
||||||
name,
|
|
||||||
nickname,
|
|
||||||
email,
|
|
||||||
role: role,
|
|
||||||
avatarUrl: '',
|
|
||||||
bio: ''
|
|
||||||
};
|
|
||||||
|
|
||||||
const stmt = db.prepare(
|
const stmt = db.prepare(
|
||||||
'INSERT INTO users (id, name, nickname, email, role, avatarUrl, bio) VALUES (@id, @name, @nickname, @email, @role, @avatarUrl, @bio)'
|
'INSERT INTO users (name, nickname, email, role, avatarUrl, bio) VALUES (@name, @nickname, @email, @role, @avatarUrl, @bio)'
|
||||||
);
|
);
|
||||||
|
|
||||||
stmt.run(newUser);
|
const info = stmt.run({
|
||||||
|
name,
|
||||||
|
nickname: nickname ?? null,
|
||||||
|
email,
|
||||||
|
role: role,
|
||||||
|
avatarUrl: '',
|
||||||
|
bio: ''
|
||||||
|
});
|
||||||
|
|
||||||
|
const newUserId = info.lastInsertRowid as number;
|
||||||
|
const newUser = getUserById(newUserId);
|
||||||
|
|
||||||
revalidatePath('/admin/users');
|
revalidatePath('/admin/users');
|
||||||
|
|
||||||
|
|
@ -96,7 +95,7 @@ interface DeleteUserResult {
|
||||||
message: string;
|
message: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteUser(id: string): Promise<DeleteUserResult> {
|
export async function deleteUser(id: number): Promise<DeleteUserResult> {
|
||||||
try {
|
try {
|
||||||
const user = getUserById(id);
|
const user = getUserById(id);
|
||||||
if (user && (user.email === 'user@example.com' || user.email === 'admin@example.com')) {
|
if (user && (user.email === 'user@example.com' || user.email === 'admin@example.com')) {
|
||||||
|
|
@ -143,7 +142,7 @@ export async function getUserByEmail(email: string): Promise<User | null> {
|
||||||
}
|
}
|
||||||
|
|
||||||
interface UpdateProfileData {
|
interface UpdateProfileData {
|
||||||
id: string;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
nickname?: string;
|
nickname?: string;
|
||||||
avatarUrl?: string;
|
avatarUrl?: string;
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,7 @@ export function getToyById(id: string): Toy | undefined {
|
||||||
return toy ? parseToy(toy) : undefined;
|
return toy ? parseToy(toy) : undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getToysByOwner(ownerId: string): Toy[] {
|
export function getToysByOwner(ownerId: number): Toy[] {
|
||||||
const stmt = db.prepare(`
|
const stmt = db.prepare(`
|
||||||
SELECT t.*, u.name as ownerName, u.avatarUrl as ownerAvatarUrl
|
SELECT t.*, u.name as ownerName, u.avatarUrl as ownerAvatarUrl
|
||||||
FROM toys t
|
FROM toys t
|
||||||
|
|
@ -93,7 +93,7 @@ export function updateToy(toyData: Omit<Toy, 'ownerName' | 'ownerAvatarUrl' | 'd
|
||||||
return getToyById(toyData.id)!;
|
return getToyById(toyData.id)!;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getOwnerProfile(ownerId: string): User | undefined {
|
export function getOwnerProfile(ownerId: number): User | undefined {
|
||||||
return getUserById(ownerId);
|
return getUserById(ownerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -104,7 +104,7 @@ export function getAllUsers(): User[] {
|
||||||
return stmt.all() as User[];
|
return stmt.all() as User[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getUserById(id: string): User | undefined {
|
export function getUserById(id: number): User | undefined {
|
||||||
const stmt = db.prepare('SELECT * FROM users WHERE id = ?');
|
const stmt = db.prepare('SELECT * FROM users WHERE id = ?');
|
||||||
return stmt.get(id) as User | undefined;
|
return stmt.get(id) as User | undefined;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ function initDb() {
|
||||||
// Create Users Table if it doesn't exist
|
// Create Users Table if it doesn't exist
|
||||||
db.exec(`
|
db.exec(`
|
||||||
CREATE TABLE IF NOT EXISTS users (
|
CREATE TABLE IF NOT EXISTS users (
|
||||||
id TEXT PRIMARY KEY,
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||||
name TEXT NOT NULL,
|
name TEXT NOT NULL,
|
||||||
nickname TEXT,
|
nickname TEXT,
|
||||||
email TEXT NOT NULL UNIQUE,
|
email TEXT NOT NULL UNIQUE,
|
||||||
|
|
@ -51,7 +51,7 @@ function initDb() {
|
||||||
category TEXT NOT NULL,
|
category TEXT NOT NULL,
|
||||||
images TEXT,
|
images TEXT,
|
||||||
unavailableRanges TEXT,
|
unavailableRanges TEXT,
|
||||||
ownerId TEXT NOT NULL,
|
ownerId INTEGER NOT NULL,
|
||||||
pricePerDay REAL,
|
pricePerDay REAL,
|
||||||
location TEXT,
|
location TEXT,
|
||||||
FOREIGN KEY (ownerId) REFERENCES users(id) ON DELETE CASCADE
|
FOREIGN KEY (ownerId) REFERENCES users(id) ON DELETE CASCADE
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,13 @@ import { addDays, formatISO, subDays } from 'date-fns';
|
||||||
const today = new Date();
|
const today = new Date();
|
||||||
|
|
||||||
export const rawUsers: User[] = [
|
export const rawUsers: User[] = [
|
||||||
{ id: 'user1', name: 'Alice Wonderland', nickname: 'Alice', email: 'user@example.com', role: 'Admin', avatarUrl: 'https://placehold.co/100x100.png?text=AW', bio: "Lover of imaginative play and sharing joy. I have a collection of classic storybooks and dress-up costumes that my kids have outgrown but still have lots of life left in them!" },
|
{ id: 1, name: 'Alice Wonderland', nickname: 'Alice', email: 'user@example.com', role: 'Admin', avatarUrl: 'https://placehold.co/100x100.png?text=AW', bio: "Lover of imaginative play and sharing joy. I have a collection of classic storybooks and dress-up costumes that my kids have outgrown but still have lots of life left in them!" },
|
||||||
{ id: 'user2', name: 'Bob The Builder', nickname: 'Bob', email: 'user2@example.com', role: 'User', avatarUrl: 'https://placehold.co/100x100.png?text=BT', bio: "Can we fix it? Yes, we can! Sharing my collection of construction toys, tools, and playsets. Always happy to help another budding builder." },
|
{ id: 2, name: 'Bob The Builder', nickname: 'Bob', email: 'user2@example.com', role: 'User', avatarUrl: 'https://placehold.co/100x100.png?text=BT', bio: "Can we fix it? Yes, we can! Sharing my collection of construction toys, tools, and playsets. Always happy to help another budding builder." },
|
||||||
{ id: 'user3', name: 'Carol Danvers', nickname: 'Captain Marvel', email: 'user3@example.com', role: 'User', avatarUrl: 'https://placehold.co/100x100.png?text=CD', bio: "Higher, further, faster. Sharing toys that inspire adventure, courage, and exploration. My collection includes superhero action figures and space-themed playsets." },
|
{ id: 3, name: 'Carol Danvers', nickname: 'Captain Marvel', email: 'user3@example.com', role: 'User', avatarUrl: 'https://placehold.co/100x100.png?text=CD', bio: "Higher, further, faster. Sharing toys that inspire adventure, courage, and exploration. My collection includes superhero action figures and space-themed playsets." },
|
||||||
{ id: 'user4', name: 'Charlie Brown', nickname: 'Chuck', email: 'user4@example.com', role: 'User', avatarUrl: '', bio: '' },
|
{ id: 4, name: 'Charlie Brown', nickname: 'Chuck', email: 'user4@example.com', role: 'User', avatarUrl: '', bio: '' },
|
||||||
{ id: 'user5', name: 'Diana Prince', nickname: 'Wonder Woman', email: 'user5@example.com', role: 'User', avatarUrl: '', bio: '' },
|
{ id: 5, name: 'Diana Prince', nickname: 'Wonder Woman', email: 'user5@example.com', role: 'User', avatarUrl: '', bio: '' },
|
||||||
{ id: 'user6', name: 'Edward Nigma', nickname: 'Riddler', email: 'user6@example.com', role: 'User', avatarUrl: '', bio: '' },
|
{ id: 6, name: 'Edward Nigma', nickname: 'Riddler', email: 'user6@example.com', role: 'User', avatarUrl: '', bio: '' },
|
||||||
{ id: 'admin-main', name: 'Main Admin', nickname: 'Head Honcho', email: 'admin@example.com', role: 'Admin', avatarUrl: 'https://placehold.co/100x100.png?text=ADM', bio: 'Keeping the toy box tidy.' },
|
{ id: 7, name: 'Main Admin', nickname: 'Head Honcho', email: 'admin@example.com', role: 'Admin', avatarUrl: 'https://placehold.co/100x100.png?text=ADM', bio: 'Keeping the toy box tidy.' },
|
||||||
];
|
];
|
||||||
|
|
||||||
export const rawToys: Omit<Toy, 'ownerName' | 'ownerAvatarUrl' | 'dataAiHint'>[] = [
|
export const rawToys: Omit<Toy, 'ownerName' | 'ownerAvatarUrl' | 'dataAiHint'>[] = [
|
||||||
|
|
@ -25,7 +25,7 @@ export const rawToys: Omit<Toy, 'ownerName' | 'ownerAvatarUrl' | 'dataAiHint'>[]
|
||||||
{ startDate: formatISO(addDays(today, 5), { representation: 'date' }), endDate: formatISO(addDays(today, 7), { representation: 'date' }) },
|
{ startDate: formatISO(addDays(today, 5), { representation: 'date' }), endDate: formatISO(addDays(today, 7), { representation: 'date' }) },
|
||||||
{ startDate: formatISO(addDays(today, 15), { representation: 'date' }), endDate: formatISO(addDays(today, 16), { representation: 'date' }) },
|
{ startDate: formatISO(addDays(today, 15), { representation: 'date' }), endDate: formatISO(addDays(today, 16), { representation: 'date' }) },
|
||||||
],
|
],
|
||||||
ownerId: 'user1',
|
ownerId: 1,
|
||||||
pricePerDay: 5,
|
pricePerDay: 5,
|
||||||
location: 'Springfield Gardens',
|
location: 'Springfield Gardens',
|
||||||
},
|
},
|
||||||
|
|
@ -38,7 +38,7 @@ export const rawToys: Omit<Toy, 'ownerName' | 'ownerAvatarUrl' | 'dataAiHint'>[]
|
||||||
unavailableRanges: [
|
unavailableRanges: [
|
||||||
{ startDate: formatISO(addDays(today, 10), { representation: 'date' }), endDate: formatISO(addDays(today, 12), { representation: 'date' }) },
|
{ startDate: formatISO(addDays(today, 10), { representation: 'date' }), endDate: formatISO(addDays(today, 12), { representation: 'date' }) },
|
||||||
],
|
],
|
||||||
ownerId: 'user2',
|
ownerId: 2,
|
||||||
pricePerDay: 8,
|
pricePerDay: 8,
|
||||||
location: 'Willow Creek',
|
location: 'Willow Creek',
|
||||||
},
|
},
|
||||||
|
|
@ -49,7 +49,7 @@ export const rawToys: Omit<Toy, 'ownerName' | 'ownerAvatarUrl' | 'dataAiHint'>[]
|
||||||
category: 'Electronics',
|
category: 'Electronics',
|
||||||
images: ['https://placehold.co/600x400.png?text=Kids+Tablet', 'https://placehold.co/600x400.png?text=Tablet+Screen'],
|
images: ['https://placehold.co/600x400.png?text=Kids+Tablet', 'https://placehold.co/600x400.png?text=Tablet+Screen'],
|
||||||
unavailableRanges: [],
|
unavailableRanges: [],
|
||||||
ownerId: 'user3',
|
ownerId: 3,
|
||||||
pricePerDay: 7,
|
pricePerDay: 7,
|
||||||
location: 'Metro City',
|
location: 'Metro City',
|
||||||
},
|
},
|
||||||
|
|
@ -62,7 +62,7 @@ export const rawToys: Omit<Toy, 'ownerName' | 'ownerAvatarUrl' | 'dataAiHint'>[]
|
||||||
unavailableRanges: [
|
unavailableRanges: [
|
||||||
{ startDate: formatISO(addDays(today, 20), { representation: 'date' }), endDate: formatISO(addDays(today, 25), { representation: 'date' }) },
|
{ startDate: formatISO(addDays(today, 20), { representation: 'date' }), endDate: formatISO(addDays(today, 25), { representation: 'date' }) },
|
||||||
],
|
],
|
||||||
ownerId: 'user1',
|
ownerId: 1,
|
||||||
pricePerDay: 3,
|
pricePerDay: 3,
|
||||||
location: 'Springfield Gardens',
|
location: 'Springfield Gardens',
|
||||||
},
|
},
|
||||||
|
|
@ -73,7 +73,7 @@ export const rawToys: Omit<Toy, 'ownerName' | 'ownerAvatarUrl' | 'dataAiHint'>[]
|
||||||
category: 'Musical',
|
category: 'Musical',
|
||||||
images: ['https://placehold.co/600x400.png?text=Kids+Guitar'],
|
images: ['https://placehold.co/600x400.png?text=Kids+Guitar'],
|
||||||
unavailableRanges: [],
|
unavailableRanges: [],
|
||||||
ownerId: 'user2',
|
ownerId: 2,
|
||||||
pricePerDay: 10,
|
pricePerDay: 10,
|
||||||
location: 'Willow Creek',
|
location: 'Willow Creek',
|
||||||
},
|
},
|
||||||
|
|
@ -84,7 +84,7 @@ export const rawToys: Omit<Toy, 'ownerName' | 'ownerAvatarUrl' | 'dataAiHint'>[]
|
||||||
category: 'Outdoor',
|
category: 'Outdoor',
|
||||||
images: ['https://placehold.co/600x400.png?text=Sports+Kit'],
|
images: ['https://placehold.co/600x400.png?text=Sports+Kit'],
|
||||||
unavailableRanges: [],
|
unavailableRanges: [],
|
||||||
ownerId: 'user3',
|
ownerId: 3,
|
||||||
pricePerDay: 6,
|
pricePerDay: 6,
|
||||||
location: 'Metro City',
|
location: 'Metro City',
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
export interface MessageEntry {
|
export interface MessageEntry {
|
||||||
id: string;
|
id: string;
|
||||||
senderId: string;
|
senderId: number;
|
||||||
senderName: string;
|
senderName: string;
|
||||||
text: string;
|
text: string;
|
||||||
timestamp: string; // ISO date string
|
timestamp: string; // ISO date string
|
||||||
|
|
@ -15,7 +15,7 @@ export interface Toy {
|
||||||
images: string[];
|
images: string[];
|
||||||
unavailableRanges: { startDate: string; endDate: string }[];
|
unavailableRanges: { startDate: string; endDate: string }[];
|
||||||
ownerName: string;
|
ownerName: string;
|
||||||
ownerId: string;
|
ownerId: number;
|
||||||
ownerAvatarUrl?: string;
|
ownerAvatarUrl?: string;
|
||||||
pricePerDay?: number;
|
pricePerDay?: number;
|
||||||
location?: string;
|
location?: string;
|
||||||
|
|
@ -23,7 +23,7 @@ export interface Toy {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface User {
|
export interface User {
|
||||||
id: string;
|
id: number;
|
||||||
name: string; // This is now Full Name
|
name: string; // This is now Full Name
|
||||||
nickname?: string;
|
nickname?: string;
|
||||||
email: string;
|
email: string;
|
||||||
|
|
@ -40,7 +40,7 @@ export interface DailyAvailability {
|
||||||
|
|
||||||
export interface RentalHistoryEntry {
|
export interface RentalHistoryEntry {
|
||||||
id:string;
|
id:string;
|
||||||
userId: string;
|
userId: number;
|
||||||
toy: Toy;
|
toy: Toy;
|
||||||
rentalStartDate: string;
|
rentalStartDate: string;
|
||||||
rentalEndDate: string;
|
rentalEndDate: string;
|
||||||
|
|
@ -53,7 +53,7 @@ export interface RentalRequest {
|
||||||
id: string;
|
id: string;
|
||||||
toy: Toy;
|
toy: Toy;
|
||||||
requesterName: string;
|
requesterName: string;
|
||||||
requesterId: string;
|
requesterId: number;
|
||||||
requestedDates: string;
|
requestedDates: string;
|
||||||
status: 'pending' | 'approved' | 'declined';
|
status: 'pending' | 'approved' | 'declined';
|
||||||
message?: string;
|
message?: string;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue