diff --git a/src/actions/chuni/playlog.ts b/src/actions/chuni/playlog.ts index 76123f4..3751a00 100644 --- a/src/actions/chuni/playlog.ts +++ b/src/actions/chuni/playlog.ts @@ -1,11 +1,11 @@ 'use server'; import { requireUser } from '@/actions/auth'; +import { PlaylogFilterState } from '@/app/(with-header)/chuni/playlog/page'; import { db } from '@/db'; import { CHUNI_MUSIC_PROPERTIES } from '@/helpers/chuni/music'; import { chuniRating } from '@/helpers/chuni/rating'; import { sql } from 'kysely'; -import { PlaylogFilterState } from '@/components/chuni/playlog-list'; const SORT_KEYS = { Date: 'id', diff --git a/src/components/login-card.tsx b/src/app/(centered)/auth/login/login-card.tsx similarity index 100% rename from src/components/login-card.tsx rename to src/app/(centered)/auth/login/login-card.tsx diff --git a/src/app/(centered)/auth/login/page.tsx b/src/app/(centered)/auth/login/page.tsx index 6b2832a..faa729b 100644 --- a/src/app/(centered)/auth/login/page.tsx +++ b/src/app/(centered)/auth/login/page.tsx @@ -1,6 +1,6 @@ import { PageProps } from '@/types/page'; import { headers } from 'next/headers'; -import { LoginCard } from '@/components/login-card'; +import { LoginCard } from './login-card'; export default async function LoginPage({ searchParams }: PageProps) { const referer = headers().get('referer'); diff --git a/src/app/(centered)/auth/register/page.tsx b/src/app/(centered)/auth/register/page.tsx index e87152f..1b14cb0 100644 --- a/src/app/(centered)/auth/register/page.tsx +++ b/src/app/(centered)/auth/register/page.tsx @@ -1,5 +1,5 @@ import { PageProps } from '@/types/page'; -import { RegisterCard } from '@/components/register-card'; +import { RegisterCard } from './register-card'; export default async function RegisterPage({ searchParams }: PageProps) { return () diff --git a/src/components/register-card.tsx b/src/app/(centered)/auth/register/register-card.tsx similarity index 100% rename from src/components/register-card.tsx rename to src/app/(centered)/auth/register/register-card.tsx diff --git a/src/components/admin-user-list.tsx b/src/app/(with-header)/admin/users/admin-user-list.tsx similarity index 95% rename from src/components/admin-user-list.tsx rename to src/app/(with-header)/admin/users/admin-user-list.tsx index 9124458..6442965 100644 --- a/src/components/admin-user-list.tsx +++ b/src/app/(with-header)/admin/users/admin-user-list.tsx @@ -1,23 +1,23 @@ 'use client'; import { createUserWithAccessCode, deleteUser, setUserPermissions } from '@/actions/user'; -import { PermissionEditModal } from './permission-edit-modal'; +import { PermissionEditModal } from '@/components/permission-edit-modal'; import { useState } from 'react'; import { USER_PERMISSION_NAMES, UserPermissions } from '@/types/permissions'; import { Button, Divider, Tooltip, Input, Accordion, AccordionItem, Link, Spacer } from '@nextui-org/react'; import { ChevronDownIcon, CreditCardIcon, PencilSquareIcon, PlusIcon } from '@heroicons/react/24/outline'; -import { usePromptModal } from './prompt-modal'; +import { usePromptModal } from '@/components/prompt-modal'; import { ArrowPathIcon } from '@heroicons/react/24/outline'; import { generateAccessCode } from '@/helpers/access-code'; import { useUser } from '@/helpers/use-user'; import { TbBrandAppleArcade, TbCrown, TbFileSettings, TbUserShield } from 'react-icons/tb'; import { hasPermission } from '@/helpers/permissions'; -import { AimeCard } from './aime-card'; -import { useErrorModal } from './error-modal'; +import { AimeCard } from '@/components/aime-card'; +import { useErrorModal } from '@/components/error-modal'; import { AdminUser } from '@/data/user'; import { adminAddCardToUser } from '@/actions/card'; import { TrashIcon } from '@heroicons/react/24/outline'; -import { useConfirmModal } from './confirm-modal'; +import { useConfirmModal } from '@/components/confirm-modal'; const PERMISSION_ICONS = new Map([ [UserPermissions.USERMOD, TbUserShield], diff --git a/src/app/(with-header)/admin/users/page.tsx b/src/app/(with-header)/admin/users/page.tsx index e0e5675..15d6d3d 100644 --- a/src/app/(with-header)/admin/users/page.tsx +++ b/src/app/(with-header)/admin/users/page.tsx @@ -1,6 +1,6 @@ import { requireUser } from '@/actions/auth'; import { UserPermissions } from '@/types/permissions'; -import { AdminUserList } from '@/components/admin-user-list'; +import { AdminUserList } from './admin-user-list'; import { getUsers } from '@/data/user'; export default async function AdminUsersPage() { diff --git a/src/components/arcade.tsx b/src/app/(with-header)/arcade/[arcadeId]/arcade.tsx similarity index 96% rename from src/components/arcade.tsx rename to src/app/(with-header)/arcade/[arcadeId]/arcade.tsx index dd68b91..4b3a490 100644 --- a/src/components/arcade.tsx +++ b/src/app/(with-header)/arcade/[arcadeId]/arcade.tsx @@ -1,9 +1,9 @@ 'use client'; import { Arcade, ArcadeCab, ArcadeLink, ArcadeUser } from '@/data/arcade'; -import { JoinPrivacy, Visibility } from '@/types/privacy-visibility'; -import { Autocomplete, AutocompleteItem, Button, Divider, Dropdown, DropdownItem, DropdownMenu, DropdownTrigger, Input, Select, SelectItem, Tooltip } from '@nextui-org/react'; -import { ChevronDownIcon, GlobeAltIcon, LinkIcon, LockClosedIcon, PencilIcon, PencilSquareIcon, PlusIcon, UserMinusIcon, UserPlusIcon } from '@heroicons/react/24/outline'; +import { JoinPrivacy } from '@/types/privacy-visibility'; +import { Autocomplete, AutocompleteItem, Button, Divider, Input, Select, SelectItem, Tooltip } from '@nextui-org/react'; +import { LinkIcon, PencilIcon, PencilSquareIcon, PlusIcon, UserMinusIcon, UserPlusIcon } from '@heroicons/react/24/outline'; import { useRef, useState } from 'react'; import { useUser } from '@/helpers/use-user'; import { hasArcadePermission, hasPermission } from '@/helpers/permissions'; @@ -13,15 +13,14 @@ import { COUNTRY_CODES } from '@/types/country'; import { ArcadeUpdate, createArcadeLink, deleteArcade, deleteArcadeLink, joinPublicArcade, removeUserFromArcade, setUserArcadePermissions, updateArcade } from '@/actions/arcade'; import { useErrorModal } from '@/components/error-modal'; import { Entries } from 'type-fest'; -import { Cab } from '@/components/cab'; +import { Cab } from './cab'; import Link from 'next/link'; import { useConfirmModal } from '@/components/confirm-modal'; import { XMarkIcon } from '@heroicons/react/20/solid'; import { JoinLinksModal } from '@/components/join-links-modal'; import { useRouter, useSearchParams } from 'next/navigation'; import { PermissionEditModal, PermissionEditModalUser } from '@/components/permission-edit-modal'; -import { VisibilityIcon } from './visibility-icon'; -import { VisibilityDropdown } from './visibility-dropdown'; +import { VisibilityDropdown } from '@/components/visibility-dropdown'; export type ArcadeProps = { arcade: Arcade, diff --git a/src/components/cab.tsx b/src/app/(with-header)/arcade/[arcadeId]/cab.tsx similarity index 100% rename from src/components/cab.tsx rename to src/app/(with-header)/arcade/[arcadeId]/cab.tsx diff --git a/src/app/(with-header)/arcade/[arcadeId]/page.tsx b/src/app/(with-header)/arcade/[arcadeId]/page.tsx index b67c054..ca8ff99 100644 --- a/src/app/(with-header)/arcade/[arcadeId]/page.tsx +++ b/src/app/(with-header)/arcade/[arcadeId]/page.tsx @@ -1,7 +1,7 @@ import { getUser } from '@/actions/auth'; import { getArcadeCabs, getArcadeInviteLinks, getArcades, getArcadeUsers } from '@/data/arcade'; import { notFound } from 'next/navigation'; -import { ArcadeDetail } from '@/components/arcade'; +import { ArcadeDetail } from './arcade'; import { PrivateVisibilityError } from '@/components/private-visibility-error'; export default async function ArcadeDetailPage({ params }: { params: { arcadeId: string }}) { diff --git a/src/components/create-arcade-button.tsx b/src/app/(with-header)/arcade/create-arcade-button.tsx similarity index 100% rename from src/components/create-arcade-button.tsx rename to src/app/(with-header)/arcade/create-arcade-button.tsx diff --git a/src/app/(with-header)/arcade/page.tsx b/src/app/(with-header)/arcade/page.tsx index e5e152a..b74b45e 100644 --- a/src/app/(with-header)/arcade/page.tsx +++ b/src/app/(with-header)/arcade/page.tsx @@ -3,7 +3,7 @@ import { getUser } from '@/actions/auth'; import { Divider, Tooltip } from '@nextui-org/react'; import { UserGroupIcon } from '@heroicons/react/24/outline'; import Link from 'next/link'; -import { CreateArcadeButton } from '@/components/create-arcade-button'; +import { CreateArcadeButton } from './create-arcade-button'; import { VisibilityIcon } from '@/components/visibility-icon'; const getLocation = (arcade: Arcade) => { diff --git a/src/app/(with-header)/chuni/dashboard/page.tsx b/src/app/(with-header)/chuni/dashboard/page.tsx index 7bfbffa..6db718c 100644 --- a/src/app/(with-header)/chuni/dashboard/page.tsx +++ b/src/app/(with-header)/chuni/dashboard/page.tsx @@ -4,7 +4,7 @@ import { ChuniPlaylogCard } from '@/components/chuni/playlog-card'; import { getUserData, getUserRating } from '@/actions/chuni/profile'; import { requireUser } from '@/actions/auth'; import { notFound } from 'next/navigation'; -import { ChuniTopRatingSidebar } from '@/components/chuni/top-rating-sidebar'; +import { ChuniTopRatingSidebar } from './top-rating-sidebar'; import { Button } from '@nextui-org/react'; import Link from 'next/link'; diff --git a/src/components/chuni/top-rating-sidebar.tsx b/src/app/(with-header)/chuni/dashboard/top-rating-sidebar.tsx similarity index 98% rename from src/components/chuni/top-rating-sidebar.tsx rename to src/app/(with-header)/chuni/dashboard/top-rating-sidebar.tsx index 7bcac71..28e8729 100644 --- a/src/components/chuni/top-rating-sidebar.tsx +++ b/src/app/(with-header)/chuni/dashboard/top-rating-sidebar.tsx @@ -1,6 +1,6 @@ 'use client'; -import { ChuniTopRating } from '@/components/chuni/top-rating'; +import { ChuniTopRating } from './top-rating'; import { getUserRating } from '@/actions/chuni/profile'; import { useState } from 'react'; import { Button, ButtonGroup } from '@nextui-org/react'; diff --git a/src/components/chuni/top-rating.tsx b/src/app/(with-header)/chuni/dashboard/top-rating.tsx similarity index 100% rename from src/components/chuni/top-rating.tsx rename to src/app/(with-header)/chuni/dashboard/top-rating.tsx diff --git a/src/components/chuni/music-detail.tsx b/src/app/(with-header)/chuni/music/[musicId]/music-detail.tsx similarity index 96% rename from src/components/chuni/music-detail.tsx rename to src/app/(with-header)/chuni/music/[musicId]/music-detail.tsx index a406a08..6f52673 100644 --- a/src/components/chuni/music-detail.tsx +++ b/src/app/(with-header)/chuni/music/[musicId]/music-detail.tsx @@ -5,7 +5,7 @@ import { ChuniPlaylog } from '@/actions/chuni/playlog'; import { MusicPlayer } from '@/components/music-player'; import { getJacketUrl, getMusicUrl } from '@/helpers/assets'; import { Ticker } from '@/components/ticker'; -import { ChuniMusicPlaylog } from '@/components/chuni/music-playlog'; +import { ChuniMusicPlaylog } from './music-playlog'; import { Button } from '@nextui-org/react'; import { HeartIcon as SolidHeartIcon } from '@heroicons/react/24/solid'; import { HeartIcon as OutlineHeartIcon } from '@heroicons/react/24/outline'; diff --git a/src/components/chuni/music-playlog.tsx b/src/app/(with-header)/chuni/music/[musicId]/music-playlog.tsx similarity index 100% rename from src/components/chuni/music-playlog.tsx rename to src/app/(with-header)/chuni/music/[musicId]/music-playlog.tsx diff --git a/src/app/(with-header)/chuni/music/[musicId]/page.tsx b/src/app/(with-header)/chuni/music/[musicId]/page.tsx index 613c940..3645cfc 100644 --- a/src/app/(with-header)/chuni/music/[musicId]/page.tsx +++ b/src/app/(with-header)/chuni/music/[musicId]/page.tsx @@ -2,7 +2,7 @@ import { getMusic } from '@/actions/chuni/music'; import { notFound } from 'next/navigation'; import { getPlaylog } from '@/actions/chuni/playlog'; -import { ChuniMusicDetail } from '@/components/chuni/music-detail'; +import { ChuniMusicDetail } from './music-detail'; export default async function ChuniMusicDetailPage({ params }: { params: { musicId: string } }) { const musicId = parseInt(params.musicId); diff --git a/src/components/chuni/music-list.tsx b/src/app/(with-header)/chuni/music/music-list.tsx similarity index 100% rename from src/components/chuni/music-list.tsx rename to src/app/(with-header)/chuni/music/music-list.tsx diff --git a/src/app/(with-header)/chuni/music/page.tsx b/src/app/(with-header)/chuni/music/page.tsx index 1060538..4850d18 100644 --- a/src/app/(with-header)/chuni/music/page.tsx +++ b/src/app/(with-header)/chuni/music/page.tsx @@ -1,5 +1,5 @@ import { getMusic } from '@/actions/chuni/music'; -import { ChuniMusicList } from '@/components/chuni/music-list'; +import { ChuniMusicList } from './music-list'; export default async function ChuniMusicPage() { diff --git a/src/app/(with-header)/chuni/playlog/page.tsx b/src/app/(with-header)/chuni/playlog/page.tsx index a27af93..f1fb7cc 100644 --- a/src/app/(with-header)/chuni/playlog/page.tsx +++ b/src/app/(with-header)/chuni/playlog/page.tsx @@ -1,6 +1,115 @@ -import { ChuniPlaylogList } from '@/components/chuni/playlog-list'; +'use client'; +import { CHUNI_FILTER_DIFFICULTY, CHUNI_FILTER_GENRE, CHUNI_FILTER_LAMP, CHUNI_FILTER_LEVEL, CHUNI_FILTER_RATING, CHUNI_FILTER_SCORE, CHUNI_FILTER_WORLDS_END_STARS, CHUNI_FILTER_WORLDS_END_TAG, getLevelValFromStop } from '@/helpers/chuni/filter'; +import { FilterField, FilterSorter } from '@/components/filter-sorter'; +import { SelectItem } from '@nextui-org/react'; +import { ChuniMusic } from '@/actions/chuni/music'; +import { ArrayIndices } from 'type-fest'; +import { ChuniPlaylog, getPlaylog } from '@/actions/chuni/playlog'; +import { WindowScrollerGrid } from '@/components/window-scroller-grid'; +import { ChuniPlaylogCard } from '@/components/chuni/playlog-card'; +import { useBreakpoint } from '@/helpers/use-breakpoint'; -export default function ChuniPlaylogPage() { - return (); -} +const FILTERERS = ([ + CHUNI_FILTER_DIFFICULTY, + CHUNI_FILTER_GENRE, + { + ...CHUNI_FILTER_LAMP, + props: { + children: [ + All Justice, + Full Combo, + Clear, + ], + selectionMode: 'multiple' + } + }, + CHUNI_FILTER_WORLDS_END_TAG, + { + ...CHUNI_FILTER_SCORE, + className: 'col-span-6 md:col-span-3 lg:col-span-2 5xl:col-span-1' + }, + // CHUNI_FILTER_FAVORITE, + ({ + type: 'dateSelect', + name: 'dateRange', + label: 'Date Range', + value: undefined, + className: 'col-span-6 md:col-span-3 lg:col-span-2 5xl:col-span-1', + filter: () => false + } as FilterField), + { + ...CHUNI_FILTER_WORLDS_END_STARS, + className: 'col-span-full md:col-span-6 lg:col-span-4 5xl:col-span-2' + }, + { + ...CHUNI_FILTER_LEVEL, + className: 'col-span-full md:col-span-6 lg:col-span-4 5xl:col-span-2' + }, + { + ...CHUNI_FILTER_RATING, + className: 'col-span-full md:col-span-6 lg:col-span-4 5xl:col-span-2' + } +] as const); + +export type PlaylogFilterState = { + [K in ArrayIndices<(typeof FILTERERS)> as (typeof FILTERERS)[K]['name']]: (typeof FILTERERS[K])['value'] +}; + +const SORTERS = [{ + name: 'Date' +}, { + name: 'Rating' +}, { + name: 'Level' +}, { + name: 'Score' +}] as const; + +const PER_PAGE = [25, 50, 100, 250]; + +const REMOTE_FILTERERS = FILTERERS.map(({ filter, ...x }) => x); + +const ChuniPlaylogGrid = ({ items }: { items: ChuniPlaylog['data']; }) => { + const breakpoint = useBreakpoint(); + let colSize = 1000; + let rowSize = 275; + + if (breakpoint !== 'sm' && breakpoint !== undefined) { + colSize = 550; + rowSize = 200; + } + + return ( + {item =>
+ +
} +
); +}; + +export default function ChuniPlaylogList() { + return ( => { + const filterState = { + ...f, level: [...f.level], + dateRange: f.dateRange ? { ...f.dateRange } : undefined + } as PlaylogFilterState; + filterState.level[0] = getLevelValFromStop(filterState.level[0]); + filterState.level[1] = getLevelValFromStop(filterState.level[1]); + if (filterState.dateRange?.to) { + filterState.dateRange.to = new Date(filterState.dateRange.to); + filterState.dateRange.to.setHours(23, 59, 59, 999); + } + + return getPlaylog({ ...filterState, sort, limit: pageSize, offset: pageSize * (currentPage - 1), search, ascending }); + }} + sorters={SORTERS} pageSizes={PER_PAGE}> + {(_, d) =>
+ +
} +
); +}; diff --git a/src/app/(with-header)/chuni/userbox/page.tsx b/src/app/(with-header)/chuni/userbox/page.tsx index 32ad1bb..59e9c10 100644 --- a/src/app/(with-header)/chuni/userbox/page.tsx +++ b/src/app/(with-header)/chuni/userbox/page.tsx @@ -1,7 +1,7 @@ import { requireUser } from '@/actions/auth'; import { getUserData } from '@/actions/chuni/profile'; import { getUserboxItems } from '@/actions/chuni/userbox'; -import { ChuniUserbox } from '@/components/chuni/userbox'; +import { ChuniUserbox } from './userbox'; import { Viewport } from 'next'; export const viewport: Viewport = { diff --git a/src/components/chuni/userbox.tsx b/src/app/(with-header)/chuni/userbox/userbox.tsx similarity index 100% rename from src/components/chuni/userbox.tsx rename to src/app/(with-header)/chuni/userbox/userbox.tsx diff --git a/src/components/header-sidebar.tsx b/src/app/(with-header)/header-sidebar.tsx similarity index 97% rename from src/components/header-sidebar.tsx rename to src/app/(with-header)/header-sidebar.tsx index 48290a5..f2c0a30 100644 --- a/src/components/header-sidebar.tsx +++ b/src/app/(with-header)/header-sidebar.tsx @@ -8,13 +8,10 @@ import { ThemeSwitcherDropdown, ThemeSwitcherSwitch } from '@/components/theme-s import { AdjustmentsHorizontalIcon } from '@heroicons/react/24/solid'; import { login, logout } from '@/actions/auth'; import { usePathname, useRouter } from 'next/navigation'; -import { UserPayload } from '@/types/user'; import { MAIN_ROUTES, ROUTES, Subroute, UserOnly, filterRoute } from '@/routes'; import { useUser } from '@/helpers/use-user'; import { useBreakpoint } from '@/helpers/use-breakpoint'; import { useCookies } from 'next-client-cookies'; -import { UserPermissions } from '@/types/permissions'; -import { hasPermission } from '@/helpers/permissions'; import { ChevronDownIcon } from '@heroicons/react/24/outline'; export type HeaderSidebarProps = { diff --git a/src/app/(with-header)/layout.tsx b/src/app/(with-header)/layout.tsx index 5e9a1ee..b86aa07 100644 --- a/src/app/(with-header)/layout.tsx +++ b/src/app/(with-header)/layout.tsx @@ -1,6 +1,6 @@ import { LayoutProps } from '@/types/layout'; import { ClientProviders } from '@/components/client-providers'; -import { HeaderSidebar } from '@/components/header-sidebar'; +import { HeaderSidebar } from './header-sidebar'; export default async function HeaderLayout({children}: LayoutProps) { return ( diff --git a/src/app/(with-header)/settings/page.tsx b/src/app/(with-header)/settings/page.tsx index 8ca5d99..2f49d92 100644 --- a/src/app/(with-header)/settings/page.tsx +++ b/src/app/(with-header)/settings/page.tsx @@ -1,7 +1,7 @@ import { getCards } from '@/actions/card'; import { Divider } from '@nextui-org/react'; import { AimeCard } from '@/components/aime-card'; -import { UserSettings } from '@/components/user-settings'; +import { UserSettings } from './user-settings'; export default async function SettingsPage() { const card = await getCards(); diff --git a/src/components/user-settings.tsx b/src/app/(with-header)/settings/user-settings.tsx similarity index 97% rename from src/components/user-settings.tsx rename to src/app/(with-header)/settings/user-settings.tsx index ae11981..bb9e863 100644 --- a/src/components/user-settings.tsx +++ b/src/app/(with-header)/settings/user-settings.tsx @@ -6,7 +6,7 @@ import { getValidHomepageRoutes } from '@/routes'; import { USER_VISIBILITY_NAMES, UserVisibility } from '@/types/user'; import { Button, Checkbox, CheckboxGroup, Divider, Select, SelectItem, SelectSection } from '@nextui-org/react'; import { useState } from 'react'; -import { useErrorModal } from './error-modal'; +import { useErrorModal } from '@/components/error-modal'; export const UserSettings = () => { const user = useUser({ required: true }); diff --git a/src/app/(with-header)/team/[teamId]/page.tsx b/src/app/(with-header)/team/[teamId]/page.tsx index ad85ae1..b439ac1 100644 --- a/src/app/(with-header)/team/[teamId]/page.tsx +++ b/src/app/(with-header)/team/[teamId]/page.tsx @@ -2,7 +2,7 @@ import { getUser } from '@/actions/auth'; import { getTeamInviteLinks, getTeams, getTeamUsers } from '@/data/team'; import { notFound } from 'next/navigation'; import { PrivateVisibilityError } from '@/components/private-visibility-error'; -import { TeamDetail } from '@/components/team'; +import { TeamDetail } from './team'; export default async function TeamDetailPage({ params }: { params: { teamId: string }}) { const user = await getUser(); diff --git a/src/components/team.tsx b/src/app/(with-header)/team/[teamId]/team.tsx similarity index 96% rename from src/components/team.tsx rename to src/app/(with-header)/team/[teamId]/team.tsx index 942c0b7..12abba9 100644 --- a/src/components/team.tsx +++ b/src/app/(with-header)/team/[teamId]/team.tsx @@ -2,18 +2,18 @@ import { useRef, useState } from 'react'; import { Team, TeamUser } from '@/data/team'; -import { VisibilityDropdown } from './visibility-dropdown'; +import { VisibilityDropdown } from '@/components/visibility-dropdown'; import { Button, Divider, Input, Select, SelectItem, Tooltip } from '@nextui-org/react'; import { JoinPrivacy } from '@/types/privacy-visibility'; import { LinkIcon, PencilIcon, UserMinusIcon, UserPlusIcon, XMarkIcon } from '@heroicons/react/24/outline'; import { useUser } from '@/helpers/use-user'; import { createTeamLink, deleteTeam, deleteTeamLink, joinPublicTeam, modifyTeam, removeUserFromTeam } from '@/actions/team'; -import { useErrorModal } from './error-modal'; +import { useErrorModal } from '@/components/error-modal'; import { UserPermissions } from '@/types/permissions'; import { hasPermission } from '@/helpers/permissions'; -import { useConfirmModal } from './confirm-modal'; +import { useConfirmModal } from '@/components/confirm-modal'; import { DB } from '@/types/db'; -import { JoinLinksModal } from './join-links-modal'; +import { JoinLinksModal } from '@/components/join-links-modal'; import Link from 'next/link'; import { useRouter } from 'next/navigation'; diff --git a/src/components/create-team-button.tsx b/src/app/(with-header)/team/create-team-button.tsx similarity index 86% rename from src/components/create-team-button.tsx rename to src/app/(with-header)/team/create-team-button.tsx index 860f01d..1754e28 100644 --- a/src/components/create-team-button.tsx +++ b/src/app/(with-header)/team/create-team-button.tsx @@ -1,8 +1,8 @@ 'use client'; import { Button, Tooltip } from '@nextui-org/react'; -import { usePromptModal } from './prompt-modal'; -import { useErrorModal } from './error-modal'; +import { usePromptModal } from '@/components/prompt-modal'; +import { useErrorModal } from '@/components/error-modal'; import { PlusIcon } from '@heroicons/react/24/outline'; import { useUser } from '@/helpers/use-user'; import { createTeam } from '@/actions/team'; diff --git a/src/app/(with-header)/team/page.tsx b/src/app/(with-header)/team/page.tsx index 506130c..34c45d1 100644 --- a/src/app/(with-header)/team/page.tsx +++ b/src/app/(with-header)/team/page.tsx @@ -1,5 +1,5 @@ import { getUser } from '@/actions/auth'; -import { CreateTeamButton } from '@/components/create-team-button'; +import { CreateTeamButton } from './create-team-button'; import { VisibilityIcon } from '@/components/visibility-icon'; import { getTeams } from '@/data/team'; import { UserGroupIcon } from '@heroicons/react/24/outline'; diff --git a/src/components/chuni/playlog-list.tsx b/src/components/chuni/playlog-list.tsx deleted file mode 100644 index 49901a2..0000000 --- a/src/components/chuni/playlog-list.tsx +++ /dev/null @@ -1,108 +0,0 @@ -'use client'; - -import { CHUNI_FILTER_DIFFICULTY, CHUNI_FILTER_GENRE, CHUNI_FILTER_LAMP, CHUNI_FILTER_LEVEL, CHUNI_FILTER_RATING, CHUNI_FILTER_SCORE, CHUNI_FILTER_WORLDS_END_STARS, CHUNI_FILTER_WORLDS_END_TAG, getLevelValFromStop } from '@/helpers/chuni/filter'; -import { FilterField, FilterSorter } from '@/components/filter-sorter'; -import { SelectItem } from '@nextui-org/react'; -import { ChuniMusic } from '@/actions/chuni/music'; -import { ArrayIndices } from 'type-fest'; -import { ChuniPlaylog, getPlaylog } from '@/actions/chuni/playlog'; -import { WindowScrollerGrid } from '@/components/window-scroller-grid'; -import { ChuniPlaylogCard } from '@/components/chuni/playlog-card'; -import { useBreakpoint } from '@/helpers/use-breakpoint'; - -const FILTERERS = ([ - CHUNI_FILTER_DIFFICULTY, - CHUNI_FILTER_GENRE, - { ...CHUNI_FILTER_LAMP, - props: { - children: [ - All Justice, - Full Combo, - Clear, - ], - selectionMode: 'multiple' - } - }, - CHUNI_FILTER_WORLDS_END_TAG, - { ...CHUNI_FILTER_SCORE, - className: 'col-span-6 md:col-span-3 lg:col-span-2 5xl:col-span-1' - }, - // CHUNI_FILTER_FAVORITE, - ({ - type: 'dateSelect', - name: 'dateRange', - label: 'Date Range', - value: undefined, - className: 'col-span-6 md:col-span-3 lg:col-span-2 5xl:col-span-1', - filter: () => false - } as FilterField), - { ...CHUNI_FILTER_WORLDS_END_STARS, - className: 'col-span-full md:col-span-6 lg:col-span-4 5xl:col-span-2' - }, - { ...CHUNI_FILTER_LEVEL, - className: 'col-span-full md:col-span-6 lg:col-span-4 5xl:col-span-2' - }, - { ...CHUNI_FILTER_RATING, - className: 'col-span-full md:col-span-6 lg:col-span-4 5xl:col-span-2' - } -] as const) - -export type PlaylogFilterState = { - [K in ArrayIndices<(typeof FILTERERS)> as (typeof FILTERERS)[K]['name']]: (typeof FILTERERS[K])['value'] -}; - -const SORTERS = [{ - name: 'Date' -}, { - name: 'Rating' -}, { - name: 'Level' -}, { - name: 'Score' -}] as const; - -const PER_PAGE = [25, 50, 100, 250]; - -const REMOTE_FILTERERS = FILTERERS.map(({ filter, ...x }) => x); - -const ChuniPlaylogGrid = ({ items }: { items: ChuniPlaylog['data'] }) => { - const breakpoint = useBreakpoint(); - let colSize = 1000; - let rowSize = 275; - - if (breakpoint !== 'sm' && breakpoint !== undefined) { - colSize = 550; - rowSize = 200; - } - - return ( - {item =>
- -
} -
); -}; - -export const ChuniPlaylogList = () => { - return ( => { - const filterState = { ...f, level: [...f.level], - dateRange: f.dateRange ? { ...f.dateRange } : undefined } as PlaylogFilterState; - filterState.level[0] = getLevelValFromStop(filterState.level[0]); - filterState.level[1] = getLevelValFromStop(filterState.level[1]); - if (filterState.dateRange?.to) { - filterState.dateRange.to = new Date(filterState.dateRange.to); - filterState.dateRange.to.setHours(23, 59, 59, 999); - } - - return getPlaylog({ ...filterState, sort, limit: pageSize, offset: pageSize * (currentPage - 1), search, ascending }); - }} - sorters={SORTERS} pageSizes={PER_PAGE}> - {(_, d) =>
- -
} -
); -};