added mail service
This commit is contained in:
18
app/[locale]/(protected)/cabinet/page.tsx
Normal file
18
app/[locale]/(protected)/cabinet/page.tsx
Normal file
@@ -0,0 +1,18 @@
|
||||
import { auth, signOut } from '@/config/auth'
|
||||
|
||||
const CabinetPage = async () => {
|
||||
const session = await auth()
|
||||
return (
|
||||
<div>
|
||||
{JSON.stringify(session)}
|
||||
<form action={async () => {
|
||||
'use server'
|
||||
await signOut()
|
||||
}}>
|
||||
<button type="submit">SignOut {session?.user.role}</button>
|
||||
</form>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default CabinetPage
|
||||
23
app/[locale]/(root)/(routes)/about/page.tsx
Normal file
23
app/[locale]/(root)/(routes)/about/page.tsx
Normal file
@@ -0,0 +1,23 @@
|
||||
'use client'
|
||||
|
||||
import mailer from '@/lib/mailer'
|
||||
|
||||
export default function AboutPage () {
|
||||
const onClick = () => {
|
||||
mailer({
|
||||
to: [
|
||||
{ name: 'Yevhen', address: 'it@amok.space' },
|
||||
{ name: 'Євген', address: 'yevhen.odynets@gmail.com' },
|
||||
],
|
||||
subject: 'ПОСИЛЕННЯ МОБІЛІЗАЦІЇ В УКРАЇНІ',
|
||||
html: `<div>Коли Рада <strong>розгляне</strong> законопроєкт про мобілізацію у <del>другому</del> читанні</div>`,
|
||||
}).catch(console.error)
|
||||
}
|
||||
|
||||
return (
|
||||
<button onClick={onClick}
|
||||
className="bg-transparent hover:bg-blue-500 text-blue-700 font-semibold hover:text-white py-2 px-4 border border-blue-500 hover:border-transparent">
|
||||
sendmail
|
||||
</button>
|
||||
)
|
||||
}
|
||||
3
app/[locale]/(root)/(routes)/about/us/page.tsx
Normal file
3
app/[locale]/(root)/(routes)/about/us/page.tsx
Normal file
@@ -0,0 +1,3 @@
|
||||
export default function AboutUsPage () {
|
||||
return (<div>AboutUsPage</div>)
|
||||
}
|
||||
29
app/[locale]/(root)/page.tsx
Normal file
29
app/[locale]/(root)/page.tsx
Normal file
@@ -0,0 +1,29 @@
|
||||
import { Poppins } from 'next/font/google'
|
||||
import { getScopedI18n } from '@/locales/server'
|
||||
import { cn } from '@/lib/utils'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import LoginButton from '@/components/auth/LoginButton'
|
||||
import { bg as bgg } from '@/config/layout'
|
||||
|
||||
const font = Poppins({
|
||||
subsets: ['latin'], weight: ['600'],
|
||||
})
|
||||
|
||||
export default async function Home () {
|
||||
const t = await getScopedI18n('auth')
|
||||
return (<main
|
||||
className="flex flex-col items-center justify-center h-full bg-[radial-gradient(ellipse_at_top,_var(--tw-gradient-stops))] from-lime-400 to-emerald-800">
|
||||
<div className="space-y-6 text-center">
|
||||
<h1 className={cn('text-6xl font-semibold text-white drop-shadow-md',
|
||||
font.className)}>
|
||||
🔐 {t('title')}
|
||||
</h1>
|
||||
<p className="text-lg text-white">{t('subtitle')}</p>
|
||||
<div>
|
||||
<LoginButton>
|
||||
<Button variant="secondary" size="lg">{t('sign_in')}</Button>
|
||||
</LoginButton>
|
||||
</div>
|
||||
</div>
|
||||
</main>)
|
||||
}
|
||||
9
app/[locale]/auth/error/page.tsx
Normal file
9
app/[locale]/auth/error/page.tsx
Normal file
@@ -0,0 +1,9 @@
|
||||
import ErrorCard from '@/components/auth/ErrorCard'
|
||||
|
||||
const AuthErrorPage = () => {
|
||||
return (
|
||||
<ErrorCard/>
|
||||
)
|
||||
}
|
||||
|
||||
export default AuthErrorPage
|
||||
22
app/[locale]/auth/layout.tsx
Normal file
22
app/[locale]/auth/layout.tsx
Normal file
@@ -0,0 +1,22 @@
|
||||
'use client'
|
||||
|
||||
import { ReactElement } from 'react'
|
||||
import Navbar from '@/components/auth/Navbar'
|
||||
|
||||
type Props = {
|
||||
//params: { locale: string };
|
||||
children: ReactElement;
|
||||
}
|
||||
const AuthLayout = ({ children }: Props) => {
|
||||
return (
|
||||
<>
|
||||
<Navbar/>
|
||||
<div
|
||||
className="h-full flex items-center justify-center bg-[radial-gradient(ellipse_at_top,_var(--tw-gradient-stops))] from-sky-400 to-blue-800">
|
||||
{children}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default AuthLayout
|
||||
9
app/[locale]/auth/login/page.tsx
Normal file
9
app/[locale]/auth/login/page.tsx
Normal file
@@ -0,0 +1,9 @@
|
||||
import { LoginForm } from '@/components/auth/LoginForm'
|
||||
|
||||
const LoginPage = () => {
|
||||
return (
|
||||
<LoginForm/>
|
||||
)
|
||||
}
|
||||
|
||||
export default LoginPage
|
||||
11
app/[locale]/auth/register/page.tsx
Normal file
11
app/[locale]/auth/register/page.tsx
Normal file
@@ -0,0 +1,11 @@
|
||||
import { RegisterForm } from '@/components/auth/RegisterForm'
|
||||
|
||||
const RegisterPage = () => {
|
||||
return (
|
||||
<div>
|
||||
<RegisterForm/>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default RegisterPage
|
||||
66
app/[locale]/globals.css
Normal file
66
app/[locale]/globals.css
Normal file
@@ -0,0 +1,66 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
html,
|
||||
body,
|
||||
:root {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
@layer base {
|
||||
:root {
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 222.2 84% 4.9%;
|
||||
--card: 0 0% 100%;
|
||||
--card-foreground: 222.2 84% 4.9%;
|
||||
--popover: 0 0% 100%;
|
||||
--popover-foreground: 222.2 84% 4.9%;
|
||||
--primary: 221.2 83.2% 53.3%;
|
||||
--primary-foreground: 210 40% 98%;
|
||||
--secondary: 210 40% 96.1%;
|
||||
--secondary-foreground: 222.2 47.4% 11.2%;
|
||||
--muted: 210 40% 96.1%;
|
||||
--muted-foreground: 215.4 16.3% 46.9%;
|
||||
--accent: 210 40% 96.1%;
|
||||
--accent-foreground: 222.2 47.4% 11.2%;
|
||||
--destructive: 0 84.2% 60.2%;
|
||||
--destructive-foreground: 210 40% 98%;
|
||||
--border: 214.3 31.8% 91.4%;
|
||||
--input: 214.3 31.8% 91.4%;
|
||||
--ring: 221.2 83.2% 53.3%;
|
||||
--radius: 0rem;
|
||||
}
|
||||
|
||||
.dark {
|
||||
--background: 222.2 84% 4.9%;
|
||||
--foreground: 210 40% 98%;
|
||||
--card: 222.2 84% 4.9%;
|
||||
--card-foreground: 210 40% 98%;
|
||||
--popover: 222.2 84% 4.9%;
|
||||
--popover-foreground: 210 40% 98%;
|
||||
--primary: 217.2 91.2% 59.8%;
|
||||
--primary-foreground: 222.2 47.4% 11.2%;
|
||||
--secondary: 217.2 32.6% 17.5%;
|
||||
--secondary-foreground: 210 40% 98%;
|
||||
--muted: 217.2 32.6% 17.5%;
|
||||
--muted-foreground: 215 20.2% 65.1%;
|
||||
--accent: 217.2 32.6% 17.5%;
|
||||
--accent-foreground: 210 40% 98%;
|
||||
--destructive: 0 62.8% 30.6%;
|
||||
--destructive-foreground: 210 40% 98%;
|
||||
--border: 217.2 32.6% 17.5%;
|
||||
--input: 217.2 32.6% 17.5%;
|
||||
--ring: 224.3 76.3% 48%;
|
||||
}
|
||||
}
|
||||
|
||||
@layer base {
|
||||
* {
|
||||
@apply border-border;
|
||||
}
|
||||
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
}
|
||||
}
|
||||
29
app/[locale]/layout.tsx
Normal file
29
app/[locale]/layout.tsx
Normal file
@@ -0,0 +1,29 @@
|
||||
import type { Metadata } from 'next'
|
||||
import { Inter } from 'next/font/google'
|
||||
import './globals.css'
|
||||
import { ReactElement } from 'react'
|
||||
import { I18nProviderClient } from '@/locales/client'
|
||||
import { lc } from '@/lib/utils'
|
||||
|
||||
const inter = Inter({ subsets: ['cyrillic'] })
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Create Next App', description: 'Generated by create next app',
|
||||
}
|
||||
|
||||
type Props = {
|
||||
params: { locale: string }; children: ReactElement;
|
||||
}
|
||||
|
||||
export default function RootLayout ({
|
||||
params: { locale }, children,
|
||||
}: Readonly<Props>) {
|
||||
|
||||
return (<html lang={lc(locale).java}>
|
||||
<body className={inter.className}>
|
||||
<I18nProviderClient locale={locale} fallback={<p>Loading...</p>}>
|
||||
{children}
|
||||
</I18nProviderClient>
|
||||
</body>
|
||||
</html>)
|
||||
}
|
||||
1
app/api/auth/[...nextauth]/route.ts
Normal file
1
app/api/auth/[...nextauth]/route.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { GET, POST } from '@/config/auth'
|
||||
BIN
app/favicon.ico
BIN
app/favicon.ico
Binary file not shown.
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 1.1 KiB |
@@ -1,33 +0,0 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
:root {
|
||||
--foreground-rgb: 0, 0, 0;
|
||||
--background-start-rgb: 214, 219, 220;
|
||||
--background-end-rgb: 255, 255, 255;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
:root {
|
||||
--foreground-rgb: 255, 255, 255;
|
||||
--background-start-rgb: 0, 0, 0;
|
||||
--background-end-rgb: 0, 0, 0;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
color: rgb(var(--foreground-rgb));
|
||||
background: linear-gradient(
|
||||
to bottom,
|
||||
transparent,
|
||||
rgb(var(--background-end-rgb))
|
||||
)
|
||||
rgb(var(--background-start-rgb));
|
||||
}
|
||||
|
||||
@layer utilities {
|
||||
.text-balance {
|
||||
text-wrap: balance;
|
||||
}
|
||||
}
|
||||
@@ -1,22 +0,0 @@
|
||||
import type { Metadata } from "next";
|
||||
import { Inter } from "next/font/google";
|
||||
import "./globals.css";
|
||||
|
||||
const inter = Inter({ subsets: ["latin"] });
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Create Next App",
|
||||
description: "Generated by create next app",
|
||||
};
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
}: Readonly<{
|
||||
children: React.ReactNode;
|
||||
}>) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<body className={inter.className}>{children}</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
113
app/page.tsx
113
app/page.tsx
@@ -1,113 +0,0 @@
|
||||
import Image from "next/image";
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<main className="flex min-h-screen flex-col items-center justify-between p-24">
|
||||
<div className="z-10 max-w-5xl w-full items-center justify-between font-mono text-sm lg:flex">
|
||||
<p className="fixed left-0 top-0 flex w-full justify-center border-b border-gray-300 bg-gradient-to-b from-zinc-200 pb-6 pt-8 backdrop-blur-2xl dark:border-neutral-800 dark:bg-zinc-800/30 dark:from-inherit lg:static lg:w-auto lg:rounded-xl lg:border lg:bg-gray-200 lg:p-4 lg:dark:bg-zinc-800/30">
|
||||
Get started by editing
|
||||
<code className="font-mono font-bold">app/page.tsx</code>
|
||||
</p>
|
||||
<div className="fixed bottom-0 left-0 flex h-48 w-full items-end justify-center bg-gradient-to-t from-white via-white dark:from-black dark:via-black lg:static lg:h-auto lg:w-auto lg:bg-none">
|
||||
<a
|
||||
className="pointer-events-none flex place-items-center gap-2 p-8 lg:pointer-events-auto lg:p-0"
|
||||
href="https://vercel.com?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
By{" "}
|
||||
<Image
|
||||
src="/vercel.svg"
|
||||
alt="Vercel Logo"
|
||||
className="dark:invert"
|
||||
width={100}
|
||||
height={24}
|
||||
priority
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="relative flex place-items-center before:absolute before:h-[300px] before:w-full sm:before:w-[480px] before:-translate-x-1/2 before:rounded-full before:bg-gradient-radial before:from-white before:to-transparent before:blur-2xl before:content-[''] after:absolute after:-z-20 after:h-[180px] after:w-full sm:after:w-[240px] after:translate-x-1/3 after:bg-gradient-conic after:from-sky-200 after:via-blue-200 after:blur-2xl after:content-[''] before:dark:bg-gradient-to-br before:dark:from-transparent before:dark:to-blue-700 before:dark:opacity-10 after:dark:from-sky-900 after:dark:via-[#0141ff] after:dark:opacity-40 before:lg:h-[360px] z-[-1]">
|
||||
<Image
|
||||
className="relative dark:drop-shadow-[0_0_0.3rem_#ffffff70] dark:invert"
|
||||
src="/next.svg"
|
||||
alt="Next.js Logo"
|
||||
width={180}
|
||||
height={37}
|
||||
priority
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="mb-32 grid text-center lg:max-w-5xl lg:w-full lg:mb-0 lg:grid-cols-4 lg:text-left">
|
||||
<a
|
||||
href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
|
||||
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<h2 className={`mb-3 text-2xl font-semibold`}>
|
||||
Docs{" "}
|
||||
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
|
||||
->
|
||||
</span>
|
||||
</h2>
|
||||
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
|
||||
Find in-depth information about Next.js features and API.
|
||||
</p>
|
||||
</a>
|
||||
|
||||
<a
|
||||
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
|
||||
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<h2 className={`mb-3 text-2xl font-semibold`}>
|
||||
Learn{" "}
|
||||
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
|
||||
->
|
||||
</span>
|
||||
</h2>
|
||||
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
|
||||
Learn about Next.js in an interactive course with quizzes!
|
||||
</p>
|
||||
</a>
|
||||
|
||||
<a
|
||||
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
|
||||
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<h2 className={`mb-3 text-2xl font-semibold`}>
|
||||
Templates{" "}
|
||||
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
|
||||
->
|
||||
</span>
|
||||
</h2>
|
||||
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
|
||||
Explore starter templates for Next.js.
|
||||
</p>
|
||||
</a>
|
||||
|
||||
<a
|
||||
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
|
||||
className="group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
>
|
||||
<h2 className={`mb-3 text-2xl font-semibold`}>
|
||||
Deploy{" "}
|
||||
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
|
||||
->
|
||||
</span>
|
||||
</h2>
|
||||
<p className={`m-0 max-w-[30ch] text-sm opacity-50 text-balance`}>
|
||||
Instantly deploy your Next.js site to a shareable URL with Vercel.
|
||||
</p>
|
||||
</a>
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user