feature - fixed modal

This commit is contained in:
James Wyndham 2024-03-12 07:16:07 +08:00
parent 6158fbc045
commit 7fa3a2034a
15 changed files with 1303 additions and 128 deletions

View File

@ -0,0 +1,817 @@
<!DOCTYPE html>
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:v="urn:schemas-microsoft-com:vml"
xmlns:o="urn:schemas-microsoft-com:office:office"
>
<head>
<title></title>
<!--[if !mso]><!-->
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<!--<![endif]-->
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<style type="text/css">
#outlook a {
padding: 0;
}
body {
margin: 0;
padding: 0;
-webkit-text-size-adjust: 100%;
-ms-text-size-adjust: 100%;
}
table,
td {
border-collapse: collapse;
mso-table-lspace: 0pt;
mso-table-rspace: 0pt;
}
img {
border: 0;
height: auto;
line-height: 100%;
outline: none;
text-decoration: none;
-ms-interpolation-mode: bicubic;
}
p {
display: block;
margin: 13px 0;
}
</style>
<!--[if mso]>
<noscript>
<xml>
<o:OfficeDocumentSettings>
<o:AllowPNG />
<o:PixelsPerInch>96</o:PixelsPerInch>
</o:OfficeDocumentSettings>
</xml>
</noscript>
<![endif]-->
<!--[if lte mso 11]>
<style type="text/css">
.mj-outlook-group-fix {
width: 100% !important;
}
</style>
<![endif]-->
<!--[if !mso]><!-->
<link
href="https://fonts.googleapis.com/css?family=Ubuntu:300,400,500,700"
rel="stylesheet"
type="text/css"
/>
<link
href="https://fonts.googleapis.com/css?family=Arimo:ital,wght@0,400..700;1,400..700"
rel="stylesheet"
type="text/css"
/>
<style type="text/css">
@import url(https://fonts.googleapis.com/css?family=Ubuntu:300,400,500,700);
@import url(https://fonts.googleapis.com/css?family=Arimo:ital,wght@0,400..700;1,400..700);
</style>
<!--<![endif]-->
<style type="text/css">
@media only screen and (min-width: 480px) {
.mj-column-per-100 {
width: 100% !important;
max-width: 100%;
}
}
</style>
<style media="screen and (min-width:480px)">
.moz-text-html .mj-column-per-100 {
width: 100% !important;
max-width: 100%;
}
</style>
<style type="text/css">
@media only screen and (max-width: 480px) {
table.mj-full-width-mobile {
width: 100% !important;
}
td.mj-full-width-mobile {
width: auto !important;
}
}
</style>
</head>
<body style="word-spacing: normal; background-color: #ffffff">
<div style="background-color: #ffffff">
<!--[if mso | IE]><table align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:600px;" width="600" bgcolor="#ffffff" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]-->
<div
style="
background: #ffffff;
background-color: #ffffff;
margin: 0px auto;
max-width: 600px;
"
>
<table
align="center"
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="background: #ffffff; background-color: #ffffff; width: 100%"
>
<tbody>
<tr>
<td
style="
direction: ltr;
font-size: 0px;
padding: 20px 0;
padding-bottom: 0px;
padding-top: 0;
text-align: center;
"
>
<!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]-->
<div
class="mj-column-per-100 mj-outlook-group-fix"
style="
font-size: 0px;
text-align: left;
direction: ltr;
display: inline-block;
vertical-align: top;
width: 100%;
"
>
<table
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="vertical-align: top"
width="100%"
>
<tbody>
<tr>
<td
align="left"
style="
font-size: 0px;
padding: 10px 25px;
padding-top: 8px;
padding-right: 0px;
padding-bottom: 8px;
padding-left: 0px;
word-break: break-word;
"
>
<table
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="
border-collapse: collapse;
border-spacing: 0px;
"
>
<tbody>
<tr>
<td style="width: 180px">
<img
alt=""
height="auto"
src="http://fastpocket.dev/images/combination-icon.png"
style="
border: none;
display: block;
outline: none;
text-decoration: none;
height: auto;
width: 100%;
font-size: 13px;
"
width="180"
/>
</td>
</tr>
</tbody>
</table>
</td>
</tr>
</tbody>
</table>
</div>
<!--[if mso | IE]></td></tr></table><![endif]-->
</td>
</tr>
</tbody>
</table>
</div>
<!--[if mso | IE]></td></tr></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:600px;" width="600" bgcolor="#FD5469" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]-->
<div
style="
background: #fd5469;
background-color: #fd5469;
margin: 0px auto;
max-width: 600px;
"
>
<table
align="center"
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="background: #fd5469; background-color: #fd5469; width: 100%"
>
<tbody>
<tr>
<td
style="
direction: ltr;
font-size: 0px;
padding: 20px 0;
padding-bottom: 0px;
padding-top: 0;
text-align: center;
"
>
<!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]-->
<div
class="mj-column-per-100 mj-outlook-group-fix"
style="
font-size: 0px;
text-align: left;
direction: ltr;
display: inline-block;
vertical-align: top;
width: 100%;
"
>
<table
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="vertical-align: top"
width="100%"
>
<tbody>
<tr>
<td
align="left"
style="
font-size: 0px;
padding: 10px 25px;
padding-top: 50px;
padding-right: 25px;
padding-bottom: 30px;
padding-left: 25px;
word-break: break-word;
"
>
<div
style="
font-family: Arimo, Arial, sans-serif;
font-size: 45px;
font-weight: 900;
line-height: 1;
text-align: left;
color: #ffffff;
"
>
You're Going To Love What Happens Next
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!--[if mso | IE]></td></tr></table><![endif]-->
</td>
</tr>
</tbody>
</table>
</div>
<!--[if mso | IE]></td></tr></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:600px;" width="600" bgcolor="#FFFFFF" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]-->
<div
style="
background: #ffffff;
background-color: #ffffff;
margin: 0px auto;
max-width: 600px;
"
>
<table
align="center"
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="background: #ffffff; background-color: #ffffff; width: 100%"
>
<tbody>
<tr>
<td
style="
direction: ltr;
font-size: 0px;
padding: 20px 0;
padding-bottom: 20px;
padding-top: 20px;
text-align: center;
"
>
<!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:middle;width:600px;" ><![endif]-->
<div
class="mj-column-per-100 mj-outlook-group-fix"
style="
font-size: 0px;
text-align: left;
direction: ltr;
display: inline-block;
vertical-align: middle;
width: 100%;
"
>
<table
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="vertical-align: middle"
width="100%"
>
<tbody>
<tr>
<td
align="left"
style="
font-size: 0px;
padding: 10px 25px;
padding-top: 16px;
padding-right: 25px;
padding-left: 25px;
word-break: break-word;
"
>
<div
style="
font-family: Arimo, Arial, sans-serif;
font-size: 24px;
line-height: 1;
text-align: left;
color: #fd5469;
"
>
{{.firstName}} your next launch is closer than you
think - FastPocket will make it closer.
</div>
</td>
</tr>
<tr>
<td
align="left"
style="
font-size: 0px;
padding: 10px 25px;
padding-top: 16px;
padding-right: 25px;
padding-left: 25px;
word-break: break-word;
"
>
<div
style="
font-family: Arimo, Arial, sans-serif;
font-size: 18px;
line-height: 1;
text-align: left;
color: #29171c;
"
>
We&apos;re really excited to help you develop apps
quickly. Check out the
<a
style="color: #7082ff"
href="https://fastpocket.dev/pricing"
>tools</a
>
we are using to help you build at 10x. When you are
ready to start producing apps at max capacity click
the button below.
</div>
</td>
</tr>
<tr>
<td
align="center"
vertical-align="middle"
style="
font-size: 0px;
padding: 10px 25px;
padding-top: 48px;
padding-bottom: 48px;
word-break: break-word;
"
>
<table
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="border-collapse: separate; line-height: 100%"
>
<tr>
<td
align="center"
bgcolor="#FD5469"
role="presentation"
style="
border: none;
border-radius: 10px;
cursor: auto;
mso-padding-alt: 10px 25px;
background: #fd5469;
"
valign="middle"
>
<a
href="https://fastpocket.dev/pricing"
style="
display: inline-block;
background: #fd5469;
color: #ffffff;
font-family: Arimo, Arial, sans-serif;
font-size: 22px;
font-weight: 900;
line-height: 120%;
margin: 0;
text-decoration: none;
text-transform: none;
padding: 10px 25px;
mso-padding-alt: 0px;
border-radius: 10px;
"
target="_blank"
>Build Now</a
>
</td>
</tr>
</table>
</td>
</tr>
<tr>
<td
align="center"
style="
font-size: 0px;
padding: 10px 25px;
padding-right: 25px;
padding-left: 25px;
word-break: break-word;
"
>
<div
style="
font-family: Arimo, Arial, sans-serif;
font-size: 15px;
line-height: 1;
text-align: center;
color: #fd5469;
"
>
Thanks,<br />The {{.company}} Team
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!--[if mso | IE]></td></tr></table><![endif]-->
</td>
</tr>
</tbody>
</table>
</div>
<!--[if mso | IE]></td></tr></table><table align="center" border="0" cellpadding="0" cellspacing="0" class="" style="width:600px;" width="600" ><tr><td style="line-height:0px;font-size:0px;mso-line-height-rule:exactly;"><![endif]-->
<div style="margin: 0px auto; max-width: 600px">
<table
align="center"
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="width: 100%"
>
<tbody>
<tr>
<td
style="
direction: ltr;
font-size: 0px;
padding: 20px 0;
text-align: center;
"
>
<!--[if mso | IE]><table role="presentation" border="0" cellpadding="0" cellspacing="0"><tr><td class="" style="vertical-align:top;width:600px;" ><![endif]-->
<div
class="mj-column-per-100 mj-outlook-group-fix"
style="
font-size: 0px;
text-align: left;
direction: ltr;
display: inline-block;
vertical-align: top;
width: 100%;
"
>
<table
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="vertical-align: top"
width="100%"
>
<tbody>
<tr>
<td
align="center"
style="
font-size: 0px;
padding: 10px 25px;
word-break: break-word;
"
>
<!--[if mso | IE]><table align="center" border="0" cellpadding="0" cellspacing="0" role="presentation" ><tr><td><![endif]-->
<table
align="center"
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="float: none; display: inline-table"
>
<tr>
<td style="padding: 4px; vertical-align: middle">
<table
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="
background: #4bade9;
border-radius: 3px;
width: 20px;
"
>
<tr>
<td
style="
font-size: 0;
height: 20px;
vertical-align: middle;
width: 20px;
"
>
<a
href="https://fastpocket.dev/"
target="_blank"
><img
height="20"
src="https://www.mailjet.com/images/theme/v1/icons/ico-social/web.png"
style="
border-radius: 3px;
display: block;
"
width="20"
/></a>
</td>
</tr>
</table>
</td>
<td style="vertical-align: middle">
<a
href="https://fastpocket.dev/"
style="
color: #333333;
font-size: 15px;
font-family: Ubuntu, Helvetica, Arial,
sans-serif;
line-height: 22px;
text-decoration: none;
"
target="_blank"
>Web</a
>
</td>
</tr>
</table>
<!--[if mso | IE]></td><td><![endif]-->
<table
align="center"
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="float: none; display: inline-table"
>
<tr>
<td style="padding: 4px; vertical-align: middle">
<table
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="
background: #000000;
border-radius: 3px;
width: 20px;
"
>
<tr>
<td
style="
font-size: 0;
height: 20px;
vertical-align: middle;
width: 20px;
"
>
<a
href="https://github.com/mrwyndham/pocketbase-stripe"
target="_blank"
><img
height="20"
src="https://www.mailjet.com/images/theme/v1/icons/ico-social/github.png"
style="
border-radius: 3px;
display: block;
"
width="20"
/></a>
</td>
</tr>
</table>
</td>
<td style="vertical-align: middle">
<a
href="https://github.com/mrwyndham/pocketbase-stripe"
style="
color: #333333;
font-size: 15px;
font-family: Ubuntu, Helvetica, Arial,
sans-serif;
line-height: 22px;
text-decoration: none;
"
target="_blank"
>Github</a
>
</td>
</tr>
</table>
<!--[if mso | IE]></td><td><![endif]-->
<table
align="center"
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="float: none; display: inline-table"
>
<tr>
<td style="padding: 4px; vertical-align: middle">
<table
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="
background: #eb3323;
border-radius: 3px;
width: 20px;
"
>
<tr>
<td
style="
font-size: 0;
height: 20px;
vertical-align: middle;
width: 20px;
"
>
<a
href="https://www.youtube.com/@FastPocket"
target="_blank"
><img
height="20"
src="https://www.mailjet.com/images/theme/v1/icons/ico-social/youtube.png"
style="
border-radius: 3px;
display: block;
"
width="20"
/></a>
</td>
</tr>
</table>
</td>
<td style="vertical-align: middle">
<a
href="https://www.youtube.com/@FastPocket"
style="
color: #333333;
font-size: 15px;
font-family: Ubuntu, Helvetica, Arial,
sans-serif;
line-height: 22px;
text-decoration: none;
"
target="_blank"
>Youtube</a
>
</td>
</tr>
</table>
<!--[if mso | IE]></td><td><![endif]-->
<table
align="center"
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="float: none; display: inline-table"
>
<tr>
<td style="padding: 4px; vertical-align: middle">
<table
border="0"
cellpadding="0"
cellspacing="0"
role="presentation"
style="
background: #55acee;
border-radius: 3px;
width: 20px;
"
>
<tr>
<td
style="
font-size: 0;
height: 20px;
vertical-align: middle;
width: 20px;
"
>
<a
href="https://twitter.com/intent/tweet?url=https://twitter.com/meinbiz"
target="_blank"
><img
height="20"
src="https://www.mailjet.com/images/theme/v1/icons/ico-social/twitter.png"
style="
border-radius: 3px;
display: block;
"
width="20"
/></a>
</td>
</tr>
</table>
</td>
<td style="vertical-align: middle">
<a
href="https://twitter.com/intent/tweet?url=https://twitter.com/meinbiz"
style="
color: #333333;
font-size: 15px;
font-family: Ubuntu, Helvetica, Arial,
sans-serif;
line-height: 22px;
text-decoration: none;
"
target="_blank"
>X</a
>
</td>
</tr>
</table>
<!--[if mso | IE]></td></tr></table><![endif]-->
</td>
</tr>
</tbody>
</table>
</div>
<!--[if mso | IE]></td></tr></table><![endif]-->
</td>
</tr>
</tbody>
</table>
</div>
<!--[if mso | IE]></td></tr></table><![endif]-->
</div>
</body>
</html>

