diff --git a/Backend/bin/pb_hooks/emails/signup.html b/Backend/bin/pb_hooks/emails/signup.html new file mode 100644 index 0000000..a4172be --- /dev/null +++ b/Backend/bin/pb_hooks/emails/signup.html @@ -0,0 +1,817 @@ + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ + + + + + +
+ +
+ + + + + + +
+ + + + + + +
+ +
+
+
+ +
+
+ +
+ + + + + + +
+ +
+ + + + + + +
+
+ You're Going To Love What Happens Next +
+
+
+ +
+
+ +
+ + + + + + +
+ +
+ + + + + + + + + + + + + + + +
+
+ {{.firstName}} your next launch is closer than you + think - FastPocket will make it closer. +
+
+
+ We're really excited to help you develop apps + quickly. Check out the + tools + we are using to help you build at 10x. When you are + ready to start producing apps at max capacity click + the button below. +
+
+ + + + +
+ Build Now +
+
+
+ Thanks,
The {{.company}} Team +
+
+
+ +
+
+ +
+ + + + + + +
+ +
+ + + + + + +
+ + + + + + +
+ + + + +
+ +
+
+ Web +
+ + + + + + +
+ + + + +
+ +
+
+ Github +
+ + + + + + +
+ + + + +
+ +
+
+ Youtube +
+ + + + + + +
+ + + + +
+ +
+
+ X +
+ +
+
+ +
+
+ +
+ + diff --git a/Backend/bin/pb_hooks/emails/signup.mjml b/Backend/bin/pb_hooks/emails/signup.mjml new file mode 100644 index 0000000..c870b0d --- /dev/null +++ b/Backend/bin/pb_hooks/emails/signup.mjml @@ -0,0 +1,132 @@ + + + + + + + + + + + + + + You're Going To Love What Happens Next + + + + + {{.firstName}} your next launch is closer than you think - FastPocket + will make it closer. + We're really excited to help you develop apps quickly. Check out + the + tools + we are using to help you build at 10x. When you are ready to start + producing apps at max capacity click the button below. + Build Now + Thanks,
+ The {{.company}} Team
+
+
+ + + + + Web + + + Github + + + Youtube + + + X + + + + +
+
diff --git a/Backend/bin/pb_hooks/main.pb.js b/Backend/bin/pb_hooks/main.pb.js index be44d3c..9b8bc48 100644 --- a/Backend/bin/pb_hooks/main.pb.js +++ b/Backend/bin/pb_hooks/main.pb.js @@ -1,45 +1,25 @@ onRecordAfterCreateRequest((e) => { - const message = new MailerMessage({ - from: { - address: $app.settings().meta.senderAddress, - name: $app.settings().meta.senderName, - }, - to: [{address: e.record.email()}], - subject: "Are you ready to launch 10x faster?", - html: ` -
You're Going To Love What Happens Next
${e.record.get("firstName")} your next launch is closer than you think.

FastPocket will 10x your development process
We're really excited to help you develop apps quickly. Check out the tools we are using to help you build at 10x. When you are ready to start producing apps at max capacity click the button below.
Build Now!
Thanks,
The FastPocket Team
- - `, - // bcc, cc and custom headers are also supported... - }) + const message = new MailerMessage({ + from: { + address: $app.settings().meta.senderAddress, + name: $app.settings().meta.senderName, + }, + to: [{ address: e.record.email() }], + subject: "Are you ready to launch 10x faster?", + html: $template + .loadFiles(`${__hooks}/emails/signup.html`) + .render({ + firstName: e.record.get("firstName"), + company: $app.settings().meta.appName, + }), + // bcc, cc and custom headers are also supported... + }); - $app.newMailClient().send(message) -}, "user") + $app.newMailClient().send(message); +}, "user"); routerAdd("GET", "/hello/:name", (c) => { - let name = c.pathParam("name") + let name = c.pathParam("name"); - return c.json(200, { "message": "Hello " + name }) -}) \ No newline at end of file + return c.json(200, { message: "Hello " + name }); +}); diff --git a/Frontend/app/favicon.ico b/Frontend/app/favicon.ico index 83c631f..80d7e9f 100644 Binary files a/Frontend/app/favicon.ico and b/Frontend/app/favicon.ico differ diff --git a/Frontend/components/Header.tsx b/Frontend/components/Header.tsx index a2745f2..a2fe9c7 100644 --- a/Frontend/components/Header.tsx +++ b/Frontend/components/Header.tsx @@ -11,6 +11,7 @@ import pb from "@/lib/pocketbase"; import { useTheme } from "next-themes"; import Link from "next/link"; import Icon from "@/components/Icons/Icon"; +import ModalPasswordReset from "./Modals/ModalPasswordReset"; interface HeaderProps { isUserLoggedIn: boolean; @@ -148,6 +149,7 @@ export default function Header({ isUserLoggedIn }: HeaderProps) { + ); diff --git a/Frontend/components/Modals/ModalEmailChange.tsx b/Frontend/components/Modals/ModalEmailChange.tsx new file mode 100644 index 0000000..f475b2f --- /dev/null +++ b/Frontend/components/Modals/ModalEmailChange.tsx @@ -0,0 +1,124 @@ +import React from "react"; +import Icon from "@/components/Icons/Icon"; +import { useForm } from "react-hook-form"; +import { yupResolver } from "@hookform/resolvers/yup"; +import { signInValidationSchema } from "@/utils/form"; +import { login } from "@/app/actions"; +import { toast } from "react-toastify"; +import pb from "@/lib/pocketbase"; + +function ModalPasswordReset() { + const { + register, + handleSubmit, + reset, + formState: { errors, isSubmitting }, + } = useForm({ + resolver: yupResolver(signInValidationSchema), + }); + + const onSubmit = async (data: any) => { + try { + //login user + if ( + (await login({ email: data.email, password: data.password })).success + ) { + reset(); + document.getElementById("sign-in-modal")?.click(); + } + } catch (error) { + if (error instanceof Error) { + toast.error(error.message, { + position: "bottom-left", + autoClose: 5000, + hideProgressBar: false, + closeOnClick: true, + pauseOnHover: true, + draggable: true, + progress: undefined, + theme: "colored", + }); + } + } + }; + return ( + <> + { + reset(); + }} + /> + + + ); +} + +export default ModalPasswordReset; diff --git a/Frontend/components/Modals/ModalPasswordReset.tsx b/Frontend/components/Modals/ModalPasswordReset.tsx new file mode 100644 index 0000000..a2a5167 --- /dev/null +++ b/Frontend/components/Modals/ModalPasswordReset.tsx @@ -0,0 +1,103 @@ +import React, { useRef } from "react"; +import Icon from "@/components/Icons/Icon"; +import { useForm } from "react-hook-form"; +import { yupResolver } from "@hookform/resolvers/yup"; +import { signInValidationSchema } from "@/utils/form"; +import { toast } from "react-toastify"; +import pb from "@/lib/pocketbase"; + +function ModalPasswordReset() { + const { + register, + handleSubmit, + reset, + formState: { errors, isSubmitting }, + } = useForm({ + resolver: yupResolver(signInValidationSchema), + }); + + const onSubmit = async (data: any) => { + console.log(data); + try { + //login user + if (await pb.collection("user").requestPasswordReset(data.email)) { + reset(); + document.getElementById("password-reset-modal")?.click(); + document.getElementById("sign-in-modal")?.click(); + } + } catch (error) { + if (error instanceof Error) { + toast.error(error.message, { + position: "bottom-left", + autoClose: 5000, + hideProgressBar: false, + closeOnClick: true, + pauseOnHover: true, + draggable: true, + progress: undefined, + theme: "colored", + }); + } + } + }; + return ( + <> + { + reset(); + }} + /> + + + ); +} + +export default ModalPasswordReset; diff --git a/Frontend/components/Modals/ModalSignIn.tsx b/Frontend/components/Modals/ModalSignIn.tsx index 903d577..bf3b47a 100644 --- a/Frontend/components/Modals/ModalSignIn.tsx +++ b/Frontend/components/Modals/ModalSignIn.tsx @@ -1,19 +1,18 @@ import React from "react"; import Icon from "@/components/Icons/Icon"; -import { useTheme } from "next-themes"; -import colors from "@/utils/colors"; import { useForm } from "react-hook-form"; import { yupResolver } from "@hookform/resolvers/yup"; import { signInValidationSchema } from "@/utils/form"; import { login } from "@/app/actions"; import { toast } from "react-toastify"; +import pb from "@/lib/pocketbase"; function ModalSignIn() { const { register, handleSubmit, reset, - formState: { errors }, + formState: { errors, isSubmitting }, } = useForm({ resolver: yupResolver(signInValidationSchema), }); @@ -63,47 +62,57 @@ function ModalSignIn() {
-
+

Welcome back!

Lets kick some more ass?

-
+
{errors.email?.message} 
-
+
{errors.password?.message} 
- +
+ + +
diff --git a/Frontend/components/Modals/ModalSignUp.tsx b/Frontend/components/Modals/ModalSignUp.tsx index bc6002d..7c99255 100644 --- a/Frontend/components/Modals/ModalSignUp.tsx +++ b/Frontend/components/Modals/ModalSignUp.tsx @@ -21,7 +21,7 @@ function ModalSignUp({ register, handleSubmit, reset, - formState: { errors }, + formState: { errors, isSubmitting }, } = useForm({ resolver: yupResolver(signUpValidationSchema), }); @@ -55,6 +55,7 @@ function ModalSignUp({ lastSeen: new Date(), role: "Admin", displayName: `${data.firstName} ${data.lastName}`, + passwordConfirm: data.password, ...data, }; try { @@ -82,16 +83,21 @@ function ModalSignUp({ } } catch (error) { if (error instanceof Error) { - toast.error(error.message, { - position: "bottom-left", - autoClose: 5000, - hideProgressBar: false, - closeOnClick: true, - pauseOnHover: true, - draggable: true, - progress: undefined, - theme: "colored", - }); + toast.error( + Object.values((error as any).data.data) + .map((x: any) => x.message) + .join(), + { + position: "bottom-left", + autoClose: 5000, + hideProgressBar: false, + closeOnClick: true, + pauseOnHover: true, + draggable: true, + progress: undefined, + theme: "colored", + } + ); } } }; @@ -120,10 +126,7 @@ function ModalSignUp({
-
+

We Are Growing Fast, and We Want You To Join The Party!

@@ -131,14 +134,10 @@ function ModalSignUp({ Excited to see what we've got! Signup and get started!

-
+
-
+
-
+
-
+
-
+
-
+
-
- -
- {errors.passwordConfirm?.message}  -
-
-
diff --git a/Frontend/components/Navigation.tsx b/Frontend/components/Navigation.tsx index 11d3365..8363551 100644 --- a/Frontend/components/Navigation.tsx +++ b/Frontend/components/Navigation.tsx @@ -37,7 +37,9 @@ function Navigation({ isUserLoggedIn }: { isUserLoggedIn: boolean }) { {/* Site branding */}
{/* Logo */} - + + +
{/* Navbar menu content here */}
  • @@ -79,7 +81,9 @@ function Navigation({ isUserLoggedIn }: { isUserLoggedIn: boolean }) { {/* Sidebar content here */}
    {/* Logo */} - + + +
  • Get Your FastPocket diff --git a/Frontend/sections/AccountContent.tsx b/Frontend/sections/AccountContent.tsx index e5b571c..29877ba 100644 --- a/Frontend/sections/AccountContent.tsx +++ b/Frontend/sections/AccountContent.tsx @@ -10,6 +10,7 @@ import { useState, useEffect } from "react"; import { toast } from "react-toastify"; import { useRouter } from "next/navigation"; import { useQRCode } from "next-qrcode"; +import pb from "@/lib/pocketbase"; interface ManageSubscriptionProps { user: User; @@ -107,7 +108,7 @@ function AccountContent({ user }: ManageSubscriptionProps) {
  • - @@ -147,7 +148,7 @@ function AccountContent({ user }: ManageSubscriptionProps) {

    @@ -157,19 +158,35 @@ function AccountContent({ user }: ManageSubscriptionProps) {

    {"You haven’t upgraded your workflow yet"}

    -
    +
    + +
    )} diff --git a/Frontend/sections/Hero/WaitingListWithImageHero.tsx b/Frontend/sections/Hero/WaitingListWithImageHero.tsx index 95a8cf8..aa2d852 100644 --- a/Frontend/sections/Hero/WaitingListWithImageHero.tsx +++ b/Frontend/sections/Hero/WaitingListWithImageHero.tsx @@ -16,7 +16,7 @@ const WaitingListWithImageHero = () => { const { register, handleSubmit, - formState: { errors }, + formState: { errors, isSubmitting }, } = useForm({ resolver: yupResolver(waitinglistValidationSchema), }); @@ -177,22 +177,27 @@ const WaitingListWithImageHero = () => {
    diff --git a/Frontend/sections/PageHeader.tsx b/Frontend/sections/PageHeader.tsx index 669a167..799ee3b 100644 --- a/Frontend/sections/PageHeader.tsx +++ b/Frontend/sections/PageHeader.tsx @@ -8,7 +8,7 @@ interface PageHeaderProps { function PageHeader({ title, subtitle, className }: PageHeaderProps) { return (
    -

    +

    {title}

    {subtitle} diff --git a/Frontend/utils/form.ts b/Frontend/utils/form.ts index a7cc036..ae3b97b 100644 --- a/Frontend/utils/form.ts +++ b/Frontend/utils/form.ts @@ -50,10 +50,6 @@ const signUpValidationSchema = Yup.object().shape({ .password() .required("Password is required.") .min(8, "Password is too short - should be 8 characters minimum.") - .minUppercase(1, "password must contain at least 1 upper case letter"), - passwordConfirm: Yup.string() - .required("Please retype your password.") - .oneOf([Yup.ref("password")], "Your passwords do not match."), }); const waitinglistValidationSchema = Yup.object().shape({ firstName: Yup.string().required("First Name is required"), diff --git a/version.txt b/version similarity index 100% rename from version.txt rename to version