api and shadcn
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
'use client';
|
||||
|
||||
import * as React from 'react';
|
||||
import { ThemeProvider as NextThemesProvider } from 'next-themes';
|
||||
import { type ThemeProviderProps } from 'next-themes';
|
||||
|
||||
export function ThemeProvider({ children, ...props }: ThemeProviderProps) {
|
||||
return <NextThemesProvider {...props}>{children}</NextThemesProvider>;
|
||||
}
|
||||
@@ -1,13 +1,87 @@
|
||||
import { NextResponse, NextRequest } from 'next/server';
|
||||
import { TwitterApi } from 'twitter-api-v2';
|
||||
import config from '@/env';
|
||||
import { PostRequest } from '@/platform';
|
||||
import config from '@/app/api/env';
|
||||
import { PostRequest } from '@/utils';
|
||||
import { inspect } from 'util';
|
||||
import database from '../database';
|
||||
import { generateUrlSafeString } from '@/utils';
|
||||
|
||||
// Account creation
|
||||
// Email doesn't exist
|
||||
// Password is between 6-20 characters
|
||||
export async function POST(req: NextRequest) {
|
||||
const { email, password } = await req.json();
|
||||
|
||||
if (typeof email !== 'string' || typeof password !== 'string')
|
||||
return NextResponse.json(
|
||||
{
|
||||
message:
|
||||
"Invalid structure, body requires 'email: string' and 'password: string'",
|
||||
},
|
||||
{ status: 400 }
|
||||
);
|
||||
|
||||
if (await database.users.countDocuments({ email }))
|
||||
return NextResponse.json(
|
||||
{
|
||||
message: 'Email already registered',
|
||||
},
|
||||
{ status: 409 }
|
||||
);
|
||||
|
||||
await database.users.insertOne({ email, password });
|
||||
|
||||
const response = NextResponse.json(
|
||||
{
|
||||
message: 'ok',
|
||||
},
|
||||
{ status: 200 }
|
||||
);
|
||||
|
||||
response.cookies.set('session_id', generateUrlSafeString(16));
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Account login
|
||||
// Email exists
|
||||
// Password is valid
|
||||
export async function GET(req: NextRequest) {
|
||||
const { email, password } = await req.json();
|
||||
|
||||
if (typeof email !== 'string' || typeof password !== 'string')
|
||||
return NextResponse.json(
|
||||
{
|
||||
message:
|
||||
"Invalid structure, body requires 'email: string' and 'password: string'",
|
||||
},
|
||||
{ status: 400 }
|
||||
);
|
||||
|
||||
const user = await database.users.findOne({ email });
|
||||
|
||||
if (!user)
|
||||
return NextResponse.json(
|
||||
{
|
||||
message: 'Invalid email',
|
||||
},
|
||||
{ status: 400 }
|
||||
);
|
||||
|
||||
if (user.password !== password)
|
||||
return NextResponse.json(
|
||||
{
|
||||
message: 'Invalid password',
|
||||
},
|
||||
{ status: 400 }
|
||||
);
|
||||
|
||||
const sessionId = (await database.sessions.insertOne({ email })).insertedId;
|
||||
|
||||
return NextResponse.json(
|
||||
{
|
||||
message: 'ok, feature not available yet',
|
||||
message: 'ok',
|
||||
sessionId,
|
||||
},
|
||||
{ status: 200 }
|
||||
);
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import { MongoClient } from 'mongodb';
|
||||
import config from './env';
|
||||
import { generateUrlSafeString, Session, User } from '@/utils';
|
||||
|
||||
const client = new MongoClient(config.mongoUrl);
|
||||
|
||||
const db = client.db('klayrion');
|
||||
|
||||
export default {
|
||||
users: db.collection<User>('users'),
|
||||
sessions: db.collection<Session>('sessions'),
|
||||
};
|
||||
@@ -0,0 +1,14 @@
|
||||
function error(name: string): string {
|
||||
throw `'${name}' not found in '.env'`;
|
||||
}
|
||||
|
||||
const config = {
|
||||
twitter: {
|
||||
key: process.env.TWITTER_KEY || error('TWITTER_KEY'),
|
||||
secret: process.env.TWITTER_SECRET || error('TWITTER_SECRET'),
|
||||
},
|
||||
|
||||
mongoUrl: process.env.MONGO_URL || error('MONGO_URL'),
|
||||
};
|
||||
|
||||
export default config;
|
||||
@@ -1,7 +1,7 @@
|
||||
import { NextResponse, NextRequest } from 'next/server';
|
||||
import { TwitterApi } from 'twitter-api-v2';
|
||||
import config from '@/env';
|
||||
import { PostRequest } from '@/platform';
|
||||
import config from '@/app/api/env';
|
||||
import { PostRequest } from '@/utils';
|
||||
import { inspect } from 'util';
|
||||
|
||||
export async function POST(req: NextRequest) {
|
||||
|
||||
+61
-10
@@ -2,20 +2,71 @@
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
:root {
|
||||
--background: #ffffff;
|
||||
--foreground: #171717;
|
||||
body {
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
}
|
||||
|
||||
@media (prefers-color-scheme: dark) {
|
||||
@layer base {
|
||||
:root {
|
||||
--background: #0a0a0a;
|
||||
--foreground: #ededed;
|
||||
--background: 0 0% 100%;
|
||||
--foreground: 0 0% 3.9%;
|
||||
--card: 0 0% 100%;
|
||||
--card-foreground: 0 0% 3.9%;
|
||||
--popover: 0 0% 100%;
|
||||
--popover-foreground: 0 0% 3.9%;
|
||||
--primary: 0 0% 9%;
|
||||
--primary-foreground: 0 0% 98%;
|
||||
--secondary: 0 0% 96.1%;
|
||||
--secondary-foreground: 0 0% 9%;
|
||||
--muted: 0 0% 96.1%;
|
||||
--muted-foreground: 0 0% 45.1%;
|
||||
--accent: 0 0% 96.1%;
|
||||
--accent-foreground: 0 0% 9%;
|
||||
--destructive: 0 84.2% 60.2%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
--border: 0 0% 89.8%;
|
||||
--input: 0 0% 89.8%;
|
||||
--ring: 0 0% 3.9%;
|
||||
--chart-1: 12 76% 61%;
|
||||
--chart-2: 173 58% 39%;
|
||||
--chart-3: 197 37% 24%;
|
||||
--chart-4: 43 74% 66%;
|
||||
--chart-5: 27 87% 67%;
|
||||
--radius: 0.5rem;
|
||||
}
|
||||
.dark {
|
||||
--background: 0 0% 3.9%;
|
||||
--foreground: 0 0% 98%;
|
||||
--card: 0 0% 3.9%;
|
||||
--card-foreground: 0 0% 98%;
|
||||
--popover: 0 0% 3.9%;
|
||||
--popover-foreground: 0 0% 98%;
|
||||
--primary: 0 0% 98%;
|
||||
--primary-foreground: 0 0% 9%;
|
||||
--secondary: 0 0% 14.9%;
|
||||
--secondary-foreground: 0 0% 98%;
|
||||
--muted: 0 0% 14.9%;
|
||||
--muted-foreground: 0 0% 63.9%;
|
||||
--accent: 0 0% 14.9%;
|
||||
--accent-foreground: 0 0% 98%;
|
||||
--destructive: 0 62.8% 30.6%;
|
||||
--destructive-foreground: 0 0% 98%;
|
||||
--border: 0 0% 14.9%;
|
||||
--input: 0 0% 14.9%;
|
||||
--ring: 0 0% 83.1%;
|
||||
--chart-1: 220 70% 50%;
|
||||
--chart-2: 160 60% 45%;
|
||||
--chart-3: 30 80% 55%;
|
||||
--chart-4: 280 65% 60%;
|
||||
--chart-5: 340 75% 55%;
|
||||
}
|
||||
}
|
||||
|
||||
body {
|
||||
color: var(--foreground);
|
||||
background: var(--background);
|
||||
font-family: Arial, Helvetica, sans-serif;
|
||||
@layer base {
|
||||
* {
|
||||
@apply border-border;
|
||||
}
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
}
|
||||
}
|
||||
|
||||
+27
-26
@@ -1,34 +1,35 @@
|
||||
import type { Metadata } from "next";
|
||||
import { Roboto, Roboto_Mono } from "next/font/google";
|
||||
import "./globals.css";
|
||||
|
||||
const roboto = Roboto({
|
||||
weight: "500",
|
||||
subsets: ["latin"],
|
||||
variable: "--font-roboto",
|
||||
});
|
||||
|
||||
const robotoMono = Roboto_Mono({
|
||||
weight: "500",
|
||||
subsets: ["latin"],
|
||||
variable: "--font-roboto-mono",
|
||||
});
|
||||
import type { Metadata } from 'next';
|
||||
import { cn } from '@/lib/utils';
|
||||
import './globals.css';
|
||||
import { ThemeProvider } from './ThemeProvider';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Klayrion: The best AI social media scheduling tool",
|
||||
description: "Generated by create next app",
|
||||
title: 'Create Next App',
|
||||
description: 'Generated by create next app',
|
||||
};
|
||||
|
||||
export default function RootLayout({
|
||||
children,
|
||||
children,
|
||||
}: Readonly<{
|
||||
children: React.ReactNode;
|
||||
children: React.ReactNode;
|
||||
}>) {
|
||||
return (
|
||||
<html lang="en">
|
||||
<body className={`${roboto.variable} ${robotoMono.variable} antialiased`}>
|
||||
{children}
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
return (
|
||||
<html lang="en" suppressHydrationWarning>
|
||||
<body
|
||||
suppressHydrationWarning
|
||||
className={cn(
|
||||
'min-h-screen bg-background font-sans antialiased'
|
||||
)}
|
||||
>
|
||||
<ThemeProvider
|
||||
attribute="class"
|
||||
defaultTheme="dark"
|
||||
enableSystem
|
||||
disableTransitionOnChange
|
||||
>
|
||||
{children}
|
||||
</ThemeProvider>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
'use client';
|
||||
|
||||
export default function Login() {
|
||||
return <div className="bg-[#ccc] w-1/2 h-screen ml-auto"></div>;
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
'use client';
|
||||
|
||||
export default function SignUp() {
|
||||
return <div className="bg-[#ccc] w-1/2 h-screen ml-auto"></div>;
|
||||
}
|
||||
Reference in New Issue
Block a user