View File

@ -0,0 +1,132 @@
<mjml>
<mj-head>
<mj-font
name="Raleway"
href="https://fonts.googleapis.com/css?family=Raleway:ital,wght@0,100..900;1,100..900&display=swap"
/>
<mj-font
name="Arimo"
href="https://fonts.googleapis.com/css?family=Arimo:ital,wght@0,400..700;1,400..700"
/>
</mj-head>
<mj-body background-color="#ffffff" font-size="13px">
<mj-section background-color="#ffffff" padding-bottom="0px" padding-top="0">
<mj-column vertical-align="top" width="100%">
<mj-image
src="http://fastpocket.dev/images/combination-icon.png"
alt=""
align="left"
border="none"
width="180px"
padding-left="0px"
padding-right="0px"
padding-bottom="8px"
padding-top="8px"
></mj-image>
</mj-column>
</mj-section>
<mj-section
background-color="#FD5469"
vertical-align="top"
padding-bottom="0px"
padding-top="0"
>
<mj-column vertical-align="top" width="100%">
<mj-text
align="left"
color="#ffffff"
font-size="45px"
font-weight="900"
font-family="Arimo, Arial, sans-serif"
padding-left="25px"
padding-right="25px"
padding-bottom="30px"
padding-top="50px"
>You're Going To Love What Happens Next</mj-text
>
</mj-column>
</mj-section>
<mj-section
background-color="#FFF"
padding-bottom="20px"
padding-top="20px"
>
<mj-column vertical-align="middle" width="100%">
<mj-text
align="left"
color="#FD5469"
font-size="24px"
font-family="Arimo, Arial, sans-serif"
padding-top="16px"
padding-left="25px"
padding-right="25px"
>{{.firstName}} your next launch is closer than you think - FastPocket
will make it closer.</mj-text
>
<mj-text
align="left"
color="#29171C"
font-size="18px"
font-family="Arimo, Arial, sans-serif"
padding-left="25px"
padding-top="16px"
padding-right="25px"
>We&apos;re really excited to help you develop apps quickly. Check out
the
<a style="color: #7082ff" href="https://fastpocket.dev/pricing"
>tools</a
>
we are using to help you build at 10x. When you are ready to start
producing apps at max capacity click the button below.</mj-text
>
<mj-button
align="center"
font-size="22px"
font-weight="900"
background-color="#FD5469"
border-radius="10px"
color="#fff"
font-family="Arimo, Arial, sans-serif"
padding-top="48px"
padding-bottom="48px"
href="https://fastpocket.dev/pricing"
>Build Now</mj-button
>
<mj-text
align="center"
color="#FD5469"
font-size="15px"
font-family="Arimo, Arial, sans-serif"
padding-left="25px"
padding-right="25px"
>Thanks, <br />
The {{.company}} Team</mj-text
>
</mj-column>
</mj-section>
<mj-section>
<mj-column>
<mj-social font-size="15px" icon-size="20px" mode="horizontal">
<mj-social-element name="web" href="https://fastpocket.dev/">
Web
</mj-social-element>
<mj-social-element
name="github"
href="https://github.com/mrwyndham/pocketbase-stripe"
>
Github
</mj-social-element>
<mj-social-element
name="youtube"
href="https://www.youtube.com/@FastPocket"
>
Youtube
</mj-social-element>
<mj-social-element name="twitter" href="https://twitter.com/meinbiz">
X
</mj-social-element>
</mj-social>
</mj-column>
</mj-section>
</mj-body>
</mjml>

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -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) {
</div>
</div>
<ModalSignIn />
<ModalPasswordReset />
<ModalSignUp setUser={setStatefulUser} />
</header>
);

