chore: add all the code from original repo

This commit is contained in:
Riccardo
2024-05-23 16:55:29 +02:00
parent d8f9a215eb
commit 85d66215a7
66 changed files with 16668 additions and 122 deletions

View File

@@ -0,0 +1,68 @@
import { TagsAction } from '@/components/Settings/Tags/actions/TagsAction';
import { Button, Dialog, DialogContent, DialogTitle } from '@mui/material';
import { useEffect, useState } from 'react';
import { useFormState } from 'react-dom';
import { Tags } from '../../../../data/types';
import { CreateItemAction } from './actions/CreateItemAction';
import { CreateItemForm } from './CreateItemForm';
interface CreateItemProps {
open: boolean;
close: (created: boolean) => void;
profile: string | undefined;
}
export default function CreateItemDialog({
open,
close,
profile
}: CreateItemProps) {
const [tags, setTags] = useState<Tags>([]);
const [formState, formAction] = useFormState(CreateItemAction, {
open: true,
profile
});
useEffect(() => {
const updateTags = async () => {
if (profile) {
try {
const updatedTags = await TagsAction({ selectedProfile: profile });
setTags(updatedTags);
} catch (error) {
console.error("Couldn't fetch tags.");
}
}
};
updateTags();
}, [profile]);
useEffect(() => {
if (!formState.open) {
close(true);
}
}, [open, close, formState]);
const handleClose = async () => {
close(false);
};
return (
<Dialog open={open} onClose={handleClose}>
<DialogTitle sx={{ alignSelf: 'center' }}>Create a new item</DialogTitle>
<DialogContent sx={{ width: '400px' }}>
<CreateItemForm profile={profile} formAction={formAction} tags={tags} />
<Button
variant="outlined"
color="primary"
fullWidth
onClick={handleClose}
>
Close
</Button>
</DialogContent>
</Dialog>
);
}

View File

@@ -0,0 +1,89 @@
import { CreateButton } from '@/components/UI/CreateButton';
import {
Checkbox,
FormControl,
FormControlLabel,
InputLabel,
MenuItem,
Select,
SelectChangeEvent,
Stack,
TextField
} from '@mui/material';
import { Currency } from '@prisma/client';
import { useState } from 'react';
import { Tag } from '../../../../data/types';
interface CreateItemProps {
profile: string | undefined;
formAction: (payload: FormData) => void;
tags: Tag[];
}
export function CreateItemForm({ profile, formAction, tags }: CreateItemProps) {
const [selectedTag, setSelectedTag] = useState('');
const handleTagChange = (event: SelectChangeEvent<string>) => {
setSelectedTag(event.target.value as string);
};
return (
<form action={formAction}>
<Stack spacing={2} my={2}>
<TextField name="name" label="Item" variant="outlined" required />
<TextField name="description" label="Description" variant="outlined" />
<TextField
name="price"
label="Price"
variant="outlined"
required
type="number"
inputProps={{ defaultValue: 0, step: 0.01, min: 0 }}
/>
<FormControl variant="outlined">
<InputLabel id="currency-label">Currency</InputLabel>
<Select
name="currency"
label="Currency"
labelId="currency-label"
value={Currency.DKK}
>
{Object.values(Currency).map((value) => (
<MenuItem key={value} value={value}>
{value}
</MenuItem>
))}
</Select>
</FormControl>
{profile && (
<FormControl variant="outlined">
<InputLabel id="tag-label">Tag</InputLabel>
<Select
name="tag"
label="Tag"
labelId="tag-label"
value={selectedTag} // Use the state here
onChange={handleTagChange}
>
{tags.map((tag) => (
<MenuItem key={tag.id} value={tag.id}>
{tag.name}
</MenuItem>
))}
</Select>
</FormControl>
)}
<TextField name="body" label="Comment" variant="outlined" />
<TextField
name="score"
label="Score"
variant="outlined"
type="number"
inputProps={{ step: 1, min: 0, max: 10 }}
/>
<FormControlLabel control={<Checkbox name="regret" />} label="Regret" />
<CreateButton />
</Stack>
</form>
);
}

View File

@@ -0,0 +1,76 @@
'use server';
import { nanoid } from 'nanoid';
import { initializeUser } from '../../../../../data/initializeUser';
import { CreateItemFormSchema } from '../../../../../data/types';
import prisma from '../../../../../prisma/prisma';
interface CreateItemActionProps {
open: boolean;
profile?: string;
error?: string;
}
export async function CreateItemAction(
{ profile }: CreateItemActionProps,
formData: FormData
) {
await initializeUser();
const profileId = profile ?? (await prisma.profile.findFirst())?.id;
const formDataObj = Object.fromEntries(formData.entries());
const validatedBody = CreateItemFormSchema.safeParse(formDataObj);
if (!validatedBody.success || !profileId) {
throw new Error('Bad request');
}
const { name, description, price, currency, tag, body, score, regret } =
validatedBody.data;
const newId = nanoid();
try {
await prisma.$transaction([
prisma.item.create({
data: {
id: newId,
name,
description,
price,
currency,
Profile: {
connect: {
id: profileId
}
},
Tag: tag
? {
connect: {
id: tag
}
}
: undefined
}
}),
prisma.itemComment.create({
data: {
body,
score,
regret,
Item: {
connect: {
id: newId
}
}
}
})
]);
} catch (error) {
throw new Error(`Failed to create item`);
}
return { open: false, profile: profileId };
}