@@ -5,7 +5,8 @@ import Row from "react-bootstrap/Row";
|
|||||||
import Button from "../../pageElements/Button";
|
import Button from "../../pageElements/Button";
|
||||||
import { db, auth } from "../../firebase";
|
import { db, auth } from "../../firebase";
|
||||||
import { createUserWithEmailAndPassword } from "firebase/auth";
|
import { createUserWithEmailAndPassword } from "firebase/auth";
|
||||||
import { Link, useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import Toggle from "../../pageElements/Toggle";
|
||||||
import TextInput from "../../pageElements/TextInput";
|
import TextInput from "../../pageElements/TextInput";
|
||||||
import { v4 as uuidv4 } from "uuid";
|
import { v4 as uuidv4 } from "uuid";
|
||||||
import { collection, setDoc, doc } from "firebase/firestore";
|
import { collection, setDoc, doc } from "firebase/firestore";
|
||||||
@@ -24,6 +25,7 @@ import PaymentModal from "../Modals/PaymentModal";
|
|||||||
import Radio from "../../pageElements/Radio";
|
import Radio from "../../pageElements/Radio";
|
||||||
import "../../styles/signup.scss";
|
import "../../styles/signup.scss";
|
||||||
import Stripe from "stripe";
|
import Stripe from "stripe";
|
||||||
|
import { stripeApiKey } from "../../secrets";
|
||||||
|
|
||||||
const SignupPage = () => {
|
const SignupPage = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
@@ -35,20 +37,20 @@ const SignupPage = () => {
|
|||||||
getFormDataDefaults(paymentfields)
|
getFormDataDefaults(paymentfields)
|
||||||
);
|
);
|
||||||
const [showPaymentModal, setShowPaymentModal] = useState(false);
|
const [showPaymentModal, setShowPaymentModal] = useState(false);
|
||||||
const [showSelectPlan, setShowSelectPlan] = useState(true);
|
const [showSelectPlan, setShowSelectPlan] = useState(false);
|
||||||
const [activeRadioOption, setActiveRadioOption] = useState("monthlyBasic");
|
const [activeRadioOption, setActiveRadioOption] = useState("monthlyBasic");
|
||||||
const modalText = "Description of monthly and annual subscriptions";
|
|
||||||
const [selectedPlan, setSelectedPlan] = useState({});
|
const [selectedPlan, setSelectedPlan] = useState({});
|
||||||
// this could also go in App.js if needed in the future
|
const [isAnnualBilling, setIsAnnualBilling] = useState(false);
|
||||||
const stripe = new Stripe(
|
// Could also go in App.js if needed in the future
|
||||||
"pk_test_51NNoasBi8p7FeGFrI5SfpM6HuNMoxwImx6NRKyKbgbt6OPxMxQDiZ9I1GqvDa9qUwB3D3jlJOng6MyjPppWofxzP00Exvr8dBy"
|
const stripe = new Stripe(stripeApiKey);
|
||||||
);
|
|
||||||
|
|
||||||
const apiUrl =
|
const apiUrl =
|
||||||
process.env.NODE_ENV === "development"
|
process.env.NODE_ENV === "development"
|
||||||
? process.env.REACT_APP_API_DEV
|
? process.env.REACT_APP_API_DEV
|
||||||
: process.env.REACT_APP_API_PROD;
|
: process.env.REACT_APP_API_PROD;
|
||||||
|
|
||||||
|
const modalText = "Description of monthly and annual subscriptions";
|
||||||
|
|
||||||
const handleChangeInput = (e, name) => {
|
const handleChangeInput = (e, name) => {
|
||||||
const newData = handleFormDataChange(e, name, data, signupFields);
|
const newData = handleFormDataChange(e, name, data, signupFields);
|
||||||
if (newData !== null) {
|
if (newData !== null) {
|
||||||
@@ -72,16 +74,12 @@ const SignupPage = () => {
|
|||||||
const tempPlan = signupRadioFields.filter((field) => {
|
const tempPlan = signupRadioFields.filter((field) => {
|
||||||
return field.value === value;
|
return field.value === value;
|
||||||
});
|
});
|
||||||
console.log("tempPlan", tempPlan);
|
|
||||||
setSelectedPlan(tempPlan);
|
setSelectedPlan(tempPlan);
|
||||||
const temp = value;
|
const temp = value;
|
||||||
setActiveRadioOption(temp);
|
setActiveRadioOption(temp);
|
||||||
};
|
};
|
||||||
|
|
||||||
signupRadioFields.map((option) => {
|
|
||||||
console.log(option.value);
|
|
||||||
});
|
|
||||||
|
|
||||||
const validateData = () => {
|
const validateData = () => {
|
||||||
const newData = getValidatedFormData(data, signupFields);
|
const newData = getValidatedFormData(data, signupFields);
|
||||||
const hasErrors = isFormDataHasErrors(newData);
|
const hasErrors = isFormDataHasErrors(newData);
|
||||||
@@ -155,12 +153,20 @@ const SignupPage = () => {
|
|||||||
if (isBusy) {
|
if (isBusy) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
const dataValues = validateData();
|
const dataValues = validateData();
|
||||||
if (dataValues === null) {
|
if (dataValues === null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
setShowSelectPlan(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleToggle = () => {
|
||||||
|
setIsAnnualBilling(!isAnnualBilling);
|
||||||
|
console.log("isAnnualBilling", isAnnualBilling);
|
||||||
|
};
|
||||||
|
|
||||||
async function handleStripeAuthorization(
|
async function handleStripeAuthorization(
|
||||||
user,
|
user,
|
||||||
paymentDataValues,
|
paymentDataValues,
|
||||||
@@ -231,7 +237,7 @@ const SignupPage = () => {
|
|||||||
if (paymentDataValues === null) {
|
if (paymentDataValues === null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
//
|
||||||
let dataValues = validateData();
|
let dataValues = validateData();
|
||||||
if (dataValues === null) {
|
if (dataValues === null) {
|
||||||
return;
|
return;
|
||||||
@@ -371,13 +377,23 @@ const SignupPage = () => {
|
|||||||
{showSelectPlan ? (
|
{showSelectPlan ? (
|
||||||
<div className="select-plan-container">
|
<div className="select-plan-container">
|
||||||
<div className="select-sub-left">
|
<div className="select-sub-left">
|
||||||
<div>
|
<div className="select-plan-header">
|
||||||
|
<div className="plan-header-right">
|
||||||
<h5 className="signup-subheader-text">
|
<h5 className="signup-subheader-text">
|
||||||
Select your subscription plan
|
Select a subscription plan
|
||||||
</h5>
|
</h5>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="plan-header-left">
|
||||||
|
<div className="select-toggle-box">
|
||||||
|
<p className="select-billing-text">Billed annually</p>
|
||||||
|
<Toggle onClick={handleToggle} />
|
||||||
|
<p className="select-billing-text">Billed montly</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div className="radio-group-box">
|
<div className="radio-group-box">
|
||||||
{signupRadioFields?.map((option, i) => (
|
{signupRadioFields?.map((option, i) => (
|
||||||
|
<div className="signup-radio-container">
|
||||||
<Radio
|
<Radio
|
||||||
onClick={handleChangeRadioInput}
|
onClick={handleChangeRadioInput}
|
||||||
value={option.value}
|
value={option.value}
|
||||||
@@ -385,30 +401,13 @@ const SignupPage = () => {
|
|||||||
description={option.description}
|
description={option.description}
|
||||||
details={option.details}
|
details={option.details}
|
||||||
activeRadioOption={activeRadioOption}
|
activeRadioOption={activeRadioOption}
|
||||||
price={option.price}
|
price={option.pricing}
|
||||||
|
isAnnualBilling={isAnnualBilling}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="select-sub-right">
|
|
||||||
<div className="select-plan-summary-box ">
|
|
||||||
<div>Order summary</div>
|
|
||||||
<div>{`{subVar} subscription type`}</div>
|
|
||||||
<div>{`{subVar} subscription mini description`}</div>
|
|
||||||
<div>{`Total billed today: {subVar} `}</div>
|
|
||||||
<div>Plus aplicable sales tax -toooltip</div>
|
|
||||||
</div>
|
|
||||||
<div className="selectplan-payment-button-wrapper">
|
|
||||||
<Button
|
|
||||||
className="primary-button signup-proceed"
|
|
||||||
type="button"
|
|
||||||
size="lg"
|
|
||||||
onClick={handleProceedToPayment}
|
|
||||||
disabled={isBusy}
|
|
||||||
labelText="Proceed to Payment"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<></>
|
<></>
|
||||||
|
|||||||
@@ -1,26 +1,50 @@
|
|||||||
export const signupRadioFields = [
|
export const signupRadioFields = [
|
||||||
{
|
{
|
||||||
name: "Monthly - basic",
|
name: "Associate",
|
||||||
label: "Monthly - basic",
|
label: "Monthly - basic",
|
||||||
value: "monthlyBasic",
|
value: "monthlyBasic",
|
||||||
description: "Generate 1 document per month",
|
description: [
|
||||||
details: "Billed every month",
|
"1 document per month",
|
||||||
price: 89,
|
"Carryover 1 document to next period",
|
||||||
|
"24/7 support",
|
||||||
|
"First month is free!",
|
||||||
|
],
|
||||||
|
details: "",
|
||||||
|
pricing: [
|
||||||
|
{ type: "standard", amount: 69 },
|
||||||
|
{ type: "annDiscount", amount: 49 },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Monthly - pro",
|
name: "Partner",
|
||||||
label: "Monthly - pro",
|
label: "Monthly - pro",
|
||||||
value: "monthlyProPlan",
|
value: "monthlyProPlan",
|
||||||
description: "Generate up to 3 documents per month",
|
description: [
|
||||||
details: "Billed every three months. A xxx percent savings",
|
"3 documents per month",
|
||||||
price: 159,
|
"Carryover 2 documents to next period",
|
||||||
|
"Up to 2 additional accounts: 59/each",
|
||||||
|
"24/7 support",
|
||||||
|
],
|
||||||
|
details: "",
|
||||||
|
pricing: [
|
||||||
|
{ type: "standard", amount: 97 },
|
||||||
|
{ type: "annDiscount", amount: 79 },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "Annual - unlimted annual",
|
name: "Senior Partner",
|
||||||
label: "Annual - unlimited annual",
|
label: "Annual - unlimited annual",
|
||||||
value: "annualUnlimited",
|
value: "annualUnlimited",
|
||||||
description: "Generate unlimited documents.",
|
description: [
|
||||||
details: "Billed annualy. A xxx percent savings",
|
"Unlimited documents.",
|
||||||
price: 1489,
|
"Triage-level support",
|
||||||
|
"Up to 8 additional accounts at 19/each",
|
||||||
|
],
|
||||||
|
details: "",
|
||||||
|
pricing: [
|
||||||
|
{ type: "standard", amount: 149 },
|
||||||
|
{ type: "annDiscount", amount: 119 },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
//
|
||||||
|
|||||||
@@ -12,59 +12,47 @@ const Radio = (props) => {
|
|||||||
disabled,
|
disabled,
|
||||||
activeRadioOption,
|
activeRadioOption,
|
||||||
details,
|
details,
|
||||||
|
isAnnualBilling,
|
||||||
} = props;
|
} = props;
|
||||||
const classCheckbox = "checkbox";
|
const classCheckbox = "checkbox";
|
||||||
const classOption = "option";
|
const classOption = "option";
|
||||||
console.log("value, activeRadioOption", value, activeRadioOption);
|
const index = isAnnualBilling ? Number("1") : Number("0");
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className="radio-container">
|
||||||
|
<div className="radio-option-container" key={name}>
|
||||||
|
<>
|
||||||
|
<div className="radio-circle-container">
|
||||||
<div
|
<div
|
||||||
className="radio-option-container"
|
className="radio-circle-top"
|
||||||
key={name}
|
|
||||||
onClick={() => !disabled && onClick && onClick(value)}
|
onClick={() => !disabled && onClick && onClick(value)}
|
||||||
>
|
>
|
||||||
{value == activeRadioOption ? (
|
{value == activeRadioOption ? (
|
||||||
<>
|
|
||||||
<div className="radio-circle-container">
|
|
||||||
<div className="radio-circle-top">
|
|
||||||
<div className="radio-circle-box">
|
<div className="radio-circle-box">
|
||||||
<CircleFill color="#1a76c7" size="20px" />
|
<CircleFill color="#1a76c7" size="20px" />
|
||||||
</div>
|
</div>
|
||||||
<div className="radio-name-box"> {`${name}`} </div>
|
|
||||||
<div className="radio-price-box">
|
|
||||||
<div className="radio-price"> {`${price}`} </div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div></div>
|
|
||||||
<div className="radio-circle-lower">
|
|
||||||
<div className="radio-description-box">
|
|
||||||
{" "}
|
|
||||||
{`${description}`}{" "}
|
|
||||||
</div>
|
|
||||||
<div className="radio-description-box">{`${details}`} </div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
) : (
|
) : (
|
||||||
<>
|
|
||||||
<div className="radio-circle-container">
|
|
||||||
<div className="radio-circle-top">
|
|
||||||
<div className="radio-circle-box">
|
<div className="radio-circle-box">
|
||||||
<Circle color="#1a76c7" size="20px" />
|
<Circle color="#1a76c7" size="20px" />
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
<div className="radio-name-box"> {`${name}`} </div>
|
<div className="radio-name-box"> {`${name}`} </div>
|
||||||
<div className="radio-price-box">
|
<div className="radio-price-box">
|
||||||
<div className="radio-price"> {`${price}`} </div>
|
<div className="radio-price">
|
||||||
|
{" "}
|
||||||
|
{`${price[index]["amount"]}`}{" "}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="radio-circle-lower">
|
<div className="radio-circle-lower">
|
||||||
<div className="radio-description-box">{`${description}`} </div>
|
<div className="radio-description-box">
|
||||||
|
{description.map((item, i) => {
|
||||||
|
return <p className="signup-feat-item">{item}</p>;
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
<div className="radio-description-box">{`${details}`} </div>
|
<div className="radio-description-box">{`${details}`} </div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</>
|
</>
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
24
src/pageElements/Toggle.js
Normal file
24
src/pageElements/Toggle.js
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
import ToggleButton from "react-bootstrap/ToggleButton";
|
||||||
|
import ToggleButtonGroup from "react-bootstrap/ToggleButtonGroup";
|
||||||
|
|
||||||
|
const Toggle = (props) => {
|
||||||
|
const { onClick } = props;
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<ToggleButtonGroup type="radio" name="options" defaultValue={1}>
|
||||||
|
<ToggleButton
|
||||||
|
onClick={onClick}
|
||||||
|
id="tbg-radio-1"
|
||||||
|
value={1}
|
||||||
|
></ToggleButton>
|
||||||
|
<ToggleButton
|
||||||
|
onClick={onClick}
|
||||||
|
id="tbg-radio-2"
|
||||||
|
value={2}
|
||||||
|
></ToggleButton>
|
||||||
|
</ToggleButtonGroup>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default Toggle;
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
height: 160px;
|
height: 290px;
|
||||||
margin: 10px 8px 0px 8px;
|
margin: 10px 8px 0px 8px;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
border: 1px solid #d4d4d4;
|
border: 1px solid #d4d4d4;
|
||||||
@@ -12,38 +12,51 @@
|
|||||||
height: 40px;
|
height: 40px;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
|
margin-top: 12px;
|
||||||
|
margin-left: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.radio-circle-lower {
|
.radio-circle-lower {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
margin-left: 18px;
|
margin-left: 12px;
|
||||||
padding-left: 26px;
|
padding-left: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.radio-circle-box {
|
.radio-circle-box {
|
||||||
height: 40px;
|
display: flex;
|
||||||
margin: 12px 8px;
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
margin: auto;
|
||||||
|
height: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.radio-name-box {
|
.radio-name-box {
|
||||||
height: 40px;
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding-top: 10px;
|
||||||
|
height: 30px;
|
||||||
width: 50%;
|
width: 50%;
|
||||||
font-family: var(--main-font);
|
font-family: var(--main-font);
|
||||||
font-family: Roboto;
|
font-family: Roboto;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
letter-spacing: 0.05rem;
|
letter-spacing: 0.05rem;
|
||||||
margin: 13px 8px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.radio-price-box {
|
.radio-price-box {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: row-reverse;
|
flex-direction: row-reverse;
|
||||||
margin: 16px 8px;
|
height: 30px;
|
||||||
width: 30%;
|
width: 30%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.radio-price {
|
.radio-price {
|
||||||
width: 20px;
|
height: 25px;
|
||||||
|
width: 40px;
|
||||||
float: right;
|
float: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.radio-description-box {
|
||||||
|
width: 240px;
|
||||||
|
}
|
||||||
|
|||||||
@@ -64,11 +64,35 @@
|
|||||||
height: 600px;
|
height: 600px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.select-plan-header {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
width: 900px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.plan-header-right {
|
||||||
|
padding: 12px 14px;
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.plan-header-left {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
padding: 12px 14px;
|
||||||
|
width: 50%;
|
||||||
|
}
|
||||||
|
|
||||||
.select-sub-left {
|
.select-sub-left {
|
||||||
width: 60%;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 45px;
|
||||||
|
width: 100%;
|
||||||
|
padding: 12px;
|
||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
background-color: rgb(240, 247, 250);
|
background-color: rgb(240, 247, 250);
|
||||||
margin-right: 8px;
|
|
||||||
border: 1px solid #e9e9e9;
|
border: 1px solid #e9e9e9;
|
||||||
padding: 6px;
|
padding: 6px;
|
||||||
}
|
}
|
||||||
@@ -82,6 +106,20 @@
|
|||||||
padding: 6px;
|
padding: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.select-toggle-box {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 2px;
|
||||||
|
width: 240px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.select-billing-text {
|
||||||
|
font-size: 0.85rem;
|
||||||
|
}
|
||||||
|
|
||||||
.signup-radio-wrapper {
|
.signup-radio-wrapper {
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -95,10 +133,10 @@
|
|||||||
|
|
||||||
.radio-group-box {
|
.radio-group-box {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: row;
|
||||||
padding: 6px;
|
padding: 6px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 300px;
|
height: 420px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.select-plan-summary-box {
|
.select-plan-summary-box {
|
||||||
@@ -109,6 +147,7 @@
|
|||||||
border-radius: 10px;
|
border-radius: 10px;
|
||||||
background-color: #fff;
|
background-color: #fff;
|
||||||
border: 1px solid #e9e9e9;
|
border: 1px solid #e9e9e9;
|
||||||
|
margin-top: 5px;
|
||||||
padding: 6px;
|
padding: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,3 +161,13 @@
|
|||||||
.signup-option {
|
.signup-option {
|
||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.signup-radio-container {
|
||||||
|
width: 350px;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.signup-feat-item {
|
||||||
|
font-size: 0.9rem;
|
||||||
|
margin: 8px 0px 8px 4px;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user