View File

@ -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 (
<>
<input
type="checkbox"
id="sign-in-modal"
className="modal-toggle"
onClick={() => {
reset();
}}
/>
<label htmlFor="sign-in-modal" className="modal cursor-pointer">
<label className="modal-box relative bg-base-100 max-w-full md:max-w-[550px] py-4 px-3 md:p-6">
<div className="flex justify-end pb-2 select-none">
<label
htmlFor="sign-in-modal"
className="cursor-pointer text-base-content"
>
<Icon name="Dismiss20Filled" size="medium" />
</label>
</div>
<div>
<div className="w-[100%] bg-gradient-to-r from-primary to-secondary px-6 pt-2 mt-3 pb-6 rounded-lg text-primary-content">
<h3 className="pb-1 text-3xl font-bold md:text-3xl pt-6">
Welcome back!
</h3>
<p className="text-sm md:text-base">Lets kick some more ass?</p>
</div>
<form onSubmit={handleSubmit(onSubmit)} className="w-full">
<div className="relative mt-6">
<input
type="text"
className="py-3 px-4 block w-full bg-base-200 text-base-content border-primary/40 rounded-lg text-sm focus:border-secondary focus:ring-secondary disabled:opacity-50 disabled:pointer-events-none "
placeholder="Your email…"
aria-label="Your email…"
autoComplete="on"
{...register("email")}
/>
<div className="text-start text-sm italic text-error-content">
{errors.email?.message}&nbsp;
</div>
</div>
<div className="relative mt-1 mb-2 ">
<input
type="password"
className="py-3 px-4 block w-full bg-base-200 text-base-content border-primary/40 rounded-lg text-sm focus:border-secondary focus:ring-secondary disabled:opacity-50 disabled:pointer-events-none "
placeholder="Your password..."
aria-label="Your password..."
{...register("password")}
/>
<div className="text-start text-sm italic text-error-content">
{errors.password?.message}&nbsp;
</div>
</div>
<div className="flex flex-row w-full justify-between">
<button
disabled={isSubmitting}
type="submit"
className="btn btn-primary"
>
Sign In
{isSubmitting && <div className="loading"></div>}
</button>
<button
onClick={() =>
pb.collection("user").requestPasswordReset(user.email)
}
className="btn btn-secondary text-primary-content capitalize border-none"
>
Reset Password
</button>
</div>
</form>
</div>
</label>
</label>
</>
);
}
export default ModalPasswordReset;

