feat: mii descriptions
This commit is contained in:
parent
8753358a48
commit
398580e72b
7 changed files with 34 additions and 6 deletions
|
|
@ -0,0 +1,2 @@
|
|||
-- AlterTable
|
||||
ALTER TABLE "miis" ADD COLUMN "description" VARCHAR(256);
|
||||
|
|
@ -64,11 +64,12 @@ model Session {
|
|||
}
|
||||
|
||||
model Mii {
|
||||
id Int @id @default(autoincrement())
|
||||
userId Int
|
||||
name String @db.VarChar(64)
|
||||
imageCount Int @default(0)
|
||||
tags String[]
|
||||
id Int @id @default(autoincrement())
|
||||
userId Int
|
||||
name String @db.VarChar(64)
|
||||
imageCount Int @default(0)
|
||||
tags String[]
|
||||
description String? @db.VarChar(256)
|
||||
|
||||
firstName String
|
||||
lastName String
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ const uploadsDirectory = path.join(process.cwd(), "uploads");
|
|||
const submitSchema = z.object({
|
||||
name: nameSchema,
|
||||
tags: tagsSchema,
|
||||
description: z.string().trim().max(256).optional(),
|
||||
qrBytesRaw: z
|
||||
.array(z.number(), { required_error: "A QR code is required" })
|
||||
.length(372, { message: "QR code size is not a valid Tomodachi Life QR code" }),
|
||||
|
|
@ -54,6 +55,7 @@ export async function POST(request: NextRequest) {
|
|||
const parsed = submitSchema.safeParse({
|
||||
name: formData.get("name"),
|
||||
tags: rawTags,
|
||||
description: formData.get("description"),
|
||||
qrBytesRaw: rawQrBytesRaw,
|
||||
image1: formData.get("image1"),
|
||||
image2: formData.get("image2"),
|
||||
|
|
@ -61,11 +63,12 @@ export async function POST(request: NextRequest) {
|
|||
});
|
||||
|
||||
if (!parsed.success) return rateLimit.sendResponse({ error: parsed.error.errors[0].message }, 400);
|
||||
const { name: uncensoredName, tags: uncensoredTags, qrBytesRaw, image1, image2, image3 } = parsed.data;
|
||||
const { name: uncensoredName, tags: uncensoredTags, description: uncensoredDescription, qrBytesRaw, image1, image2, image3 } = parsed.data;
|
||||
|
||||
// Censor potential inappropriate words
|
||||
const name = profanity.censor(uncensoredName);
|
||||
const tags = uncensoredTags.map((t) => profanity.censor(t));
|
||||
const description = uncensoredDescription && profanity.censor(uncensoredDescription);
|
||||
|
||||
// Validate image files
|
||||
const images: File[] = [];
|
||||
|
|
@ -97,6 +100,7 @@ export async function POST(request: NextRequest) {
|
|||
userId: Number(session.user.id),
|
||||
name,
|
||||
tags,
|
||||
description,
|
||||
|
||||
firstName: conversion.tomodachiLifeMii.firstName,
|
||||
lastName: conversion.tomodachiLifeMii.lastName,
|
||||
|
|
|
|||
|
|
@ -200,6 +200,9 @@ export default async function MiiPage({ params }: Props) {
|
|||
{mii.createdAt.toLocaleTimeString("en-GB", { timeZone: "UTC" })} UTC
|
||||
</h4>
|
||||
</div>
|
||||
|
||||
{/* Description */}
|
||||
{mii.description && <p className="text-sm mt-2 ml-2 bg-white/50 p-3 rounded-lg border border-orange-200">{mii.description}</p>}
|
||||
</div>
|
||||
|
||||
{/* Buttons */}
|
||||
|
|
|
|||
|
|
@ -65,6 +65,7 @@ export default function ReportMiiForm({ mii, likes }: Props) {
|
|||
</label>
|
||||
<textarea
|
||||
rows={3}
|
||||
maxLength={256}
|
||||
placeholder="Type notes here for the report..."
|
||||
className="pill input !rounded-xl resize-none col-span-2"
|
||||
value={notes}
|
||||
|
|
|
|||
|
|
@ -69,6 +69,7 @@ export default function ReportUserForm({ user }: Props) {
|
|||
</label>
|
||||
<textarea
|
||||
rows={3}
|
||||
maxLength={256}
|
||||
placeholder="Type notes here for the report..."
|
||||
className="pill input !rounded-xl resize-none col-span-2"
|
||||
value={notes}
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ export default function SubmitForm() {
|
|||
|
||||
const [name, setName] = useState("");
|
||||
const [tags, setTags] = useState<string[]>([]);
|
||||
const [description, setDescription] = useState("");
|
||||
const [qrBytesRaw, setQrBytesRaw] = useState<number[]>([]);
|
||||
|
||||
const handleSubmit = async () => {
|
||||
|
|
@ -68,6 +69,7 @@ export default function SubmitForm() {
|
|||
const formData = new FormData();
|
||||
formData.append("name", name);
|
||||
formData.append("tags", JSON.stringify(tags));
|
||||
formData.append("description", description);
|
||||
formData.append("qrBytesRaw", JSON.stringify(qrBytesRaw));
|
||||
files.forEach((file, index) => {
|
||||
// image1, image2, etc.
|
||||
|
|
@ -190,6 +192,20 @@ export default function SubmitForm() {
|
|||
<TagSelector tags={tags} setTags={setTags} />
|
||||
</div>
|
||||
|
||||
<div className="w-full grid grid-cols-3 items-start">
|
||||
<label htmlFor="reason-note" className="font-semibold py-2">
|
||||
Description
|
||||
</label>
|
||||
<textarea
|
||||
rows={3}
|
||||
maxLength={256}
|
||||
placeholder="(optional) Type a description..."
|
||||
className="pill input !rounded-xl resize-none col-span-2"
|
||||
value={description}
|
||||
onChange={(e) => setDescription(e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Separator */}
|
||||
<div className="flex items-center gap-4 text-zinc-500 text-sm font-medium mt-8 mb-2">
|
||||
<hr className="flex-grow border-zinc-300" />
|
||||
|
|
|
|||
Loading…
Reference in a new issue