feature - signin from signup

This commit is contained in:
James Wyndham 2024-02-22 10:23:12 +08:00
parent 91b69ce30f
commit edbf656701
9 changed files with 144 additions and 82 deletions

View File

@ -31,6 +31,7 @@ export default async function RootLayout({
children: React.ReactNode; children: React.ReactNode;
}) { }) {
const isUserLoggedIn = await isAuthenticated(cookies()); const isUserLoggedIn = await isAuthenticated(cookies());
console.log(isUserLoggedIn);
return ( return (
<html <html

View File

@ -107,7 +107,10 @@ function Header({ isUserLoggedIn }: HeaderProps) {
</button> </button>
</> </>
) : ( ) : (
<button onClick={() => logout()} className={`btn btn-error`}> <button
onClick={() => logout()}
className={`btn btn-error text-primary-content ml-2`}
>
Logout Logout
</button> </button>
)} )}

View File

@ -4,6 +4,8 @@ import { useForm } from "react-hook-form";
import { yupResolver } from "@hookform/resolvers/yup"; import { yupResolver } from "@hookform/resolvers/yup";
import { signUpValidationSchema } from "@/utils/form"; import { signUpValidationSchema } from "@/utils/form";
import { companySizeList } from "@/constants"; import { companySizeList } from "@/constants";
import pb from "@/lib/pocketbase";
import { login } from "@/app/(auth)/actions";
function ModalSignUp() { function ModalSignUp() {
const { const {
@ -14,6 +16,35 @@ function ModalSignUp() {
} = useForm({ } = useForm({
resolver: yupResolver(signUpValidationSchema), resolver: yupResolver(signUpValidationSchema),
}); });
const onSubmit = async (data: any) => {
data = {
emailVisibility: false,
lastSeen: new Date(),
role: "Admin",
displayName: `${data.firstName} ${data.lastName}`,
...data,
};
try {
//create organisation
const organisation = await pb.collection("organisation").create({
name: data.organisation,
organisationSize: data.organisationSize,
});
//create user
await pb
.collection("user")
.create({ ...data, organisation: organisation.id });
//login user
if (
(await login({ email: data.email, password: data.password })).success
) {
reset();
document.getElementById("sign-up-modal")?.click();
}
} catch (error) {
console.log("heyaa");
}
};
return ( return (
<> <>
<input <input
@ -50,13 +81,7 @@ function ModalSignUp() {
Excited to see what we&apos;ve got! Signup and get started! Excited to see what we&apos;ve got! Signup and get started!
</p> </p>
</div> </div>
<form <form onSubmit={handleSubmit(onSubmit)} className="w-full md:w-2/3">
onSubmit={handleSubmit((data) => {
console.log(data);
reset();
})}
className="w-full md:w-2/3"
>
<div className="relative mt-6"> <div className="relative mt-6">
<input <input
type="text" type="text"
@ -177,10 +202,10 @@ function ModalSignUp() {
className="py-3 px-4 block w-full bg-base-200 text-base-content border-white rounded-lg text-sm focus:border-blue-500 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none " className="py-3 px-4 block w-full bg-base-200 text-base-content border-white rounded-lg text-sm focus:border-blue-500 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none "
placeholder="Confirm Password..." placeholder="Confirm Password..."
aria-label="Confirmed Password" aria-label="Confirmed Password"
{...register("passwordConfirmation")} {...register("passwordConfirm")}
/> />
<div className="text-start text-sm italic text-error-content"> <div className="text-start text-sm italic text-error-content">
{errors.passwordConfirmation?.message}&nbsp; {errors.passwordConfirm?.message}&nbsp;
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,11 +1,27 @@
"use client"; "use client";
import colors, { hexToRgb } from "@/utils/colors"; import colors, { hexToRgb } from "@/utils/colors";
import { useTheme } from "next-themes"; import { useTheme } from "next-themes";
import React, { ReactNode } from "react"; import React, { ReactNode, useEffect, useMemo, useState } from "react";
const Background = ({ children }: { children: ReactNode }) => { const Background = ({ children }: { children: ReactNode }) => {
const { theme } = useTheme(); const { theme } = useTheme();
const backgroundColor = hexToRgb(colors[theme ?? "light"]["base-100"]); const [mounted, setMounted] = useState(false);
// useEffect only runs on the client, so now we can safely show the UI
useEffect(() => {
setMounted(true);
}, []);
if (!mounted) {
return (
<div className="h-full relative w-full bg-center bg-no-repeat bg-cover bg-fixed min-h-screen flex flex-col animation-pulse"></div>
);
}
console.log("theme", theme);
const backgroundColor = hexToRgb(colors[theme!]["base-100"]);
return ( return (
<div <div
className="h-full relative w-full bg-center bg-no-repeat bg-cover bg-fixed min-h-screen flex flex-col" className="h-full relative w-full bg-center bg-no-repeat bg-cover bg-fixed min-h-screen flex flex-col"

View File

@ -1,5 +1,4 @@
import { NextRequest, NextResponse } from "next/server"; import { NextRequest, NextResponse } from "next/server";
import pb from "./lib/pocketbase";
import { isAuthenticated } from "./lib/auth"; import { isAuthenticated } from "./lib/auth";
export async function middleware(request: NextRequest) { export async function middleware(request: NextRequest) {
@ -11,14 +10,14 @@ export async function middleware(request: NextRequest) {
) { ) {
return NextResponse.next(); return NextResponse.next();
} }
// const isLoggedIn = await isAuthenticated(request.cookies as any); const isLoggedIn = await isAuthenticated(request.cookies as any);
// if (pathname.startsWith("/account")) { if (pathname.startsWith("/account")) {
// if (isLoggedIn) { if (isLoggedIn) {
// return NextResponse.next(); return NextResponse.next();
// } else { } else {
// request.nextUrl.pathname = "/" request.nextUrl.pathname = "/"
// } }
// return NextResponse.redirect(request.nextUrl); return NextResponse.redirect(request.nextUrl);
// } }
// return NextResponse.next(); return NextResponse.next();
} }

View File

@ -15,15 +15,19 @@ const FormLeftDescriptionRightContactUs = () => {
resolver: yupResolver(contactUsValidationSchema), resolver: yupResolver(contactUsValidationSchema),
}); });
const onSubmit = (data: { const onSubmit = async (data: {
firstName: string; firstName: string;
lastName: string; lastName: string;
email: string; email: string;
phoneNumber?: string; phoneNumber?: string;
note?: string; note?: string;
}) => { }) => {
localStorage.setItem("contactus", JSON.stringify(data)); try {
pb.collection("contact").create(data); await pb.collection("contact").create({ source: "contactus", ...data });
localStorage.setItem("contactus", JSON.stringify(data));
} catch (error) {
console.log("heya");
}
}; };
return ( return (
<> <>

View File

@ -8,6 +8,7 @@ import Icon from "@/components/Icon";
import colors, { hexToRgb } from "@/utils/colors"; import colors, { hexToRgb } from "@/utils/colors";
import Footer from "@/components/Footer"; import Footer from "@/components/Footer";
import { useTheme } from "next-themes"; import { useTheme } from "next-themes";
import Background from "@/components/Utilities/Background";
const WaitingListWithImageHero = () => { const WaitingListWithImageHero = () => {
const { theme } = useTheme(); const { theme } = useTheme();
@ -21,28 +22,28 @@ const WaitingListWithImageHero = () => {
resolver: yupResolver(waitinglistValidationSchema), resolver: yupResolver(waitinglistValidationSchema),
}); });
const onSubmit = (data: { const onSubmit = async (data: {
firstName: string; firstName: string;
lastName: string; lastName: string;
email: string; email: string;
}) => { }) => {
localStorage.setItem("contact", JSON.stringify(data)); try {
pb.collection("contact").create(data); await pb.collection("contact").create({ source: "waitinglist", ...data });
localStorage.setItem("waitinglist", JSON.stringify(data));
} catch (error) {
console.log("heya");
}
}; };
return ( return (
<div <Background>
className="h-full relative w-full bg-center bg-no-repeat bg-cover bg-fixed"
style={{
backgroundImage: `linear-gradient(rgba(${backgroundColor?.r}, ${backgroundColor?.g}, ${backgroundColor?.b}, 0.7), rgba(135, 80, 156, 0.05)), url(/images/hero.jpg)`,
}}
>
<div className="h-screen w-full bg-clip flex items-center justify-center"> <div className="h-screen w-full bg-clip flex items-center justify-center">
<div className="text-center py-8 px-4 sm:px-6 lg:px-8"> <div className="text-center py-8 px-4 sm:px-6 lg:px-8">
<h1 className="font-semibold text-3xl sm:text-6xl text-base-content font-heading whitespace-nowrap flex flex-row justify-center pb-6 gap-x-3"> <h1 className="font-semibold text-3xl sm:text-6xl text-base-content font-heading whitespace-nowrap flex flex-row justify-center pb-6 gap-x-3">
<Icon name="LeafThree24Filled" size="xlarge" /> <Icon name="LeafThree24Filled" size="xlarge" />
Bethel Farms Bethel Farms
</h1> </h1>
{typeof window !== "undefined" && !localStorage.getItem("contact") ? ( {typeof window !== "undefined" &&
!localStorage.getItem("waitinglist") ? (
<> <>
<h2 className="text-2xl text-base-content"> <h2 className="text-2xl text-base-content">
Get notified when we launch Get notified when we launch
@ -61,7 +62,7 @@ const WaitingListWithImageHero = () => {
{...register("firstName")} {...register("firstName")}
type="text" type="text"
id="hs-cover-with-gradient-form-name-1" id="hs-cover-with-gradient-form-name-1"
className=" py-3 ps-11 pe-4 block w-full bg-base-100/[.03] border-white/20 placeholder:text-base-content dark:placeholder:bg-base-content placeholder:text-base-content rounded-lg text-sm focus:border-white/30 focus:ring-white/30 sm:p-4 sm:ps-11" className=" py-3 ps-11 pe-4 block w-full bg-base-100/[.03] border-white/20 placeholder:text-base-content placeholder:text-base-content rounded-lg text-sm focus:border-white/30 focus:ring-white/30 sm:p-4 sm:ps-11"
placeholder="First name" placeholder="First name"
/> />
<div className="absolute inset-y-0 start-0 flex items-center pointer-events-none z-20 ps-4"> <div className="absolute inset-y-0 start-0 flex items-center pointer-events-none z-20 ps-4">
@ -82,7 +83,7 @@ const WaitingListWithImageHero = () => {
</svg> </svg>
</div> </div>
</div> </div>
<div className="text-start text-sm italic text-error-content"> <div className="text-start text-sm italic text-error">
{errors.firstName?.message}&nbsp; {errors.firstName?.message}&nbsp;
</div> </div>
</div> </div>
@ -119,7 +120,7 @@ const WaitingListWithImageHero = () => {
</svg> </svg>
</div> </div>
</div> </div>
<div className="text-start text-sm italic text-error-content"> <div className="text-start text-sm italic text-error">
{errors.lastName?.message}&nbsp; {errors.lastName?.message}&nbsp;
</div> </div>
</div> </div>
@ -135,7 +136,7 @@ const WaitingListWithImageHero = () => {
{...register("email")} {...register("email")}
type="email" type="email"
id="hs-cover-with-gradient-form-email-1" id="hs-cover-with-gradient-form-email-1"
className=" py-3 ps-11 pe-4 block w-full bg-base-100/[.03] border-white/20 text-base-content placeholder:text-base-content dark:placeholder:bg-base-content rounded-lg text-sm focus:border-white/30 focus:ring-white/30 sm:p-4 sm:ps-11" className=" py-3 ps-11 pe-4 block w-full bg-base-100/[.03] border-white/20 text-base-content placeholder:text-base-content rounded-lg text-sm focus:border-white/30 focus:ring-white/30 sm:p-4 sm:ps-11"
placeholder="Email address" placeholder="Email address"
/> />
<div className="absolute inset-y-0 start-0 flex items-center pointer-events-none z-20 ps-4"> <div className="absolute inset-y-0 start-0 flex items-center pointer-events-none z-20 ps-4">
@ -156,15 +157,12 @@ const WaitingListWithImageHero = () => {
</svg> </svg>
</div> </div>
</div> </div>
<div className="text-start text-sm italic text-error-content"> <div className="text-start text-sm italic text-error">
{errors.email?.message}&nbsp; {errors.email?.message}&nbsp;
</div> </div>
</div> </div>
<div className="grid"> <div className="grid">
<button <button className="btn btn-neutral" type="submit">
className="btn btn-primary bg-base-content"
type="submit"
>
Join the waitlist Join the waitlist
<svg <svg
className="flex-shrink-0 size-4" className="flex-shrink-0 size-4"
@ -193,7 +191,7 @@ const WaitingListWithImageHero = () => {
</div> </div>
</div> </div>
<Footer /> <Footer />
</div> </Background>
); );
}; };

View File

@ -1,3 +1,4 @@
import pb from "@/lib/pocketbase";
import { newsletterValidationSchema } from "@/utils/form"; import { newsletterValidationSchema } from "@/utils/form";
import { yupResolver } from "@hookform/resolvers/yup"; import { yupResolver } from "@hookform/resolvers/yup";
import React from "react"; import React from "react";
@ -7,11 +8,20 @@ function Newsletter() {
const { const {
register, register,
handleSubmit, handleSubmit,
reset,
formState: { errors }, formState: { errors },
} = useForm({ } = useForm({
resolver: yupResolver(newsletterValidationSchema), resolver: yupResolver(newsletterValidationSchema),
}); });
const onSubmit = async (data: { email: string }) => {
try {
await pb.collection("contact").create({ source: "newsletter", ...data });
localStorage.setItem("newsletter", JSON.stringify(data));
} catch (error) {
console.log("heya");
}
};
return ( return (
<section> <section>
<div className="max-w-6xl mx-auto px-4 sm:px-6"> <div className="max-w-6xl mx-auto px-4 sm:px-6">
@ -20,43 +30,49 @@ function Newsletter() {
className="relative bg-gradient-to-r from-primary to-secondary py-10 px-8 md:py-16 md:px-12" className="relative bg-gradient-to-r from-primary to-secondary py-10 px-8 md:py-16 md:px-12"
data-aos="fade-up" data-aos="fade-up"
> >
<div className="relative flex flex-col lg:flex-row justify-between items-center"> {typeof window !== "undefined" &&
<div className="mb-6 lg:mr-16 lg:mb-0 text-center lg:text-left lg:w-1/2 text-primary-content"> !localStorage.getItem("newsletter") ? (
<h3 className=" mb-2 text-3xl font-black"> <div className="relative flex flex-col lg:flex-row justify-between items-center">
Stay Ahead of the Curve <div className="mb-6 lg:mr-16 lg:mb-0 text-center lg:text-left lg:w-1/2 text-primary-content">
</h3> <h3 className=" mb-2 text-3xl font-black">
<p className=" text-lg"> Stay Ahead of the Curve
Join our newsletter to get top news before anyone else. </h3>
</p> <p className=" text-lg">
</div> Join our newsletter to get top news before anyone else.
</p>
</div>
<div className="w-full lg:w-1/2"> <div className="w-full lg:w-1/2">
<form <form
onSubmit={handleSubmit((data) => { onSubmit={handleSubmit(onSubmit)}
console.log(data); className="flex flex-col sm:flex-row justify-center max-w-xs mx-auto sm:max-w-md lg:max-w-none gap-x-2"
reset(); >
})} <div className="w-full">
className="flex flex-col sm:flex-row justify-center max-w-xs mx-auto sm:max-w-md lg:max-w-none gap-x-2" <input
> id="NewsletterEmail"
<div className="w-full"> type="text"
<input className="py-3 px-4 block w-full text-base-content border-white rounded-lg text-sm focus:border-blue-500 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none "
id="NewsletterEmail" placeholder="Email…"
type="text" aria-label="Email…"
className="py-3 px-4 block w-full text-base-content border-white rounded-lg text-sm focus:border-blue-500 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none " {...register("email")}
placeholder="Email…" />
aria-label="Email…" <div className="text-start text-sm italic text-error-content">
{...register("email")} {errors.email?.message}&nbsp;
/> </div>
<div className="text-start text-sm italic text-error-content">
{errors.email?.message}&nbsp;
</div> </div>
</div> <button className="btn text-primary-content btn-neutral">
<button className="btn text-primary-content btn-neutral"> Subscribe
Subscribe </button>
</button> </form>
</form> </div>
</div> </div>
</div> ) : (
<div className="relative flex flex-col lg:flex-row justify-between items-center text-primary-content">
<h3 className=" mb-2 text-3xl font-black">
Thanks for subscribing. You won&apos;t regret it!
</h3>
</div>
)}
</div> </div>
</div> </div>
</section> </section>

View File

@ -51,7 +51,7 @@ const signUpValidationSchema = Yup.object().shape({
.required("Password is required.") .required("Password is required.")
.min(8, "Password is too short - should be 8 characters minimum.") .min(8, "Password is too short - should be 8 characters minimum.")
.minUppercase(1, "password must contain at least 1 upper case letter"), .minUppercase(1, "password must contain at least 1 upper case letter"),
passwordConfirmation: Yup.string() passwordConfirm: Yup.string()
.required("Please retype your password.") .required("Please retype your password.")
.oneOf([Yup.ref("password")], "Your passwords do not match."), .oneOf([Yup.ref("password")], "Your passwords do not match."),
}); });