View File

@ -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 (
<>
<input
type="checkbox"
id="password-reset-modal"
className="modal-toggle"
onClick={() => {
reset();
}}
/>
<label htmlFor="password-reset-modal" className="modal cursor-pointer">
<label className="modal-box relative bg-base-100 max-w-full md:max-w-[450px] py-4 px-3 md:p-6">
<div className="flex justify-end pb-2 select-none">
<label
htmlFor="password-reset-modal"
className="cursor-pointer text-base-content"
>
<Icon name="Dismiss20Filled" size="medium" />
</label>
</div>
<div>
<div className="w-[100%] bg-gradient-to-r from-primary to-secondary px-6 pt-2 mt-3 pb-6 rounded-lg text-primary-content">
<h3 className="pb-1 text-3xl font-bold md:text-3xl pt-6">
Reset Your Password
</h3>
<p className="text-sm md:text-base">Enter in your email</p>
</div>
<form onSubmit={handleSubmit(onSubmit)} className="w-full">
<div className="relative mt-6">
<input
type="text"
className="py-3 px-4 block w-full bg-base-200 text-base-content border-primary/40 rounded-lg text-sm focus:border-secondary focus:ring-secondary disabled:opacity-50 disabled:pointer-events-none "
placeholder="Your email…"
aria-label="Your email…"
autoComplete="on"
{...register("email")}
/>
<div className="text-start text-sm italic text-error-content">
{errors.email?.message}&nbsp;
</div>
</div>
<div className="flex flex-row w-full justify-between">
<button
disabled={isSubmitting}
type="submit"
className="btn btn-primary"
>
Reset Password
{isSubmitting && <div className="loading"></div>}
</button>
</div>
</form>
</div>
</label>
</label>
</>
);
}
export default ModalPasswordReset;

