From fc4a20c1fc1e8900da51acead443df16389441c7 Mon Sep 17 00:00:00 2001 From: Andres Date: Sun, 8 Jun 2025 15:34:42 +0200 Subject: [PATCH] wip --- bun.lock | 3 + package.json | 1 + src/app/(home)/admin/releases/page.tsx | 6 +- .../(home)/admin/releases/releases-client.tsx | 398 ++++++++++++++++-- src/server/api/routers/releases.ts | 46 ++ src/server/db/schema.ts | 2 + 6 files changed, 422 insertions(+), 34 deletions(-) diff --git a/bun.lock b/bun.lock index b3ebcf4..8faeae4 100644 --- a/bun.lock +++ b/bun.lock @@ -77,6 +77,7 @@ "tailwind-merge": "^3.1.0", "tw-animate-css": "^1.2.5", "vaul": "^1.1.2", + "zlib": "^1.0.5", "zod": "^3.24.2", }, "devDependencies": { @@ -1129,6 +1130,8 @@ "which": ["which@4.0.0", "", { "dependencies": { "isexe": "^3.1.1" }, "bin": { "node-which": "bin/which.js" } }, "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg=="], + "zlib": ["zlib@1.0.5", "", {}, "sha512-40fpE2II+Cd3k8HWTWONfeKE2jL+P42iWJ1zzps5W51qcTsOUKM5Q5m2PFb0CLxlmFAaUuUdJGc3OfZy947v0w=="], + "zod": ["zod@3.24.2", "", {}, "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ=="], "zwitch": ["zwitch@2.0.4", "", {}, "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A=="], diff --git a/package.json b/package.json index cf33c60..1818d23 100644 --- a/package.json +++ b/package.json @@ -92,6 +92,7 @@ "tailwind-merge": "^3.1.0", "tw-animate-css": "^1.2.5", "vaul": "^1.1.2", + "zlib": "^1.0.5", "zod": "^3.24.2" }, "devDependencies": { diff --git a/src/app/(home)/admin/releases/page.tsx b/src/app/(home)/admin/releases/page.tsx index baebd2d..c1c5c86 100644 --- a/src/app/(home)/admin/releases/page.tsx +++ b/src/app/(home)/admin/releases/page.tsx @@ -22,7 +22,11 @@ export default async function ReleasesPage() { return ( -
+
diff --git a/src/app/(home)/admin/releases/releases-client.tsx b/src/app/(home)/admin/releases/releases-client.tsx index 8282cc9..1c74bcc 100644 --- a/src/app/(home)/admin/releases/releases-client.tsx +++ b/src/app/(home)/admin/releases/releases-client.tsx @@ -1,9 +1,34 @@ 'use client' +import { + AlertDialog, + AlertDialogAction, + AlertDialogCancel, + AlertDialogContent, + AlertDialogDescription, + AlertDialogFooter, + AlertDialogHeader, + AlertDialogTitle, +} from '@/components/ui/alert-dialog' import { Button } from '@/components/ui/button' -import { Card, CardContent } from '@/components/ui/card' +import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card' +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, +} from '@/components/ui/dialog' import { Input } from '@/components/ui/input' import { Label } from '@/components/ui/label' +import { + Select, + SelectContent, + SelectItem, + SelectTrigger, + SelectValue, +} from '@/components/ui/select' import { Table, TableBody, @@ -12,79 +37,386 @@ import { TableHeader, TableRow, } from '@/components/ui/table' +import { Textarea } from '@/components/ui/textarea' import { api } from '@/trpc/react' +import { Pencil, Trash2 } from 'lucide-react' +import { useEffect, useState } from 'react' import { useForm } from 'react-hook-form' +import { toast } from 'sonner' + export function ReleasesClient() { + const utils = api.useUtils() const [releases] = api.releases.getReleases.useSuspenseQuery() - const addRelease = api.releases.addRelease.useMutation() + const addRelease = api.releases.addRelease.useMutation({ + onSuccess: () => { + utils.releases.getReleases.invalidate() + toast.success('Release added successfully') + form.reset() + }, + onError: (error) => { + toast.error(`Error adding release: ${error.message}`) + }, + }) + const updateRelease = api.releases.updateRelease.useMutation({ + onSuccess: () => { + utils.releases.getReleases.invalidate() + toast.success('Release updated successfully') + setEditDialogOpen(false) + }, + onError: (error) => { + toast.error(`Error updating release: ${error.message}`) + }, + }) + const deleteRelease = api.releases.deleteRelease.useMutation({ + onSuccess: () => { + utils.releases.getReleases.invalidate() + toast.success('Release deleted successfully') + setDeleteDialogOpen(false) + }, + onError: (error) => { + toast.error(`Error deleting release: ${error.message}`) + }, + }) + + const [smodsVersions, setSmodsVersions] = useState(['latest']) + const [lovelyVersions, setLovelyVersions] = useState(['latest']) + const [editDialogOpen, setEditDialogOpen] = useState(false) + const [deleteDialogOpen, setDeleteDialogOpen] = useState(false) + const [selectedRelease, setSelectedRelease] = useState< + (typeof releases)[0] | null + >(null) + + const SMODS_RELEASES_URL = + 'https://api.github.com/repos/Steamodded/smods/releases' + const LOVELY_RELEASES_BASE_URL = + 'https://github.com/ethangreen-dev/lovely-injector/releases' + + useEffect(() => { + // Fetch Steamodded versions + fetch(SMODS_RELEASES_URL) + .then((response) => response.json()) + .then((data) => { + const versions = data.map((release: any) => release.tag_name) + setSmodsVersions(['latest', ...versions]) + }) + .catch((error) => { + console.error('Error fetching Steamodded versions:', error) + }) + + // Fetch lovely injector versions + // Since we don't have a direct API for lovely injector, we'll use GitHub API + fetch( + 'https://api.github.com/repos/ethangreen-dev/lovely-injector/releases' + ) + .then((response) => response.json()) + .then((data) => { + const versions = data.map((release: any) => release.tag_name) + setLovelyVersions(['latest', ...versions]) + }) + .catch((error) => { + console.error('Error fetching lovely injector versions:', error) + }) + }, []) + const form = useForm({ defaultValues: { name: '', version: '', description: '', url: '', + smods_version: 'latest', + lovely_version: 'latest', }, }) + + const editForm = useForm({ + defaultValues: { + id: 0, + name: '', + version: '', + description: '', + url: '', + smods_version: 'latest', + lovely_version: 'latest', + }, + }) + + const handleEditRelease = (release: (typeof releases)[0]) => { + setSelectedRelease(release) + editForm.reset({ + id: release.id, + name: release.name, + version: release.version, + description: release.description || '', + url: release.url, + smods_version: release.smods_version || 'latest', + lovely_version: release.lovely_version || 'latest', + }) + setEditDialogOpen(true) + } + + const handleDeleteRelease = (release: (typeof releases)[0]) => { + setSelectedRelease(release) + setDeleteDialogOpen(true) + } return ( -
-

Releases

-
- +
+

Releases

+
+
- + Name Version Description URL + Steamodded Version + Lovely Injector Version + Actions {releases.map((release) => ( - - {release.name} + + {release.name} {release.version} - {release.description} - + +
+ {release.description} +
+
+ - {release.url} +
{release.url}
+ {release.smods_version || 'latest'} + {release.lovely_version || 'latest'} + + + +
))}
- - + +
+
+

Add New Release

addRelease.mutate(values))} > -
- - +
+ +
-
- - +
+ +
-
- - +
+ +