feature - signin from signup
This commit is contained in:
parent
91b69ce30f
commit
edbf656701
|
@ -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
|
||||||
|
|
|
@ -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>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -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've got! Signup and get started!
|
Excited to see what we'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}
|
{errors.passwordConfirm?.message}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -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"
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 (
|
||||||
<>
|
<>
|
||||||
|
|
|
@ -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}
|
{errors.firstName?.message}
|
||||||
</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}
|
{errors.lastName?.message}
|
||||||
</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}
|
{errors.email?.message}
|
||||||
</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>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -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}
|
||||||
/>
|
</div>
|
||||||
<div className="text-start text-sm italic text-error-content">
|
|
||||||
{errors.email?.message}
|
|
||||||
</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't regret it!
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
|
@ -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."),
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue