diff --git a/app/(sharing)/[token]/[id]/page.tsx b/app/(sharing)/[token]/[id]/page.tsx index 9198a23..e213d34 100644 --- a/app/(sharing)/[token]/[id]/page.tsx +++ b/app/(sharing)/[token]/[id]/page.tsx @@ -41,77 +41,86 @@ export default async function Share({ const chunithm: chunithm[] = songsData.filter((song) => playlogIds.includes(song.id), ); + return ( -
-
- {chunithm.map((song) => ( -
- - Song: {song.title} - -
- ))} -
- -
- {chunithm.map((song) => ( -
- - Artist: {song.artist} - -
- ))} -
- -
- {chunithm.map((song) => ( -
- - Score: {song.score?.toLocaleString()} - -
- ))} -
- -
- {chunithm.map((song) => ( -
- - Rank: {getGrade(song.score ?? 0)} - -
- ))} -
- -
- {chunithm.map((song) => ( -
- - {song.isFullCombo && "FULL COMBO!"} - - - Max combo: {song.maxCombo} - -
- ))} -
- -
- {chunithm.map((song) => ( -
-
- - Judge Justice: {song.judgeJustice} - - - Judge Attack: {song.judgeAttack} - - - Miss: {song.judgeGuilty} +
+
+
+ {chunithm.map((song) => ( +
+ + Song: {song.title}
-
- ))} + ))} +
+ +
+ {chunithm.map((song) => ( +
+ + Artist: {song.artist} + +
+ ))} +
+ +
+ {chunithm.map((song) => ( +
+ + Score: {song.score?.toLocaleString()} + +
+ ))} +
+ +
+ {chunithm.map((song) => ( +
+ + Rank: {getGrade(song.score ?? 0)} + +
+ ))} +
+ +
+ {chunithm.map((song) => ( +
+ + {song.isFullCombo && "FULL COMBO!"} + +
+ + Max combo: {song.maxCombo} + +
+
+ ))} +
+ +
+ {chunithm.map((song) => ( +
+
+ + Justice Critcal: {song.judgeCritical! + song.judgeHeaven!} + + + Justice: {song.judgeJustice} + + + + Attack: {song.judgeAttack} + + + Miss: {song.judgeGuilty} + +
+
+ ))} +
); diff --git a/app/favicon.ico b/app/favicon.ico deleted file mode 100644 index 718d6fe..0000000 Binary files a/app/favicon.ico and /dev/null differ diff --git a/app/layout.tsx b/app/layout.tsx index ccdc3e9..47088a7 100644 --- a/app/layout.tsx +++ b/app/layout.tsx @@ -15,6 +15,12 @@ export default function RootLayout({ }>) { return ( + + + + + {" "} +
{children}
diff --git a/components/scoreplaylog/action.ts b/components/scoreplaylog/action.ts index 4880ae8..40684a2 100644 --- a/components/scoreplaylog/action.ts +++ b/components/scoreplaylog/action.ts @@ -1,11 +1,150 @@ "use server"; import { artemis } from "@/lib/prisma"; +import { chuni_score_best } from "@/prisma/schemas/artemis/generated/artemis"; import type * as Prisma from "@prisma/client"; type ChuniScorePlaylog = Prisma.PrismaClient; type ChuniStaticMusic = Prisma.PrismaClient; +export async function getSongsWithTitles(userId: number) { + try { + const songs: ChuniScorePlaylog[] = + await artemis.chuni_score_playlog.findMany({ + where: { + user: userId, + }, + orderBy: { + userPlayDate: "desc", + }, + select: { + id: true, + maxCombo: true, + userPlayDate: true, + isFullCombo: true, + playerRating: true, + isAllJustice: true, + score: true, + judgeHeaven: true, + judgeGuilty: true, + judgeJustice: true, + judgeAttack: true, + judgeCritical: true, + isClear: true, + skillId: true, + skillEffect: true, + skillLevel: true, + isNewRecord: true, + musicId: true, + level: true, + rateAir: true, + rateHold: true, + rateFlick: true, + rateSlide: true, + rateTap: true, + romVersion: true, + eventId: true, + characterId: true, + charaIllustId: true, + track: true, + isContinue: true, + isFreeToPlay: true, + playKind: true, + playDate: true, + orderId: true, + sortNumber: true, + user: true, + placeId: true, + ticketId: true, + }, + }); + + const chuniScorePlaylogMusicId = songs + .map((song) => song.musicId) + .filter((id): id is number => id !== null); + + const staticMusicInfo: ChuniStaticMusic[] = + await artemis.chuni_static_music.findMany({ + where: { + songId: { + in: chuniScorePlaylogMusicId, + }, + }, + select: { + songId: true, + title: true, + artist: true, + chartId: true, + level: true, + genre: true, + worldsEndTag: true, + jacketPath: true, + }, + }); + + const chuniScoreBest: chuni_score_best[] = + await artemis.chuni_score_best.findMany({ + where: { + musicId: { + in: chuniScorePlaylogMusicId, + }, + }, + select: { + id: true, + user: true, + musicId: true, + level: true, + playCount: true, + scoreMax: true, + resRequestCount: true, + resAcceptCount: true, + resSuccessCount: true, + missCount: true, + maxComboCount: true, + isFullCombo: true, + isAllJustice: true, + isSuccess: true, + fullChain: true, + maxChain: true, + scoreRank: true, + isLock: true, + ext1: true, + theoryCount: true, + }, + }); + + const songsWithTitles = songs.map((song) => { + const staticInfo = staticMusicInfo.find( + (chuniStaticMusic) => + chuniStaticMusic.songId === song.musicId && + chuniStaticMusic.chartId === song.level, + ); + + const bestScore = chuniScoreBest.find( + (score) => score.musicId === song.musicId, + ); + + return { + ...song, + title: staticInfo?.title || "Unknown Title", + artist: staticInfo?.artist || "Unknown Artist", + genre: staticInfo?.genre || "Unknown Genre", + chartId: staticInfo?.chartId || "Unknown chartId", + level: staticInfo?.level || "Unknown Level", + chartlevel: song.level || "Unknown Level", + playCount: bestScore?.playCount || 0, + isSuccess: bestScore?.isSuccess || 0, + jacketPath: staticInfo?.jacketPath || "", + }; + }); + + return songsWithTitles; + } catch (error) { + console.error("Error fetching songs with titles:", error); + throw error; + } +} + export async function searchSongWithTitle( userId: number, searchQuery: string = "", @@ -39,32 +178,41 @@ export async function searchSongWithTitle( }, }, select: { + songId: true, title: true, }, }); - const playCounts = await artemis.chuni_score_playlog.groupBy({ - by: ["musicId"], - _count: { - musicId: true, - }, - where: { - user: userId, - musicId: { - in: chuniScorePlaylogMusicId, + const chuniScoreBest: chuni_score_best[] = + await artemis.chuni_score_best.findMany({ + where: { + musicId: { + in: chuniScorePlaylogMusicId, + }, }, - }, - }); - - const playCountMap = playCounts.reduce( - (map, item) => { - if (item.musicId !== null) { - map[item.musicId] = item._count.musicId; - } - return map; - }, - {} as Record, - ); + select: { + id: true, + user: true, + musicId: true, + level: true, + playCount: true, + scoreMax: true, + resRequestCount: true, + resAcceptCount: true, + resSuccessCount: true, + missCount: true, + maxComboCount: true, + isFullCombo: true, + isAllJustice: true, + isSuccess: true, + fullChain: true, + maxChain: true, + scoreRank: true, + isLock: true, + ext1: true, + theoryCount: true, + }, + }); const songsWithTitles = songs.map((song) => { const staticInfo = staticMusicInfo.find( @@ -73,9 +221,14 @@ export async function searchSongWithTitle( chuniStaticMusic.chartId === song.level, ); + const bestScore = chuniScoreBest.find( + (score) => score.musicId === song.musicId, + ); + return { ...song, title: staticInfo?.title || "Unknown Title", + playCount: bestScore?.playCount || 0, }; }); diff --git a/components/scoreplaylog/colums.tsx b/components/scoreplaylog/colums.tsx index 00a3422..77351fc 100644 --- a/components/scoreplaylog/colums.tsx +++ b/components/scoreplaylog/colums.tsx @@ -18,11 +18,11 @@ import { generateShareToken } from "@/app/(sharing)/[token]/token"; import { ArrowUpDown, MoreHorizontalIcon } from "lucide-react"; import { chuni_score_playlog } from "@/prisma/schemas/artemis/generated/artemis"; import { chuni_static_music } from "@/prisma/schemas/artemis/generated/artemis"; +import { chuni_score_best } from "@/prisma/schemas/artemis/generated/artemis"; import { getDifficultyText, getGrade } from "@/lib/helpers"; import { Skeleton } from "../ui/skeleton"; -type chunithm = chuni_score_playlog & - chuni_static_music & { playCount: number }; +type chunithm = chuni_score_playlog & chuni_static_music & chuni_score_best; export const columns: ColumnDef[] = [ { @@ -31,7 +31,7 @@ export const columns: ColumnDef[] = [ cell: ({ row }) => { const jacketPath = row.original.jacketPath?.replace(".dds", ".png"); - const [isLoading, setIsLoading] = useState(true); + return (
{!jacketPath ? ( @@ -40,7 +40,7 @@ export const columns: ColumnDef[] = [ Jacket )} {row.original.title} @@ -53,32 +53,61 @@ export const columns: ColumnDef[] = [ accessorKey: "score", header: ({ column }) => { return ( - ); }, - cell: ({ row }) =>
{row.original.score?.toLocaleString()}
, - sortingFn: (a, b) => { - const highScore = a.original.score ?? 0; - const lowScore = b.original.score ?? 0; + cell: ({ row }) => { + const isSuccess = row.original.isSuccess; + const skillId = row.original.skillId; + let isSuccessText = ""; - return lowScore - highScore; + switch (isSuccess) { + case 0: + isSuccessText = "Not Clear"; + break; + case 1: + isSuccessText = "Clear"; + break; + case 2: + isSuccessText = "Hard"; + break; + case 3: + isSuccessText = "Absolute"; + break; + case 4: + isSuccessText = "Absolute+"; + break; + case 6: + isSuccessText = "Catastrophe"; + break; + default: + isSuccessText = isSuccess?.toString() ?? ""; + break; + } + + return ( +
+ {row.original.score?.toLocaleString()} +
+ {isSuccessText} +
+
+ New!! +
+
+ ); }, }, - { - accessorKey: "isNew", - header: "New", - cell: ({ row }) => ( -
- {row.original.isNewRecord && New!!} -
- ), - }, + { accessorKey: "grade", header: "Grade", @@ -122,14 +151,6 @@ export const columns: ColumnDef[] = [ {row.original.isAllJustice && All Justice}
), - // sortingFn: (a, b) => { - // const isAllJustice = a.original.isAllJustice; - // const defaultSort = b.original.isAllJustice; - - // if (isAllJustice && !defaultSort) return -1; - // if (!isAllJustice && defaultSort) return 1; - // return 0; - // }, }, { @@ -173,13 +194,7 @@ export const columns: ColumnDef[] = [ Actions - {/* - song.title && navigator.clipboard.writeText(song.title) - } - > - Copy song title - */} + Share Song diff --git a/components/scoreplaylog/data-table.tsx b/components/scoreplaylog/data-table.tsx index bd23e66..90d0f8e 100644 --- a/components/scoreplaylog/data-table.tsx +++ b/components/scoreplaylog/data-table.tsx @@ -84,7 +84,7 @@ export function DataTable({ data-state={row.getIsSelected() && "selected"} > {row.getVisibleCells().map((cell) => ( - + {flexRender(cell.column.columnDef.cell, cell.getContext())} ))} @@ -99,7 +99,7 @@ export function DataTable({ )} -
+