mirror of
https://github.com/MoonTechLab/LunaTV.git
synced 2026-02-27 06:54:43 +08:00
Initial commit from Create Next App
This commit is contained in:
5
src/app/api/hello/route.ts
Normal file
5
src/app/api/hello/route.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import { NextResponse } from 'next/server';
|
||||
|
||||
export async function GET() {
|
||||
return NextResponse.json({ hello: 'Next.js' });
|
||||
}
|
||||
17
src/app/components/layout.tsx
Normal file
17
src/app/components/layout.tsx
Normal file
@@ -0,0 +1,17 @@
|
||||
import { Metadata } from 'next';
|
||||
import * as React from 'react';
|
||||
|
||||
import '@/styles/colors.css';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Components',
|
||||
description: 'Pre-built components with awesome default',
|
||||
};
|
||||
|
||||
export default function ComponentsLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return <>{children}</>;
|
||||
}
|
||||
461
src/app/components/page.tsx
Normal file
461
src/app/components/page.tsx
Normal file
@@ -0,0 +1,461 @@
|
||||
'use client';
|
||||
|
||||
import clsx from 'clsx';
|
||||
import {
|
||||
ArrowRight,
|
||||
CreditCard,
|
||||
Laptop,
|
||||
Phone,
|
||||
Plus,
|
||||
Shield,
|
||||
} from 'lucide-react';
|
||||
import React from 'react';
|
||||
|
||||
import Button from '@/components/buttons/Button';
|
||||
import IconButton from '@/components/buttons/IconButton';
|
||||
import TextButton from '@/components/buttons/TextButton';
|
||||
import ArrowLink from '@/components/links/ArrowLink';
|
||||
import ButtonLink from '@/components/links/ButtonLink';
|
||||
import PrimaryLink from '@/components/links/PrimaryLink';
|
||||
import UnderlineLink from '@/components/links/UnderlineLink';
|
||||
import UnstyledLink from '@/components/links/UnstyledLink';
|
||||
import NextImage from '@/components/NextImage';
|
||||
import Skeleton from '@/components/Skeleton';
|
||||
|
||||
type Color = (typeof colorList)[number];
|
||||
|
||||
export default function ComponentPage() {
|
||||
const [mode, setMode] = React.useState<'dark' | 'light'>('light');
|
||||
const [color, setColor] = React.useState<Color>('sky');
|
||||
function toggleMode() {
|
||||
return mode === 'dark' ? setMode('light') : setMode('dark');
|
||||
}
|
||||
|
||||
const textColor = mode === 'dark' ? 'text-gray-300' : 'text-gray-600';
|
||||
|
||||
return (
|
||||
<main>
|
||||
<section
|
||||
className={clsx(mode === 'dark' ? 'bg-dark' : 'bg-white', color)}
|
||||
>
|
||||
<div
|
||||
className={clsx(
|
||||
'layout min-h-screen py-20',
|
||||
mode === 'dark' ? 'text-white' : 'text-black'
|
||||
)}
|
||||
>
|
||||
<h1>Built-in Components</h1>
|
||||
<ArrowLink direction='left' className='mt-2' href='/'>
|
||||
Back to Home
|
||||
</ArrowLink>
|
||||
|
||||
<div className='mt-8 flex flex-wrap gap-2'>
|
||||
<Button
|
||||
onClick={toggleMode}
|
||||
variant={mode === 'dark' ? 'light' : 'dark'}
|
||||
>
|
||||
Set to {mode === 'dark' ? 'light' : 'dark'}
|
||||
</Button>
|
||||
{/* <Button onClick={randomize}>Randomize CSS Variable</Button> */}
|
||||
</div>
|
||||
|
||||
<ol className='mt-8 space-y-6'>
|
||||
<li className='space-y-2'>
|
||||
<h2 className='text-lg md:text-xl'>Customize Colors</h2>
|
||||
<p className={clsx('!mt-1 text-sm', textColor)}>
|
||||
You can change primary color to any Tailwind CSS colors. See
|
||||
globals.css to change your color.
|
||||
</p>
|
||||
<div className='flex flex-wrap gap-2'>
|
||||
<select
|
||||
name='color'
|
||||
id='color'
|
||||
value={color}
|
||||
className={clsx(
|
||||
'block max-w-xs rounded',
|
||||
mode === 'dark'
|
||||
? 'bg-dark border border-gray-600'
|
||||
: 'border-gray-300 bg-white',
|
||||
'focus:border-primary-400 focus:ring-primary-400 focus:outline-none focus:ring'
|
||||
)}
|
||||
onChange={(e) => setColor(e.target.value as Color)}
|
||||
>
|
||||
{colorList.map((c) => (
|
||||
<option key={c} value={c}>
|
||||
{c}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<ButtonLink href='https://github.com/theodorusclarence/ts-nextjs-tailwind-starter/blob/main/src/styles/colors.css'>
|
||||
Check list of colors
|
||||
</ButtonLink>
|
||||
</div>
|
||||
<div className='flex flex-wrap gap-2 text-xs font-medium'>
|
||||
<div className='bg-primary-50 flex h-10 w-10 items-center justify-center rounded text-black'>
|
||||
50
|
||||
</div>
|
||||
<div className='bg-primary-100 flex h-10 w-10 items-center justify-center rounded text-black'>
|
||||
100
|
||||
</div>
|
||||
<div className='bg-primary-200 flex h-10 w-10 items-center justify-center rounded text-black'>
|
||||
200
|
||||
</div>
|
||||
<div className='bg-primary-300 flex h-10 w-10 items-center justify-center rounded text-black'>
|
||||
300
|
||||
</div>
|
||||
<div className='bg-primary-400 flex h-10 w-10 items-center justify-center rounded text-black'>
|
||||
400
|
||||
</div>
|
||||
<div className='bg-primary-500 flex h-10 w-10 items-center justify-center rounded text-black'>
|
||||
500
|
||||
</div>
|
||||
<div className='bg-primary-600 flex h-10 w-10 items-center justify-center rounded text-white'>
|
||||
600
|
||||
</div>
|
||||
<div className='bg-primary-700 flex h-10 w-10 items-center justify-center rounded text-white'>
|
||||
700
|
||||
</div>
|
||||
<div className='bg-primary-800 flex h-10 w-10 items-center justify-center rounded text-white'>
|
||||
800
|
||||
</div>
|
||||
<div className='bg-primary-900 flex h-10 w-10 items-center justify-center rounded text-white'>
|
||||
900
|
||||
</div>
|
||||
<div className='bg-primary-950 flex h-10 w-10 items-center justify-center rounded text-white'>
|
||||
950
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
<li className='space-y-2'>
|
||||
<h2 className='text-lg md:text-xl'>UnstyledLink</h2>
|
||||
<p className={clsx('!mt-1 text-sm', textColor)}>
|
||||
No style applied, differentiate internal and outside links, give
|
||||
custom cursor for outside links.
|
||||
</p>
|
||||
<div className='space-x-2'>
|
||||
<UnstyledLink href='/'>Internal Links</UnstyledLink>
|
||||
<UnstyledLink href='https://theodorusclarence.com'>
|
||||
Outside Links
|
||||
</UnstyledLink>
|
||||
</div>
|
||||
</li>
|
||||
<li className='space-y-2'>
|
||||
<h2 className='text-lg md:text-xl'>PrimaryLink</h2>
|
||||
<p className={clsx('!mt-1 text-sm', textColor)}>
|
||||
Add styling on top of UnstyledLink, giving a primary color to
|
||||
the link.
|
||||
</p>
|
||||
<div className='space-x-2'>
|
||||
<PrimaryLink href='/'>Internal Links</PrimaryLink>
|
||||
<PrimaryLink href='https://theodorusclarence.com'>
|
||||
Outside Links
|
||||
</PrimaryLink>
|
||||
</div>
|
||||
</li>
|
||||
<li className='space-y-2'>
|
||||
<h2 className='text-lg md:text-xl'>UnderlineLink</h2>
|
||||
<p className={clsx('!mt-1 text-sm', textColor)}>
|
||||
Add styling on top of UnstyledLink, giving a dotted and animated
|
||||
underline.
|
||||
</p>
|
||||
<div className='space-x-2'>
|
||||
<UnderlineLink href='/'>Internal Links</UnderlineLink>
|
||||
<UnderlineLink href='https://theodorusclarence.com'>
|
||||
Outside Links
|
||||
</UnderlineLink>
|
||||
</div>
|
||||
</li>
|
||||
<li className='space-y-2'>
|
||||
<h2 className='text-lg md:text-xl'>ArrowLink</h2>
|
||||
<p className={clsx('!mt-1 text-sm', textColor)}>
|
||||
Useful for indicating navigation, I use this quite a lot, so why
|
||||
not build a component with some whimsy touch?
|
||||
</p>
|
||||
<div className='flex flex-wrap items-center gap-4'>
|
||||
<ArrowLink href='/' direction='left'>
|
||||
Direction Left
|
||||
</ArrowLink>
|
||||
<ArrowLink href='/'>Direction Right</ArrowLink>
|
||||
<ArrowLink
|
||||
as={UnstyledLink}
|
||||
className='inline-flex items-center'
|
||||
href='/'
|
||||
>
|
||||
Polymorphic
|
||||
</ArrowLink>
|
||||
<ArrowLink
|
||||
as={ButtonLink}
|
||||
variant='light'
|
||||
className='inline-flex items-center'
|
||||
href='/'
|
||||
>
|
||||
Polymorphic
|
||||
</ArrowLink>
|
||||
</div>
|
||||
</li>
|
||||
<li className='space-y-2'>
|
||||
<h2 className='text-lg md:text-xl'>ButtonLink</h2>
|
||||
<p className={clsx('!mt-1 text-sm', textColor)}>
|
||||
Button styled link with 3 variants.
|
||||
</p>
|
||||
<div className='flex flex-wrap gap-2'>
|
||||
<ButtonLink
|
||||
variant='primary'
|
||||
href='https://theodorusclarence.com'
|
||||
>
|
||||
Primary Variant
|
||||
</ButtonLink>
|
||||
<ButtonLink
|
||||
variant='outline'
|
||||
isDarkBg={mode === 'dark'}
|
||||
href='https://theodorusclarence.com'
|
||||
>
|
||||
Outline Variant
|
||||
</ButtonLink>
|
||||
<ButtonLink
|
||||
variant='ghost'
|
||||
isDarkBg={mode === 'dark'}
|
||||
href='https://theodorusclarence.com'
|
||||
>
|
||||
Ghost Variant
|
||||
</ButtonLink>
|
||||
<ButtonLink variant='dark' href='https://theodorusclarence.com'>
|
||||
Dark Variant
|
||||
</ButtonLink>
|
||||
<ButtonLink
|
||||
variant='light'
|
||||
href='https://theodorusclarence.com'
|
||||
>
|
||||
Light Variant
|
||||
</ButtonLink>
|
||||
</div>
|
||||
</li>
|
||||
<li className='space-y-2'>
|
||||
<h2 className='text-lg md:text-xl'>Button</h2>
|
||||
<p className={clsx('!mt-1 text-sm', textColor)}>
|
||||
Ordinary button with style.
|
||||
</p>
|
||||
<div className='flex flex-wrap gap-2'>
|
||||
<Button variant='primary'>Primary Variant</Button>
|
||||
<Button variant='outline' isDarkBg={mode === 'dark'}>
|
||||
Outline Variant
|
||||
</Button>
|
||||
<Button variant='ghost' isDarkBg={mode === 'dark'}>
|
||||
Ghost Variant
|
||||
</Button>
|
||||
<Button variant='dark'>Dark Variant</Button>
|
||||
<Button variant='light'>Light Variant</Button>
|
||||
</div>
|
||||
<div className='flex flex-wrap gap-2'>
|
||||
<Button
|
||||
variant='primary'
|
||||
leftIcon={Plus}
|
||||
rightIcon={ArrowRight}
|
||||
>
|
||||
Icon
|
||||
</Button>
|
||||
<Button
|
||||
variant='outline'
|
||||
leftIcon={Plus}
|
||||
rightIcon={ArrowRight}
|
||||
isDarkBg={mode === 'dark'}
|
||||
>
|
||||
Icon
|
||||
</Button>
|
||||
<Button
|
||||
variant='ghost'
|
||||
leftIcon={Plus}
|
||||
rightIcon={ArrowRight}
|
||||
isDarkBg={mode === 'dark'}
|
||||
>
|
||||
Icon
|
||||
</Button>
|
||||
<Button variant='dark' leftIcon={Plus} rightIcon={ArrowRight}>
|
||||
Icon
|
||||
</Button>
|
||||
<Button variant='light' leftIcon={Plus} rightIcon={ArrowRight}>
|
||||
Icon
|
||||
</Button>
|
||||
</div>
|
||||
<div className='!mt-4 flex flex-wrap gap-2'>
|
||||
<Button size='sm' variant='primary'>
|
||||
Small Size
|
||||
</Button>
|
||||
<Button size='sm' variant='outline' isDarkBg={mode === 'dark'}>
|
||||
Small Size
|
||||
</Button>
|
||||
<Button size='sm' variant='ghost' isDarkBg={mode === 'dark'}>
|
||||
Small Size
|
||||
</Button>
|
||||
<Button size='sm' variant='dark'>
|
||||
Small Size
|
||||
</Button>
|
||||
<Button size='sm' variant='light'>
|
||||
Small Size
|
||||
</Button>
|
||||
</div>
|
||||
<div className='flex flex-wrap gap-2'>
|
||||
<Button
|
||||
size='sm'
|
||||
variant='primary'
|
||||
leftIcon={Plus}
|
||||
rightIcon={ArrowRight}
|
||||
>
|
||||
Icon
|
||||
</Button>
|
||||
<Button
|
||||
size='sm'
|
||||
variant='outline'
|
||||
leftIcon={Plus}
|
||||
rightIcon={ArrowRight}
|
||||
isDarkBg={mode === 'dark'}
|
||||
>
|
||||
Icon
|
||||
</Button>
|
||||
<Button
|
||||
size='sm'
|
||||
variant='ghost'
|
||||
leftIcon={Plus}
|
||||
rightIcon={ArrowRight}
|
||||
isDarkBg={mode === 'dark'}
|
||||
>
|
||||
Icon
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
size='sm'
|
||||
variant='dark'
|
||||
leftIcon={Plus}
|
||||
rightIcon={ArrowRight}
|
||||
>
|
||||
Icon
|
||||
</Button>
|
||||
<Button
|
||||
size='sm'
|
||||
variant='light'
|
||||
leftIcon={Plus}
|
||||
rightIcon={ArrowRight}
|
||||
>
|
||||
Icon
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
<div className='!mt-4 flex flex-wrap gap-2'>
|
||||
<Button disabled variant='primary'>
|
||||
Disabled
|
||||
</Button>
|
||||
<Button disabled variant='outline' isDarkBg={mode === 'dark'}>
|
||||
Disabled
|
||||
</Button>
|
||||
<Button disabled variant='ghost' isDarkBg={mode === 'dark'}>
|
||||
Disabled
|
||||
</Button>
|
||||
<Button disabled variant='dark'>
|
||||
Disabled
|
||||
</Button>
|
||||
<Button disabled variant='light'>
|
||||
Disabled
|
||||
</Button>
|
||||
</div>
|
||||
<div className='flex flex-wrap gap-2'>
|
||||
<Button isLoading variant='primary'>
|
||||
Disabled
|
||||
</Button>
|
||||
<Button isLoading variant='outline' isDarkBg={mode === 'dark'}>
|
||||
Disabled
|
||||
</Button>
|
||||
<Button isLoading variant='ghost' isDarkBg={mode === 'dark'}>
|
||||
Disabled
|
||||
</Button>
|
||||
<Button isLoading variant='dark'>
|
||||
Disabled
|
||||
</Button>
|
||||
<Button isLoading variant='light'>
|
||||
Disabled
|
||||
</Button>
|
||||
</div>
|
||||
</li>
|
||||
<li className='space-y-2'>
|
||||
<h2 className='text-lg md:text-xl'>TextButton</h2>
|
||||
<p className={clsx('!mt-1 text-sm', textColor)}>
|
||||
Button with a text style
|
||||
</p>
|
||||
<div className='space-x-2'>
|
||||
<TextButton>Primary Variant</TextButton>
|
||||
<TextButton variant='basic'>Basic Variant</TextButton>
|
||||
</div>
|
||||
</li>
|
||||
<li className='space-y-2'>
|
||||
<h2 className='text-lg md:text-xl'>IconButton</h2>
|
||||
<p className={clsx('!mt-1 text-sm', textColor)}>
|
||||
Button with only icon inside
|
||||
</p>
|
||||
<div className='space-x-2'>
|
||||
<IconButton icon={Plus} />
|
||||
<IconButton variant='outline' icon={Laptop} />
|
||||
<IconButton variant='ghost' icon={Phone} />
|
||||
<IconButton variant='dark' icon={Shield} />
|
||||
<IconButton variant='light' icon={CreditCard} />
|
||||
</div>
|
||||
</li>
|
||||
<li className='space-y-2'>
|
||||
<h2 className='text-lg md:text-xl'>Custom 404 Page</h2>
|
||||
<p className={clsx('!mt-1 text-sm', textColor)}>
|
||||
Styled 404 page with some animation.
|
||||
</p>
|
||||
<div className='flex flex-wrap gap-2'>
|
||||
<ButtonLink href='/404'>Visit the 404 page</ButtonLink>
|
||||
</div>
|
||||
</li>
|
||||
<li className='space-y-2'>
|
||||
<h2 className='text-lg md:text-xl'>Next Image</h2>
|
||||
<p className={clsx('!mt-1 text-sm', textColor)}>
|
||||
Next Image with default props and skeleton animation
|
||||
</p>
|
||||
<NextImage
|
||||
useSkeleton
|
||||
className='w-32 md:w-40'
|
||||
src='/favicon/android-chrome-192x192.png'
|
||||
width='180'
|
||||
height='180'
|
||||
alt='Icon'
|
||||
/>
|
||||
</li>
|
||||
<li className='space-y-2'>
|
||||
<h2 className='text-lg md:text-xl'>Skeleton</h2>
|
||||
<p className={clsx('!mt-1 text-sm', textColor)}>
|
||||
Skeleton with shimmer effect
|
||||
</p>
|
||||
<Skeleton className='h-72 w-72' />
|
||||
</li>
|
||||
</ol>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
const colorList = [
|
||||
'slate',
|
||||
'gray',
|
||||
'zinc',
|
||||
'neutral',
|
||||
'stone',
|
||||
'red',
|
||||
'orange',
|
||||
'amber',
|
||||
'yellow',
|
||||
'lime',
|
||||
'green',
|
||||
'emerald',
|
||||
'teal',
|
||||
'cyan',
|
||||
'sky',
|
||||
'blue',
|
||||
'indigo',
|
||||
'violet',
|
||||
'purple',
|
||||
'fuchsia',
|
||||
'pink',
|
||||
'rose',
|
||||
] as const;
|
||||
38
src/app/error.tsx
Normal file
38
src/app/error.tsx
Normal file
@@ -0,0 +1,38 @@
|
||||
'use client'; // Error components must be Client Components
|
||||
|
||||
import * as React from 'react';
|
||||
import { RiAlarmWarningFill } from 'react-icons/ri';
|
||||
|
||||
import TextButton from '@/components/buttons/TextButton';
|
||||
|
||||
export default function Error({
|
||||
error,
|
||||
reset,
|
||||
}: {
|
||||
error: Error & { digest?: string };
|
||||
reset: () => void;
|
||||
}) {
|
||||
React.useEffect(() => {
|
||||
// eslint-disable-next-line no-console
|
||||
console.error(error);
|
||||
}, [error]);
|
||||
|
||||
return (
|
||||
<main>
|
||||
<section className='bg-white'>
|
||||
<div className='layout flex min-h-screen flex-col items-center justify-center text-center text-black'>
|
||||
<RiAlarmWarningFill
|
||||
size={60}
|
||||
className='drop-shadow-glow animate-flicker text-red-500'
|
||||
/>
|
||||
<h1 className='mt-8 text-4xl md:text-6xl'>
|
||||
Oops, something went wrong!
|
||||
</h1>
|
||||
<TextButton variant='basic' onClick={reset} className='mt-4'>
|
||||
Try again
|
||||
</TextButton>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
62
src/app/layout.tsx
Normal file
62
src/app/layout.tsx
Normal file
@@ -0,0 +1,62 @@
|
||||
import { Metadata } from 'next';
|
||||
import * as React from 'react';
|
||||
|
||||
import '@/styles/globals.css';
|
||||
// !STARTERCONF This is for demo purposes, remove @/styles/colors.css import immediately
|
||||
import '@/styles/colors.css';
|
||||
|
||||
import { siteConfig } from '@/constant/config';
|
||||
|
||||
// !STARTERCONF Change these default meta
|
||||
// !STARTERCONF Look at @/constant/config to change them
|
||||
export const metadata: Metadata = {
|
||||
metadataBase: new URL(siteConfig.url),
|
||||
title: {
|
||||
default: siteConfig.title,
|
||||
template: `%s | ${siteConfig.title}`,
|
||||
},
|
||||
description: siteConfig.description,
|
||||
robots: { index: true, follow: true },
|
||||
// !STARTERCONF this is the default favicon, you can generate your own from https://realfavicongenerator.net/
|
||||
// ! copy to /favicon folder
|
||||
icons: {
|
||||
icon: '/favicon/favicon.ico',
|
||||
shortcut: '/favicon/favicon-16x16.png',
|
||||
apple: '/favicon/apple-touch-icon.png',
|
||||
},
|
||||
manifest: `/favicon/site.webmanifest`,
|
||||
openGraph: {
|
||||
url: siteConfig.url,
|
||||
title: siteConfig.title,
|
||||
description: siteConfig.description,
|
||||
siteName: siteConfig.title,
|
||||
images: [`${siteConfig.url}/images/og.jpg`],
|
||||
type: 'website',
|
||||
locale: 'en_US',
|
||||
},
|
||||
twitter: {
|
||||
card: 'summary_large_image',
|
||||
title: siteConfig.title,
|
||||
description: siteConfig.description,
|
||||
images: [`${siteConfig.url}/images/og.jpg`],
|
||||
// creator: '@th_clarence',
|
||||
},
|
||||
// authors: [
|
||||
// {
|
||||
// name: 'Theodorus Clarence',
|
||||
// url: 'https://theodorusclarence.com',
|
||||
// },
|
||||
// ],
|
||||
};
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
}: {
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<html>
|
||||
<body>{children}</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
24
src/app/not-found.tsx
Normal file
24
src/app/not-found.tsx
Normal file
@@ -0,0 +1,24 @@
|
||||
import { Metadata } from 'next';
|
||||
import * as React from 'react';
|
||||
import { RiAlarmWarningFill } from 'react-icons/ri';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Not Found',
|
||||
};
|
||||
|
||||
export default function NotFound() {
|
||||
return (
|
||||
<main>
|
||||
<section className='bg-white'>
|
||||
<div className='layout flex min-h-screen flex-col items-center justify-center text-center text-black'>
|
||||
<RiAlarmWarningFill
|
||||
size={60}
|
||||
className='drop-shadow-glow animate-flicker text-red-500'
|
||||
/>
|
||||
<h1 className='mt-8 text-4xl md:text-6xl'>Page Not Found</h1>
|
||||
<a href='/'>Back to home</a>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
72
src/app/page.tsx
Normal file
72
src/app/page.tsx
Normal file
@@ -0,0 +1,72 @@
|
||||
'use client';
|
||||
|
||||
import Head from 'next/head';
|
||||
import * as React from 'react';
|
||||
import '@/lib/env';
|
||||
|
||||
import ArrowLink from '@/components/links/ArrowLink';
|
||||
import ButtonLink from '@/components/links/ButtonLink';
|
||||
import UnderlineLink from '@/components/links/UnderlineLink';
|
||||
import UnstyledLink from '@/components/links/UnstyledLink';
|
||||
|
||||
/**
|
||||
* SVGR Support
|
||||
* Caveat: No React Props Type.
|
||||
*
|
||||
* You can override the next-env if the type is important to you
|
||||
* @see https://stackoverflow.com/questions/68103844/how-to-override-next-js-svg-module-declaration
|
||||
*/
|
||||
import Logo from '~/svg/Logo.svg';
|
||||
|
||||
// !STARTERCONF -> Select !STARTERCONF and CMD + SHIFT + F
|
||||
// Before you begin editing, follow all comments with `STARTERCONF`,
|
||||
// to customize the default configuration.
|
||||
|
||||
export default function HomePage() {
|
||||
return (
|
||||
<main>
|
||||
<Head>
|
||||
<title>Hi</title>
|
||||
</Head>
|
||||
<section className='bg-white'>
|
||||
<div className='layout relative flex min-h-screen flex-col items-center justify-center py-12 text-center'>
|
||||
<Logo className='w-16' />
|
||||
<h1 className='mt-4'>Next.js + Tailwind CSS + TypeScript Starter</h1>
|
||||
<p className='mt-2 text-sm text-gray-800'>
|
||||
A starter for Next.js, Tailwind CSS, and TypeScript with Absolute
|
||||
Import, Seo, Link component, pre-configured with Husky{' '}
|
||||
</p>
|
||||
<p className='mt-2 text-sm text-gray-700'>
|
||||
<ArrowLink href='https://github.com/theodorusclarence/ts-nextjs-tailwind-starter'>
|
||||
See the repository
|
||||
</ArrowLink>
|
||||
</p>
|
||||
|
||||
<ButtonLink className='mt-6' href='/components' variant='light'>
|
||||
See all components
|
||||
</ButtonLink>
|
||||
|
||||
<UnstyledLink
|
||||
href='https://vercel.com/new/git/external?repository-url=https%3A%2F%2Fgithub.com%2Ftheodorusclarence%2Fts-nextjs-tailwind-starter'
|
||||
className='mt-4'
|
||||
>
|
||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||
<img
|
||||
width='92'
|
||||
height='32'
|
||||
src='https://vercel.com/button'
|
||||
alt='Deploy with Vercel'
|
||||
/>
|
||||
</UnstyledLink>
|
||||
|
||||
<footer className='absolute bottom-2 text-gray-700'>
|
||||
© {new Date().getFullYear()} By{' '}
|
||||
<UnderlineLink href='https://theodorusclarence.com?ref=tsnextstarter'>
|
||||
Theodorus Clarence
|
||||
</UnderlineLink>
|
||||
</footer>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user