diff --git a/src/__tests__/pages/404.test.tsx b/src/__tests__/pages/404.test.tsx index fc1f529..0fdfb60 100644 --- a/src/__tests__/pages/404.test.tsx +++ b/src/__tests__/pages/404.test.tsx @@ -1,8 +1,8 @@ import { render, screen } from '@testing-library/react'; -import NotFoundPage from '@/pages/404'; +import NotFoundPage from '@/app/not-found'; -describe('404', () => { +describe('not-found', () => { it('renders a heading', () => { render(); diff --git a/src/pages/account.tsx b/src/app/account/page.tsx similarity index 66% rename from src/pages/account.tsx rename to src/app/account/page.tsx index 90aa73a..e89b0c1 100644 --- a/src/pages/account.tsx +++ b/src/app/account/page.tsx @@ -1,11 +1,12 @@ -import * as React from 'react'; +import { Metadata } from 'next'; -import Seo from '@/components/Seo'; +export const metadata: Metadata = { + title: 'Account', +}; export default function AccountPage() { return ( <> -

Account Settings Here

diff --git a/src/app/layout.tsx b/src/app/layout.tsx new file mode 100644 index 0000000..62d4be5 --- /dev/null +++ b/src/app/layout.tsx @@ -0,0 +1,35 @@ +import { Metadata } from 'next'; +import * as React from 'react'; + +import '../styles/globals.css'; + +import Player from '../components/Player'; +import Sidebar from '../components/sidebar/Sidebar'; + +export const metadata: Metadata = { + title: { + default: 'Nex | Music Player', + template: '%s | Nex', + }, + applicationName: 'Nex | Music Player', + description: 'A spotify inspired music players for communities and groups', + authors: { name: 'ThEditor', url: 'https://nex.theditor.xyz' }, + robots: 'follow, index', + icons: { icon: 'https://theditor.xyz/assets/img/profile-img.jpg' }, +}; + +export default function Layout({ children }: { children: React.ReactNode }) { + return ( + + +
+
+ +
{children}
+
+ +
+ + + ); +} diff --git a/src/pages/login.tsx b/src/app/login/page.tsx similarity index 84% rename from src/pages/login.tsx rename to src/app/login/page.tsx index 193c40a..36d0b6a 100644 --- a/src/pages/login.tsx +++ b/src/app/login/page.tsx @@ -1,20 +1,17 @@ -import { useRouter } from 'next/router'; -import { useEffect } from 'react'; +import { Metadata } from 'next'; +import { redirect } from 'next/navigation'; import Button from '@/components/buttons/Button'; import UnderlineLink from '@/components/links/UnderlineLink'; +export const metadata: Metadata = { + title: 'Login', +}; + export default function LoginPage() { - const router = useRouter(); const signedin = false; - - useEffect(() => { - if (signedin) router.push('/'); - }, [router, signedin]); - if (signedin) { - router.push('/'); - return <>; + redirect('/'); } return !signedin ? ( diff --git a/src/app/logout/page.tsx b/src/app/logout/page.tsx new file mode 100644 index 0000000..07e668c --- /dev/null +++ b/src/app/logout/page.tsx @@ -0,0 +1,12 @@ +import { Metadata } from 'next'; +import { redirect } from 'next/navigation'; + +export const metadata: Metadata = { + title: 'Logout', +}; + +export default function LogoutPage() { + const signedin = true; + + return signedin ? redirect('/') : <>; +} diff --git a/src/pages/404.tsx b/src/app/not-found.tsx similarity index 91% rename from src/pages/404.tsx rename to src/app/not-found.tsx index ca98d53..510818c 100644 --- a/src/pages/404.tsx +++ b/src/app/not-found.tsx @@ -2,13 +2,10 @@ import * as React from 'react'; import { RiAlarmWarningFill } from 'react-icons/ri'; import ArrowLink from '@/components/links/ArrowLink'; -import Seo from '@/components/Seo'; export default function NotFoundPage() { return (
- -
diff --git a/src/pages/index.tsx b/src/app/page.tsx similarity index 83% rename from src/pages/index.tsx rename to src/app/page.tsx index e3de527..a00745f 100644 --- a/src/pages/index.tsx +++ b/src/app/page.tsx @@ -1,3 +1,4 @@ +'use client'; import * as React from 'react'; import Carousel, { CarouselProps } from '@/components/carousel/Carousel'; @@ -14,17 +15,13 @@ export default function HomePage() { { title: 'Life in a bubble', subtitle: 'The van', - clickAction: () => { - return; - }, + link: '/', imgSrc: '/images/test.png', }, { title: 'Life in a bubble', subtitle: 'The van', - clickAction: () => { - return; - }, + link: '/', imgSrc: '/images/test.png', }, ], @@ -35,17 +32,13 @@ export default function HomePage() { { title: 'Life in a bubble', subtitle: 'The van', - clickAction: () => { - return; - }, + link: '/', imgSrc: '/images/test.png', }, { title: 'Life in a bubble', subtitle: 'The van', - clickAction: () => { - return; - }, + link: '/', imgSrc: '/images/test.png', }, ], diff --git a/src/pages/search.tsx b/src/app/search/page.tsx similarity index 65% rename from src/pages/search.tsx rename to src/app/search/page.tsx index 3192f83..05ea4f7 100644 --- a/src/pages/search.tsx +++ b/src/app/search/page.tsx @@ -1,11 +1,11 @@ -import * as React from 'react'; - -import Seo from '@/components/Seo'; +import { Metadata } from 'next'; +export const metadata: Metadata = { + title: 'Search', +}; export default function Search() { return ( <> -

Searching...

diff --git a/src/components/NextImage.tsx b/src/components/NextImage.tsx index 4a00355..bfb9023 100644 --- a/src/components/NextImage.tsx +++ b/src/components/NextImage.tsx @@ -1,3 +1,4 @@ +'use client'; import Image, { ImageProps } from 'next/image'; import * as React from 'react'; diff --git a/src/components/layout/Player.tsx b/src/components/Player.tsx similarity index 99% rename from src/components/layout/Player.tsx rename to src/components/Player.tsx index c4ae88a..a15ef86 100644 --- a/src/components/layout/Player.tsx +++ b/src/components/Player.tsx @@ -7,12 +7,13 @@ import { ImVolumeHigh, } from 'react-icons/im'; +import '@/styles/globals.css'; + import clsxm from '@/lib/clsxm'; import IconButton from '@/components/buttons/IconButton'; import NextImage from '@/components/NextImage'; import Slider from '@/components/Slider'; - interface PlayerProps { className?: string; } diff --git a/src/components/Seo.tsx b/src/components/Seo.tsx deleted file mode 100644 index b259ab6..0000000 --- a/src/components/Seo.tsx +++ /dev/null @@ -1,111 +0,0 @@ -import Head from 'next/head'; -import { useRouter } from 'next/router'; - -const defaultMeta = { - title: 'Nex | Music Player', - siteName: 'Nex | Music Player', - description: 'A spotify inspired music players for communities and groups', - /** Without additional '/' on the end, e.g. https://theodorusclarence.com */ - url: 'https://nex.theditor.xyz', - type: 'website', - robots: 'follow, index', - /** - * No need to be filled, will be populated with openGraph function - * If you wish to use a normal image, just specify the path below - */ - image: 'https://theditor.xyz/assets/img/profile-img.jpg', -}; - -type SeoProps = { - date?: string; - templateTitle?: string; -} & Partial; - -export default function Seo(props: SeoProps) { - const router = useRouter(); - const meta = { - ...defaultMeta, - ...props, - }; - meta['title'] = props.templateTitle - ? `${props.templateTitle} | ${meta.siteName}` - : meta.title; - - // Use siteName if there is templateTitle - // but show full title if there is none - // !STARTERCONF Follow config for opengraph, by deploying one on https://github.com/theodorusclarence/og - // ? Uncomment code below if you want to use default open graph - // meta['image'] = openGraph({ - // description: meta.description, - // siteName: props.templateTitle ? meta.siteName : meta.title, - // templateTitle: props.templateTitle, - // }); - - return ( - - {meta.title} - - - - - {/* Open Graph */} - - - - - - {/* Twitter */} - - - - - - {meta.date && ( - <> - - - - - )} - - {/* Favicons */} - {favicons.map((linkProps) => ( - - ))} - - - - - ); -} - -const favicons: Array> = [ - { - rel: 'apple-touch-icon', - sizes: '180x180', - href: '/favicon/apple-touch-icon.png', - }, - { - rel: 'icon', - type: 'image/png', - sizes: '32x32', - href: '/favicon/favicon-32x32.png', - }, - { - rel: 'icon', - type: 'image/png', - sizes: '16x16', - href: '/favicon/favicon-16x16.png', - }, - { rel: 'manifest', href: '/favicon/site.webmanifest' }, - { - rel: 'mask-icon', - href: '/favicon/safari-pinned-tab.svg', - color: '#00e887', - }, - { rel: 'shortcut icon', href: '/favicon/favicon.ico' }, -]; diff --git a/src/components/carousel/Carousel.tsx b/src/components/carousel/Carousel.tsx index d0271b6..68f8fb4 100644 --- a/src/components/carousel/Carousel.tsx +++ b/src/components/carousel/Carousel.tsx @@ -15,7 +15,7 @@ export default function Carousel({ data }: CarouselProps) { title={v.title} subtitle={v.subtitle} imgSrc={v.imgSrc} - clickAction={v.clickAction} + link={v.link} /> ))}
diff --git a/src/components/carousel/CarouselItem.tsx b/src/components/carousel/CarouselItem.tsx index efa6832..0da5b4f 100644 --- a/src/components/carousel/CarouselItem.tsx +++ b/src/components/carousel/CarouselItem.tsx @@ -1,3 +1,6 @@ +'use client'; +import { redirect } from 'next/navigation'; + import clsxm from '@/lib/clsxm'; import NextImage from '@/components/NextImage'; @@ -5,7 +8,7 @@ import NextImage from '@/components/NextImage'; export interface CarouselItemProps { title: string; subtitle: string; - clickAction: () => void; + link: string; imgSrc: string; className?: string; } @@ -13,7 +16,7 @@ export interface CarouselItemProps { export default function CarouselItem({ title, subtitle, - clickAction, + link, imgSrc, className, }: CarouselItemProps) { @@ -23,7 +26,7 @@ export default function CarouselItem({ className, 'text-light font-quicksand hover:bg-light flex w-fit cursor-pointer select-none flex-col gap-1 rounded-3xl p-3 transition-all ease-linear hover:bg-opacity-10' )} - onClick={() => clickAction()} + onClick={() => redirect(link)} > -
- -
{children}
-
- -
- ); -} diff --git a/src/components/layout/sidebar/Sidebar.tsx b/src/components/sidebar/Sidebar.tsx similarity index 74% rename from src/components/layout/sidebar/Sidebar.tsx rename to src/components/sidebar/Sidebar.tsx index d279d5a..b31ba74 100644 --- a/src/components/layout/sidebar/Sidebar.tsx +++ b/src/components/sidebar/Sidebar.tsx @@ -1,11 +1,13 @@ -import { useRouter } from 'next/router'; +'use client'; +import { useRouter } from 'next/navigation'; +import { usePathname } from 'next/navigation'; import { ImHome, ImSearch } from 'react-icons/im'; import { RiLoginBoxFill, RiLogoutBoxFill, RiUser3Fill } from 'react-icons/ri'; import clsxm from '@/lib/clsxm'; -import SidebarGroup from '@/components/layout/sidebar/SidebarGroup'; import NextImage from '@/components/NextImage'; +import SidebarGroup from '@/components/sidebar/SidebarGroup'; interface SidebarProps { className?: string; @@ -14,6 +16,7 @@ interface SidebarProps { export default function Sidebar({ className }: SidebarProps) { const router = useRouter(); const signedIn = false; + const pathname = usePathname(); return (
{ - if (router.asPath !== '/') router.push('/'); + if (pathname !== '/') router.push('/'); }, }, { id: '/search', icon: ImSearch, clickAction: () => { - if (router.asPath !== '/search') router.push('/search'); + if (pathname !== '/search') router.push('/search'); }, }, ]} /> { - if (router.asPath !== '/account') router.push('/account'); + if (pathname !== '/account') router.push('/account'); }, }, { id: 'auth', icon: signedIn ? RiLogoutBoxFill : RiLoginBoxFill, clickAction: () => { - if (!signedIn && router.asPath !== '/login') - router.push('/login'); + if (!signedIn && pathname !== '/login') router.push('/login'); if (signedIn) router.push('/logout'); }, }, diff --git a/src/components/layout/sidebar/SidebarGroup.tsx b/src/components/sidebar/SidebarGroup.tsx similarity index 98% rename from src/components/layout/sidebar/SidebarGroup.tsx rename to src/components/sidebar/SidebarGroup.tsx index a7fce9b..b3abe4b 100644 --- a/src/components/layout/sidebar/SidebarGroup.tsx +++ b/src/components/sidebar/SidebarGroup.tsx @@ -1,3 +1,4 @@ +'use client'; import { IconType } from 'react-icons/lib'; import clsxm from '@/lib/clsxm'; diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx deleted file mode 100644 index cec8315..0000000 --- a/src/pages/_app.tsx +++ /dev/null @@ -1,15 +0,0 @@ -import { AppProps } from 'next/app'; - -import '@/styles/globals.css'; - -import Layout from '@/components/layout/Layout'; - -function MyApp({ Component, pageProps }: AppProps) { - return ( - - - - ); -} - -export default MyApp; diff --git a/src/pages/_document.tsx b/src/pages/_document.tsx deleted file mode 100644 index d491d46..0000000 --- a/src/pages/_document.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import { Head, Html, Main, NextScript } from 'next/document'; - -export default function Document() { - return ( - - - - - -
- - - - ); -} diff --git a/src/pages/logout.tsx b/src/pages/logout.tsx deleted file mode 100644 index da8aafa..0000000 --- a/src/pages/logout.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import { useRouter } from 'next/router'; -import { useEffect } from 'react'; - -export default function LogoutPage() { - const router = useRouter(); - const signedin = true; - - useEffect(() => { - if (signedin) { - // todo: request logout - } - - router.push('/login'); - }, [router, signedin]); - - return signedin ? ( -
-

Logging you out...

-
- ) : ( - <> - ); -} diff --git a/tailwind.config.ts b/tailwind.config.ts index d29392f..a43ad48 100644 --- a/tailwind.config.ts +++ b/tailwind.config.ts @@ -73,4 +73,4 @@ export default { }, }, plugins: [require('@tailwindcss/forms')], -} satisfies Config; +} satisfies Config; \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json index 91efe0c..f3a4ec1 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -18,9 +18,14 @@ "@/*": ["./src/*"], "~/*": ["./public/*"] }, - "incremental": true + "incremental": true, + "plugins": [ + { + "name": "next" + } + ] }, - "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], + "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], "exclude": ["node_modules"], "moduleResolution": ["node_modules", ".next", "node"] }