View File

@ -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() {
</label>
</div>
<div>
<div
className="w-[100%] bg-gradient-to-r from-primary to-secondary px-6 pt-2 mt-3 pb-6 rounded-lg text-primary-content"
data-aos="fade-up"
>
<div className="w-[100%] bg-gradient-to-r from-primary to-secondary px-6 pt-2 mt-3 pb-6 rounded-lg text-primary-content">
<h3 className="pb-1 text-3xl font-bold md:text-3xl pt-6">
Welcome back!
</h3>
<p className="text-sm md:text-base">Lets kick some more ass?</p>
</div>
<form onSubmit={handleSubmit(onSubmit)} className="w-full md:w-2/3">
<form onSubmit={handleSubmit(onSubmit)} className="w-full">
<div className="relative mt-6">
<input
{...register("email")}
id="SignInEmail"
type="text"
className="py-3 px-4 block w-full bg-base-200 text-base-content border-primary/40 rounded-lg text-sm focus:border-secondary focus:ring-secondary disabled:opacity-50 disabled:pointer-events-none "
placeholder="Your email…"
aria-label="Your email…"
autoComplete="on"
{...register("email")}
/>
<div className="text-start text-sm italic text-error-content">
{errors.email?.message}&nbsp;
</div>
</div>
<div className="relative mt-1 mb-2">
<div className="relative mt-1 mb-2 ">
<input
{...register("password")}
id="SignInPwd"
type="password"
className="py-3 px-4 block w-full bg-base-200 text-base-content border-primary/40 rounded-lg text-sm focus:border-secondary focus:ring-secondary disabled:opacity-50 disabled:pointer-events-none "
placeholder="Your password..."
aria-label="Your password..."
{...register("password")}
/>
<div className="text-start text-sm italic text-error-content">
{errors.password?.message}&nbsp;
</div>
</div>
<button type="submit" className="btn btn-primary">
Sign In
</button>
<div className="flex flex-row w-full justify-between">
<button
disabled={isSubmitting}
type="submit"
className="btn btn-primary"
>
Sign In
{isSubmitting && <div className="loading"></div>}
</button>
<button
onClick={() =>
document.getElementById("password-reset-modal")?.click()
}
className="btn btn-ghost text-primary capitalize border-none"
>
Reset Password
</button>
</div>
</form>
</div>
</label>

View File

@ -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({
</label>
</div>
<div className="flex flex-grow flex-col h-[30rem] lg:h-full overflow-y-scroll">
<div
className="w-[100%] bg-gradient-to-r from-primary to-secondary px-6 mt-3 pb-6 rounded-lg text-primary-content"
data-aos="fade-up"
>
<div className="w-[100%] bg-gradient-to-r from-primary to-secondary px-6 mt-3 pb-6 rounded-lg text-primary-content">
<h3 className="pb-1 text-3xl font-bold md:text-3xl pt-6">
We Are Growing Fast, and We Want You To Join The Party!
</h3>
@ -131,14 +134,10 @@ function ModalSignUp({
Excited to see what we&apos;ve got! Signup and get started!
</p>
</div>
<form
onSubmit={handleSubmit(onSubmit)}
className="w-full md:w-2/3 pl-1"
>
<form onSubmit={handleSubmit(onSubmit)} className="w-full pl-1">
<div className="relative mt-6">
<input
type="text"
id="SignUpEmail"
className="py-3 px-4 block w-full bg-base-200 text-base-content border-primary/40 rounded-lg text-sm focus:border-secondary focus:ring-secondary disabled:opacity-50 disabled:pointer-events-none "
placeholder="Email…"
aria-label="Email…"
@ -151,9 +150,8 @@ function ModalSignUp({
</div>
<div className="flex flex-row gap-4">
<div className="relative mt-1">
<div className="relative mt-1 flex-grow">
<input
id="SignUpFirstName"
type="text"
className="py-3 px-4 block w-full bg-base-200 text-base-content border-primary/40 rounded-lg text-sm focus:border-secondary focus:ring-secondary disabled:opacity-50 disabled:pointer-events-none "
placeholder="First Name…"
@ -165,9 +163,8 @@ function ModalSignUp({
{errors.firstName?.message}&nbsp;
</div>
</div>
<div className="relative mt-1">
<div className="relative mt-1 flex-grow">
<input
id="SignUpLastName"
type="text"
className="py-3 px-4 block w-full bg-base-200 text-base-content border-primary/40 rounded-lg text-sm focus:border-secondary focus:ring-secondary disabled:opacity-50 disabled:pointer-events-none "
placeholder="Last Name…"
@ -180,9 +177,8 @@ function ModalSignUp({
</div>
</div>
<div className="relative mt-1">
<div className="relative mt-1 flex-grow">
<input
id="SignUpPhoneNumber"
type="text"
className="py-3 px-4 block w-full bg-base-200 text-base-content border-primary/40 rounded-lg text-sm focus:border-secondary focus:ring-secondary disabled:opacity-50 disabled:pointer-events-none "
placeholder="Phone Number…"
@ -194,9 +190,8 @@ function ModalSignUp({
</div>
</div>
<div className="flex flex-row gap-4">
<div className="relative mt-1">
<div className="relative mt-1 flex-grow">
<input
id="SignUpOrganisation"
type="text"
className="py-3 px-4 block w-full bg-base-200 text-base-content border-primary/40 rounded-lg text-sm focus:border-secondary focus:ring-secondary disabled:opacity-50 disabled:pointer-events-none "
placeholder="Organisation…"
@ -207,9 +202,8 @@ function ModalSignUp({
{errors.organisation?.message}&nbsp;
</div>
</div>
<div className="relative mt-1">
<div className="relative mt-1 flex-grow">
<select
id="SignUpCompanySize"
defaultValue={""}
className="py-3 px-4 block w-full bg-base-200 text-base-content border-primary/40 rounded-lg text-sm focus:border-secondary focus:ring-secondary disabled:opacity-50 disabled:pointer-events-none "
{...register("organisationSize")}
@ -235,7 +229,7 @@ function ModalSignUp({
</div>
</div>
<div className="flex flex-row gap-4">
<div className="relative mt-1">
<div className="relative mt-1 flex-grow">
<input
id="SignUpPwd"
type="password"
@ -248,23 +242,15 @@ function ModalSignUp({
{errors.password?.message}&nbsp;
</div>
</div>
<div className="relative mt-1 mb-2">
<input
id="SignUpPwdConfirm"
type="password"
className="py-3 px-4 block w-full bg-base-200 text-base-content border-primary/40 rounded-lg text-sm focus:border-secondary focus:ring-secondary disabled:opacity-50 disabled:pointer-events-none "
placeholder="Confirm Password..."
aria-label="Confirmed Password"
{...register("passwordConfirm")}
/>
<div className="text-start text-sm italic text-error-content">
{errors.passwordConfirm?.message}&nbsp;
</div>
</div>
</div>
<button type="submit" className="btn btn-primary">
<button
disabled={isSubmitting}
type="submit"
className="btn btn-primary"
>
Sign Up
{isSubmitting && <div className="loading"></div>}
</button>
</form>
</div>

View File

@ -37,7 +37,9 @@ function Navigation({ isUserLoggedIn }: { isUserLoggedIn: boolean }) {
{/* Site branding */}
<div className="shrink-0 mr-4">
{/* Logo */}
<Logo href="/" className="group relative cursor-pointer" />
<Link href="/">
<Logo className="group relative cursor-pointer" />
</Link>
</div>
{/* Navbar menu content here */}
<li>
@ -79,7 +81,9 @@ function Navigation({ isUserLoggedIn }: { isUserLoggedIn: boolean }) {
{/* Sidebar content here */}
<div className="shrink-0 m-3">
{/* Logo */}
<Logo href="/" className="group relative cursor-pointer" />
<Link href="/">
<Logo className="group relative cursor-pointer" />
</Link>
</div>
<li>
<Link href="/pricing">Get Your FastPocket</Link>

View File

@ -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) {
</li>
</ol>
<a href={portalWebsite}>
<button className="btn text-base capitalize !rounded-md bg-base-content bg-bg-gray-925 hover:bg-gray-900 w-full sm:w-auto mt-8">
<button className="btn btn-sm text-base capitalize !rounded-md bg-base-content bg-bg-gray-925 hover:bg-gray-900 w-full sm:w-auto mt-8">
Management Portal
</button>
</a>
@ -147,7 +148,7 @@ function AccountContent({ user }: ManageSubscriptionProps) {
</p>
<button
onClick={manageSubscription}
className="btn text-base-content capitalize !rounded-md bg-secondary hover:bg-secondary/60 w-full sm:w-auto mt-8"
className="btn btn-sm text-base-content capitalize !rounded-md bg-secondary hover:bg-secondary/60 w-full sm:w-auto mt-8"
>
Manage Subscription
</button>
@ -157,19 +158,35 @@ function AccountContent({ user }: ManageSubscriptionProps) {
<p className="text-lg text-base-content mb-4">
{"You havent upgraded your workflow yet"}
</p>
<div className="flex flex-row gap-x-2">
<div className="flex flex-row gap-2 flex-wrap">
<button
onClick={() => router.push("/pricing")}
className="btn btn-neutral text-primary-content capitalize bg-gradient-to-r from-primary to-secondary border-none"
className="btn btn-sm btn-neutral text-primary-content capitalize bg-gradient-to-r from-primary to-secondary border-none"
>
Upgrade
</button>
<button
onClick={manageSubscription}
className="btn btn-neutral text-primary-content capitalize border-none"
className="btn btn-sm btn-secondary text-primary-content capitalize border-none"
>
Manage Purchases
</button>
<button
onClick={() =>
document.getElementById("reset-password-modal")?.click()
}
className="btn btn-sm btn-secondary md:ml-auto text-primary-content capitalize border-none"
>
Reset Password
</button>
<button
onClick={() =>
document.getElementById("change-email-modal")?.click()
}
className="btn btn-sm btn-secondary text-primary-content capitalize border-none"
>
Change Email
</button>
</div>
</>
)}

View File

@ -16,7 +16,7 @@ const WaitingListWithImageHero = () => {
const {
register,
handleSubmit,
formState: { errors },
formState: { errors, isSubmitting },
} = useForm({
resolver: yupResolver(waitinglistValidationSchema),
});
@ -177,22 +177,27 @@ const WaitingListWithImageHero = () => {
<button
className="btn btn-primary text-primary-content"
type="submit"
disabled={isSubmitting}
>
Join the waitlist
<svg
className="flex-shrink-0 size-4"
xmlns="http://www.w3.org/2000/svg"
width={24}
height={24}
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth={2}
strokeLinecap="round"
strokeLinejoin="round"
>
<path d="m9 18 6-6-6-6" />
</svg>
{isSubmitting ? (
<div className="loading"></div>
) : (
<svg
className="flex-shrink-0 size-4"
xmlns="http://www.w3.org/2000/svg"
width={24}
height={24}
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth={2}
strokeLinecap="round"
strokeLinejoin="round"
>
<path d="m9 18 6-6-6-6" />
</svg>
)}
</button>
</div>
</div>

View File

@ -8,7 +8,7 @@ interface PageHeaderProps {
function PageHeader({ title, subtitle, className }: PageHeaderProps) {
return (
<div className={` pt-48 max-w-screen flex flex-col ${className}`}>
<h1 className="text-4xl md:text-5xl text-center font-bold text-base-content mb-6 mx-auto">
<h1 className="text-4xl md:text-5xl text-center font-bold text-base-content mb-6 mx-auto px-4">
{title}
</h1>
{subtitle}

View File

@ -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"),