Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion app/(private)/anotherpage/page.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,40 @@
'use client';
import Link from 'next/link';
import { useEffect, useState } from 'react';

export default function AnotherPage() {
type messageType = {
message: string;
};
const [message, setMessage] = useState();
useEffect(() => {
console.log(message);
}, [message]);
return (
<main>
<div>
<p className="absolute left-1/2 top-[calc(50%-0.75rem)]">
Another Page
<Link href="/home" className="block underline text-blue-600">
<div className="text-3xl text-black"> {message}</div>
<Link href="/home" className="block text-blue-600 underline">
Go to Home
</Link>
</p>
<button
className="rounded-lg bg-blue-500 p-2"
onClick={async () => {
const res = await fetch('api/getSamplePostResponse', {
method: 'POST',
body: JSON.stringify({ hello: 'Zernie' }),
});
if (res.ok) {
const { message } = await res.json();
setMessage(message);
}
}}
>
TEST
</button>
</div>
</main>
);
Expand Down
16 changes: 13 additions & 3 deletions app/(private)/home/page.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,32 @@
'use client';
import { Button as CreateUserBtn } from '@/app/components/Button';
import CreateUserForm from '@/app/components/CreateUserForm';

import Modal from '@/app/components/Modal';
import { signOut } from 'next-auth/react';
import Link from 'next/link';

export default function Home() {
return (
<main>
<div className="container mx-auto p-10">
<main className="flex h-full w-full flex-col">
<div className="container flex w-full justify-between p-10">
<CreateUserBtn
elTag="linkTag"
title="crate new user"
btnStyles="rounded-full bg-primary px-4 py-2 font-bold capitalize text-black hover:bg-secondary"
path="?createuser=true"
type="button"
/>
{/* <Modal element={<CreateUserForm />} /> */}

<Modal element={<CreateUserForm />} />
<button
className="rounded-full bg-red-300 px-4 py-2 font-bold capitalize text-black hover:bg-red-200"
onClick={() => {
signOut();
}}
>
Logout
</button>
</div>

<div>
Expand Down
118 changes: 68 additions & 50 deletions app/(public)/products/page.tsx
Original file line number Diff line number Diff line change
@@ -1,57 +1,75 @@
'use client'
'use client';

// Components
import GetComponent from "@/app/components/Products/GetComponent";
import PostComponent from "@/app/components/Products/PostComponent";
import ProductLabel from "@/app/components/Products/ProductLabel";
import ProductTable from "@/app/components/Products/ProductTable";
import GetComponent from '@/app/components/Products/GetComponent';
import PostComponent from '@/app/components/Products/PostComponent';
import ProductLabel from '@/app/components/Products/ProductLabel';
import ProductTable from '@/app/components/Products/ProductTable';

// Utility
import { apiRequest } from "@/app/utils/apiRequest";
import { useState } from "react";
import { apiRequest } from '@/app/utils/apiRequest';
import ProductsTable from '@/components/ProductsTable';
import { useState } from 'react';

export default function getProducts() {
const [productName, setProductName] = useState('');
const [itemCode, setItemCode] = useState('');
const [realItemCode, setRealItemCode] = useState('');
const [quantity, setQuantity] = useState(0);
const [products, setProducts] = useState([]);


async function handlePost(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
const data = await apiRequest('/api/products', 'POST', { productName, itemCode: itemCode.toUpperCase(), quantity })
setProducts(data.rows);
}

async function handleGet(e: React.MouseEvent<HTMLButtonElement>) {
e.preventDefault();
const data = await apiRequest(`/api/products?itemCode=${realItemCode.toUpperCase()}`, 'GET')
setProducts(data);
}

async function handleGetAll(e: React.MouseEvent<HTMLButtonElement>) {
e.preventDefault();
const data = await apiRequest('/api/products', 'GET')
setProducts(data);
}

const isPostValid = itemCode !== '' && productName !== '' && quantity > 0;
const isGetValid = realItemCode !== '';


return (
<div className="flex flex-wrap justify-center place-items-center text-white">
<div className="w-full flex flex-col items-center justify-center mt-20">
<PostComponent setProductName={setProductName} setItemCode={setItemCode} setQuantity={setQuantity} handlePost={handlePost} isPostValid={isPostValid} />
<GetComponent setRealItemCode={setRealItemCode} isGetValid={isGetValid} handleGet={handleGet} handleGetAll={handleGetAll} />
</div>
<main className="mt-10 w-[700px] border border-black flex p-5 text-black">
<div className="w-full flex flex-col justify-center">
<ProductLabel />
<ProductTable products={products} />
</div>
</main>
const [productName, setProductName] = useState('');
const [itemCode, setItemCode] = useState('');
const [realItemCode, setRealItemCode] = useState('');
const [quantity, setQuantity] = useState(0);
const [products, setProducts] = useState([]);

async function handlePost(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault();
const data = await apiRequest('/api/products', 'POST', {
productName,
itemCode: itemCode.toUpperCase(),
quantity,
});
setProducts(data.rows);
}

async function handleGet(e: React.MouseEvent<HTMLButtonElement>) {
e.preventDefault();
const data = await apiRequest(
`/api/products?itemCode=${realItemCode.toUpperCase()}`,
'GET',
);
setProducts(data);
}

async function handleGetAll(e: React.MouseEvent<HTMLButtonElement>) {
e.preventDefault();
const data = await apiRequest('/api/products', 'GET');
setProducts(data);
}

const isPostValid = itemCode !== '' && productName !== '' && quantity > 0;
const isGetValid = realItemCode !== '';

return (
<div className="flex flex-wrap place-items-center justify-center text-white">
<div className="mt-20 flex w-full flex-col items-center justify-center">
<PostComponent
setProductName={setProductName}
setItemCode={setItemCode}
setQuantity={setQuantity}
handlePost={handlePost}
isPostValid={isPostValid}
/>
<GetComponent
setRealItemCode={setRealItemCode}
isGetValid={isGetValid}
handleGet={handleGet}
handleGetAll={handleGetAll}
/>
</div>
<main className="mt-10 flex w-[700px] border border-black p-5 text-black">
<div className="flex w-full flex-col justify-center">
{/* <ProductLabel /> */}
{/* <ProductTable products={products} /> */}
<ProductsTable />
</div>
)
}
</main>
</div>
);
}
76 changes: 76 additions & 0 deletions app/(public)/register/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
'use client';
import { FormEvent } from 'react';

const Login = () => {
const handleSubmit = async (e: FormEvent<HTMLFormElement>) => {
e.preventDefault();
const formData = new FormData(e.currentTarget);
const response = await fetch('/api/auth/register', {
method: 'POST',
body: JSON.stringify({
email: formData.get('email'),
password: formData.get('password'),
firstName: formData.get('firstName'), // Include firstName
lastName: formData.get('lastName'), // Include lastName
}),
});
};
return (
<div className="flex h-screen flex-col items-center justify-center space-y-4 bg-gray-200">
<h1 className="text-center text-xl font-bold">Logo</h1>
<form className="flex flex-col" onSubmit={handleSubmit}>
<div className="mt-4 flex justify-between">
<label htmlFor="email" className="py-2 pr-4">
Email Address
</label>
<input
type="text"
id="email"
name="email"
className="rounded-md p-2"
/>
</div>
<div className="mt-4 flex justify-between">
<label htmlFor="password" className="py-2 pr-4">
Password
</label>
<input
type="password" // Change type to password for security
id="password"
name="password"
className="rounded-md p-2"
/>
</div>
<div className="mt-4 flex justify-between">
<label htmlFor="firstName" className="py-2 pr-4">
First Name
</label>
<input
type="text"
id="firstName"
name="firstName"
className="rounded-md p-2"
/>
</div>
<div className="mt-4 flex justify-between">
<label htmlFor="lastName" className="py-2 pr-4">
Last Name
</label>
<input
type="text"
id="lastName"
name="lastName"
className="rounded-md p-2"
/>
</div>
<button
type="submit"
className="mt-10 self-center rounded-md bg-gray-500 px-4 py-2 font-bold text-white hover:bg-gray-700"
>
Login
</button>
</form>
</div>
);
};
export default Login;
51 changes: 38 additions & 13 deletions app/api/auth/[...nextauth]/route.ts
Original file line number Diff line number Diff line change
@@ -1,25 +1,50 @@
import NextAuth from 'next-auth';
import GithubProvider from 'next-auth/providers/github';
import CredentialsProvider from 'next-auth/providers/credentials';
import { compare } from 'bcrypt';
import { db } from '@/db/drizzle/db';
import { user } from '@/db/drizzle/schema/user';
import { eq } from 'drizzle-orm';

const handler = NextAuth({
session: { strategy: 'jwt' },
providers: [
GithubProvider({
clientId: process.env.GITHUB_ID ?? '',
clientSecret: process.env.GITHUB_SECRET ?? '',
CredentialsProvider({
name: 'Credentials',
credentials: {
username: {},
password: {},
},
async authorize(credentials, req) {
const { email, password } = credentials;
console.log(credentials);
// Add logic here to look up the user from the credentials supplied
const userExists = (
await db.select().from(user).where(eq(user.email, email))
)[0];
const isPasswordValid = await compare(
password || '',
userExists.password,
);
if (isPasswordValid) {
return { id: userExists.id, email: userExists.email };
}
return null;
},
}),
],
secret: process.env.NEXTAUTH_SECRET,
pages: {
signIn: '/',
// error: '/auth/error',
// signOut: '/auth/signout'
},
callbacks: {
async signIn({ user, account, profile, email, credentials }) {
console.log(
`${JSON.stringify(user)} ${JSON.stringify(account)} ${JSON.stringify(
profile
)} ${email} ${credentials}`
);
return true;
async jwt({ token, user, session }) {
return { ...token, ...user };
},
async redirect({ baseUrl }) {
return `${baseUrl}/home`;
async session({ session, token, user }) {
session.user = token;
return session;
},
},
});
Expand Down
32 changes: 32 additions & 0 deletions app/api/auth/register/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { NextResponse } from 'next/server';
import { hash } from 'bcrypt';
import { db } from '@/db/drizzle/db';
import { user } from '@/db/drizzle/schema/user';

import { eq } from 'drizzle-orm';

export async function POST(request: Request) {
try {
const { email, password, firstName, lastName } = await request.json();
// validate email and password
const hashedPassword = await hash(password, 10);
const existingUser = await db
.select()
.from(user)
.where(eq(user.email, email));

if (existingUser[0]) {
throw new Error('User with this email or employee ID already exists.');
}
const resp = await db.insert(user).values({
firstName,
lastName, // Set to null if lastName is undefined
email,
password: hashedPassword,
});
console.log(resp)
return NextResponse.json({ email, password });
} catch (e) {
console.log({ e });
}
}
11 changes: 8 additions & 3 deletions app/api/getSamplePostResponse/route.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { type NextRequest } from 'next/server';
import { NextResponse, type NextRequest } from 'next/server';
import { getToken } from 'next-auth/jwt';

export async function POST(request: NextRequest) {
return Response.json({ message: JSON.stringify(await request.json()) });
export async function POST(req: NextRequest) {
const token = await getToken({ req });
if (!token) {
return NextResponse.json({ message: 'Invalid token ' });
}
return NextResponse.json({ message: "Hello" });
}
Loading