@@ -1,5 +1,10 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import { checkActionCode, confirmPasswordReset, getAuth, sendPasswordResetEmail } from "firebase/auth";
|
import {
|
||||||
|
checkActionCode,
|
||||||
|
confirmPasswordReset,
|
||||||
|
getAuth,
|
||||||
|
sendPasswordResetEmail,
|
||||||
|
} from "firebase/auth";
|
||||||
import Button from "../../pageElements/Button";
|
import Button from "../../pageElements/Button";
|
||||||
import { useSearchParams } from "react-router-dom";
|
import { useSearchParams } from "react-router-dom";
|
||||||
|
|
||||||
@@ -75,122 +80,133 @@ const PasswordResetPage = () => {
|
|||||||
} finally {
|
} finally {
|
||||||
setIsBusy(false);
|
setIsBusy(false);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
const resetMode = mode === "resetPassword" ? "resetPassword" : "enterEmail";
|
const resetMode = mode === "resetPassword" ? "resetPassword" : "enterEmail";
|
||||||
return (
|
return (
|
||||||
<div className="password-reset-container">
|
<div className="password-reset-container">
|
||||||
<div className="password-reset-form-wrapper">
|
<div className="password-reset-form-wrapper">
|
||||||
<div className="password-reset-form">
|
<div className="password-reset-form">
|
||||||
{resetMode === "enterEmail" ? <>
|
{resetMode === "enterEmail" ? (
|
||||||
<div className="password-reset-header">
|
<>
|
||||||
<h2 className="password-reset-header-text">
|
<div className="password-reset-header">
|
||||||
Enter Account Email
|
<h2 className="password-reset-header-text">
|
||||||
</h2>
|
Enter Account Email
|
||||||
</div>
|
</h2>
|
||||||
{!done ? (
|
|
||||||
<form>
|
|
||||||
<div className="form-floating">
|
|
||||||
<input
|
|
||||||
type="email"
|
|
||||||
className="form-control"
|
|
||||||
id="emailInput"
|
|
||||||
placeholder="Email"
|
|
||||||
value={email}
|
|
||||||
onChange={(e) => setEmail(e.target.value)}
|
|
||||||
disabled={isBusy}
|
|
||||||
></input>
|
|
||||||
<label htmlFor="emailInput" className="form-label">
|
|
||||||
Email
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div className="alert-box">
|
|
||||||
{"" !== notice && (
|
|
||||||
<div className="password-reset-alert" role="alert">
|
|
||||||
{notice}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<div className="password-reset-button-wrapper">
|
|
||||||
<Button
|
|
||||||
className="primary-button"
|
|
||||||
onClick={(e) => handleResetPassword(e)}
|
|
||||||
labelText="Submit"
|
|
||||||
disabled={isBusy}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
) : null}
|
|
||||||
{done && (
|
|
||||||
<div className="success-container">
|
|
||||||
<p className="reset-sent-text">A password reset link was sent.</p>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
{!done ? (
|
||||||
</> : null}
|
<form>
|
||||||
{resetMode === "resetPassword" ? <>
|
<div className="form-floating">
|
||||||
<div className="password-reset-header">
|
<input
|
||||||
<h2 className="password-reset-header-text">
|
type="email"
|
||||||
Enter New Password
|
className="form-control"
|
||||||
</h2>
|
id="emailInput"
|
||||||
</div>
|
placeholder="Email"
|
||||||
{!done && isCodeValid !== null && isCodeValid ? (
|
value={email}
|
||||||
<form>
|
onChange={(e) => setEmail(e.target.value)}
|
||||||
<div className="form-floating mb-3">
|
disabled={isBusy}
|
||||||
<input
|
></input>
|
||||||
type="password"
|
<label htmlFor="emailInput" className="form-label">
|
||||||
className="form-control"
|
Email
|
||||||
id="passwordInput"
|
</label>
|
||||||
placeholder="Password"
|
</div>
|
||||||
value={password}
|
<div className="alert-box">
|
||||||
onChange={(e) => setPassword(e.target.value)}
|
{"" !== notice && (
|
||||||
disabled={isBusy}
|
<div className="password-reset-alert" role="alert">
|
||||||
></input>
|
{notice}
|
||||||
<label htmlFor="emailInput" className="form-label">
|
</div>
|
||||||
Enter new password
|
)}
|
||||||
</label>
|
</div>
|
||||||
|
<div className="password-reset-button-wrapper">
|
||||||
|
<Button
|
||||||
|
className="primary-button"
|
||||||
|
onClick={(e) => handleResetPassword(e)}
|
||||||
|
labelText="Submit"
|
||||||
|
disabled={isBusy}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
) : null}
|
||||||
|
{done && (
|
||||||
|
<div className="success-container">
|
||||||
|
<p className="reset-sent-text">
|
||||||
|
A password reset link was sent.
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="form-floating">
|
)}
|
||||||
<input
|
</>
|
||||||
type="password"
|
) : null}
|
||||||
className="form-control"
|
{resetMode === "resetPassword" ? (
|
||||||
id="confirmPasswordInput"
|
<>
|
||||||
placeholder="Confirm Password"
|
<div className="password-reset-header">
|
||||||
value={confirmPassword}
|
<h2 className="password-reset-header-text">
|
||||||
onChange={(e) => setConfirmPassword(e.target.value)}
|
Enter New Password
|
||||||
disabled={isBusy}
|
</h2>
|
||||||
></input>
|
|
||||||
<label htmlFor="confirmPasswordInput" className="form-label">
|
|
||||||
Confirm password
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
<div className="alert-box">
|
|
||||||
{"" !== notice && (
|
|
||||||
<div className="password-reset-alert" role="alert">
|
|
||||||
{notice}
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<div className="password-reset-button-wrapper">
|
|
||||||
<Button
|
|
||||||
className="primary-button"
|
|
||||||
onClick={(e) => handleConfirmPasswordReset(e)}
|
|
||||||
labelText="Submit"
|
|
||||||
disabled={isBusy}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
) : null}
|
|
||||||
{!done && isCodeValid !== null && !isCodeValid && (
|
|
||||||
<div className="success-container">
|
|
||||||
<p className="reset-sent-text">Bad or already used password reset code.</p>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
{!done && isCodeValid !== null && isCodeValid ? (
|
||||||
{done && (
|
<form>
|
||||||
<div className="success-container">
|
<div className="form-floating mb-3">
|
||||||
<p className="reset-sent-text">Password changed.</p>
|
<input
|
||||||
</div>
|
type="password"
|
||||||
)}
|
className="form-control"
|
||||||
</> : null}
|
id="passwordInput"
|
||||||
|
placeholder="Password"
|
||||||
|
value={password}
|
||||||
|
onChange={(e) => setPassword(e.target.value)}
|
||||||
|
disabled={isBusy}
|
||||||
|
></input>
|
||||||
|
<label htmlFor="emailInput" className="form-label">
|
||||||
|
Enter new password
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div className="form-floating">
|
||||||
|
<input
|
||||||
|
type="password"
|
||||||
|
className="form-control"
|
||||||
|
id="confirmPasswordInput"
|
||||||
|
placeholder="Confirm Password"
|
||||||
|
value={confirmPassword}
|
||||||
|
onChange={(e) => setConfirmPassword(e.target.value)}
|
||||||
|
disabled={isBusy}
|
||||||
|
></input>
|
||||||
|
<label
|
||||||
|
htmlFor="confirmPasswordInput"
|
||||||
|
className="form-label"
|
||||||
|
>
|
||||||
|
Confirm password
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div className="alert-box">
|
||||||
|
{"" !== notice && (
|
||||||
|
<div className="password-reset-alert" role="alert">
|
||||||
|
{notice}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="password-reset-button-wrapper">
|
||||||
|
<Button
|
||||||
|
className="primary-button"
|
||||||
|
onClick={(e) => handleConfirmPasswordReset(e)}
|
||||||
|
labelText="Submit"
|
||||||
|
disabled={isBusy}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
) : null}
|
||||||
|
{!done && isCodeValid !== null && !isCodeValid && (
|
||||||
|
<div className="success-container">
|
||||||
|
<p className="reset-sent-text">
|
||||||
|
Bad or already used password reset code.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
{done && (
|
||||||
|
<div className="success-container">
|
||||||
|
<p className="reset-sent-text">Password changed.</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -83,6 +83,7 @@ const CaseListPage = ({ perPage }) => {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const dropDownOptions = [
|
const dropDownOptions = [
|
||||||
{ label: "Case name a - z", value: "caption" },
|
{ label: "Case name a - z", value: "caption" },
|
||||||
{ label: "Case name z - a", value: "caption2" },
|
{ label: "Case name z - a", value: "caption2" },
|
||||||
@@ -159,11 +160,17 @@ const CaseListPage = ({ perPage }) => {
|
|||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<div className="nodocs-text-container">
|
<div className="nodocs-text-container">
|
||||||
<p> You have not created any cases yet.</p>
|
<p> Please create your first case.</p>
|
||||||
<p>
|
<p>
|
||||||
To get started, click "Create New Case" and enter case
|
To create a discovery request or response, you will first enter
|
||||||
information.
|
some basic information about the case they will pertain to -
|
||||||
|
i.e. the caption and case number.
|
||||||
</p>
|
</p>
|
||||||
|
<p>
|
||||||
|
Then, you will upload a document (i.e. interrogatories or a
|
||||||
|
complaint), for use in generating a request/response.
|
||||||
|
</p>
|
||||||
|
<p>Click "Create New Case" to get started.</p>
|
||||||
{createNewButton()}
|
{createNewButton()}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -15,21 +15,26 @@ import { Typeahead } from "react-bootstrap-typeahead";
|
|||||||
import { AppContext } from "../../Hooks/useContext/appContext.js";
|
import { AppContext } from "../../Hooks/useContext/appContext.js";
|
||||||
import UploadModal from "../Modals/UploadModal.js";
|
import UploadModal from "../Modals/UploadModal.js";
|
||||||
import Button from "react-bootstrap/Button";
|
import Button from "react-bootstrap/Button";
|
||||||
|
import { getAuth } from "firebase/auth";
|
||||||
|
|
||||||
const Dashboard = () => {
|
const Dashboard = () => {
|
||||||
const size = window.innerWidth < 440;
|
const size = window.innerWidth < 440;
|
||||||
const [isMobile, setIsMobile] = useState(size);
|
const [isMobile, setIsMobile] = useState(size);
|
||||||
|
const auth = getAuth();
|
||||||
const count = useRef(null);
|
const count = useRef(null);
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const [allCases, setAllCases] = useState(null);
|
const [allCases, setAllCases] = useState(null);
|
||||||
const [selectedCase, setSelectedCase] = useState(null);
|
const [selectedCase, setSelectedCase] = useState(null);
|
||||||
const [showModal, setShowModal] = useState();
|
const [showModal, setShowModal] = useState();
|
||||||
const [docCount, setDocCount] = useState();
|
const [docCount, setDocCount] = useState();
|
||||||
|
const [isPromoFirstLogin, setIsPromoFirstLogin] = useState(true);
|
||||||
const [responseCount, setResponseCount] = useState();
|
const [responseCount, setResponseCount] = useState();
|
||||||
const { appState } = useContext(AppContext);
|
const { appState } = useContext(AppContext);
|
||||||
const { group } = appState;
|
const { group } = appState;
|
||||||
const appUserId = group ? group.appUserId : null;
|
const appUserId = group ? group.appUserId : null;
|
||||||
const isDashboard = true;
|
const isDashboard = true;
|
||||||
|
console.log("group on dashbaord page", group);
|
||||||
|
console.log("auth in dashoabrd page", auth);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (count.current == null) {
|
if (count.current == null) {
|
||||||
@@ -177,6 +182,31 @@ const Dashboard = () => {
|
|||||||
<div className="user-name-container2">{group.firm}</div>
|
<div className="user-name-container2">{group.firm}</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="app-divider dash-divider" />
|
<div className="app-divider dash-divider" />
|
||||||
|
{isPromoFirstLogin ? (
|
||||||
|
<>
|
||||||
|
<div className="dash-promo-first-box">
|
||||||
|
<div className="dash-promo-first-wrap">
|
||||||
|
<div className="dash-promo-first-textwrap">
|
||||||
|
<div className="dash-promo-first-text">
|
||||||
|
Welcome to Novodraft, attorney {group.lastName}. We are
|
||||||
|
excited to introduce you to our application. Review the
|
||||||
|
step-by-step user guide by clicking "How-to" in the navigation
|
||||||
|
bar.
|
||||||
|
</div>
|
||||||
|
<div className="dash-promo-first-text">
|
||||||
|
Your user name for login is:{" "}
|
||||||
|
<span className="user-name-span">{group.email}</span>. Your
|
||||||
|
temporary password is{" "}
|
||||||
|
<span className="user-name-span">{group.tpe}</span>. You
|
||||||
|
should change it now, by clicking here.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="app-divider dash-divider" />
|
||||||
|
</>
|
||||||
|
) : null}
|
||||||
<div className="stats-container">
|
<div className="stats-container">
|
||||||
<div className="stats-row-box">
|
<div className="stats-row-box">
|
||||||
<div className="stats-unit-wrapper">
|
<div className="stats-unit-wrapper">
|
||||||
|
|||||||
@@ -1,284 +1,478 @@
|
|||||||
import { useEffect } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { collection, setDoc, doc } from "firebase/firestore";
|
import { collection, setDoc, doc } from "firebase/firestore";
|
||||||
import { db } from "../../firebase";
|
import { db, auth } from "../../firebase";
|
||||||
import Button from "../../pageElements/Button";
|
import Button from "../../pageElements/Button";
|
||||||
import { v4 as uuidv4 } from "uuid";
|
import { v4 as uuidv4 } from "uuid";
|
||||||
import arrow from "../../Assets/Images/Arrow.png";
|
import arrow from "../../Assets/Images/Arrow.png";
|
||||||
import { useNavigate } from "react-router-dom";
|
import { useNavigate } from "react-router-dom";
|
||||||
|
import ConfirmModal from "../Modals/ConfirmModal";
|
||||||
|
import { createUserWithEmailAndPassword } from "firebase/auth";
|
||||||
|
import { stateDataValues } from "../../Constants/Fields/SignupFields";
|
||||||
import "../../styles/homepage.scss";
|
import "../../styles/homepage.scss";
|
||||||
|
import LoadingSpinner from "../../pageElements/LoadingSpinner";
|
||||||
|
|
||||||
const HomePage = () => {
|
const HomePage = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
const [showPromoModal, setShowPromoModal] = useState(false);
|
||||||
|
const [isBusy, setIsBusy] = useState(false);
|
||||||
|
const [notice, setNotice] = useState("");
|
||||||
|
|
||||||
const handleNavigate = () => {
|
const apiUrl =
|
||||||
navigate("/signup");
|
process.env.NODE_ENV === "development"
|
||||||
|
? process.env.REACT_APP_API_DEV
|
||||||
|
: process.env.REACT_APP_API_PROD;
|
||||||
|
|
||||||
|
async function saveUserData(
|
||||||
|
authId,
|
||||||
|
dataValues,
|
||||||
|
email,
|
||||||
|
password,
|
||||||
|
customerId,
|
||||||
|
subscriptionCreated,
|
||||||
|
subscriptionPeriodStart,
|
||||||
|
subscriptionPeriodEnd,
|
||||||
|
subscriptionId,
|
||||||
|
isPromotionalMebership = true,
|
||||||
|
docsAllowedPeMonth = 1
|
||||||
|
) {
|
||||||
|
if (!email || !password || !dataValues[0]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const appUserId = uuidv4();
|
||||||
|
const firmId = uuidv4();
|
||||||
|
const fbAuthUid = authId;
|
||||||
|
const tpe = password;
|
||||||
|
let plan = "promo plan";
|
||||||
|
let docsAllowedPerMonth;
|
||||||
|
|
||||||
|
docsAllowedPerMonth = 1;
|
||||||
|
subscriptionId = uuidv4();
|
||||||
|
plan = plan;
|
||||||
|
|
||||||
|
const docsGenerated = 0;
|
||||||
|
|
||||||
|
const {
|
||||||
|
firstName,
|
||||||
|
lastName,
|
||||||
|
firm,
|
||||||
|
telephone,
|
||||||
|
streetAddress,
|
||||||
|
city,
|
||||||
|
state,
|
||||||
|
zipCode,
|
||||||
|
barNumber,
|
||||||
|
practiceArea,
|
||||||
|
} = dataValues[0];
|
||||||
|
|
||||||
|
const userState = stateDataValues.filter((value) => {
|
||||||
|
if (value.name === state) return value;
|
||||||
|
});
|
||||||
|
|
||||||
|
const userData = {
|
||||||
|
docsAllowedPerMonth,
|
||||||
|
docsGenerated,
|
||||||
|
appUserId,
|
||||||
|
fbAuthUid,
|
||||||
|
firmId,
|
||||||
|
firstName,
|
||||||
|
lastName,
|
||||||
|
firm,
|
||||||
|
telephone,
|
||||||
|
streetAddress,
|
||||||
|
city,
|
||||||
|
state: userState,
|
||||||
|
zipCode,
|
||||||
|
barNumber,
|
||||||
|
practiceArea,
|
||||||
|
email,
|
||||||
|
tpe: tpe,
|
||||||
|
isPromotionalMebership,
|
||||||
|
isPromotionalFirstLogin: true,
|
||||||
|
customerId: customerId,
|
||||||
|
subscriptionId: subscriptionId,
|
||||||
|
subscriptionPlan: "flordia-spring-promo-plan",
|
||||||
|
subscriptionCreated: subscriptionCreated,
|
||||||
|
subscriptionPeriodStart: subscriptionPeriodStart,
|
||||||
|
subscriptionPeriodEnd: subscriptionPeriodEnd,
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const usersRef = collection(db, "users");
|
||||||
|
const res = await setDoc(doc(usersRef, fbAuthUid), userData);
|
||||||
|
return res;
|
||||||
|
} catch (error) {
|
||||||
|
console.log(`Error saving new user to db: ${error}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getFocusData(code) {
|
||||||
|
console.log("code in getFocusData", code);
|
||||||
|
try {
|
||||||
|
const response = await fetch(`${apiUrl}/v1/get-focused-data/${code}`, {
|
||||||
|
method: "GET",
|
||||||
|
});
|
||||||
|
const res = await response.json();
|
||||||
|
console.log("res in getFocusData", res);
|
||||||
|
return res;
|
||||||
|
} catch (err) {
|
||||||
|
console.log("Error in get rqst:", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleProcessPromoSubscription(code) {
|
||||||
|
console.log("code in handleProcessPromoSubscription", code);
|
||||||
|
setIsBusy(true);
|
||||||
|
setShowPromoModal(false);
|
||||||
|
if (!code) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const userData = await getFocusData(code);
|
||||||
|
console.log("userData in returned from getFocusData", userData);
|
||||||
|
const email = userData[0].email;
|
||||||
|
const password = userData[0].password;
|
||||||
|
if (email && password) {
|
||||||
|
console.log("123 email, password", email, password);
|
||||||
|
handlePromoSignup(userData, email, password);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handlePromoSignup(dataValues, email, password) {
|
||||||
|
if (!email || !password) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const customerId = `${uuidv4()}-florida-spring-promo`;
|
||||||
|
const today = new Date();
|
||||||
|
const subscriptionCreated = today;
|
||||||
|
const subscriptionPeriodStart = today;
|
||||||
|
console.log("subscriptionPeriodStart", subscriptionPeriodStart);
|
||||||
|
const subscriptionPeriodEnd = today;
|
||||||
|
const subscriptionId = uuidv4();
|
||||||
|
|
||||||
|
const userCredential = await createUserWithEmailAndPassword(
|
||||||
|
auth,
|
||||||
|
email,
|
||||||
|
password
|
||||||
|
);
|
||||||
|
|
||||||
|
const user = userCredential.user;
|
||||||
|
dataValues = { ...dataValues };
|
||||||
|
const isPromotionalMebership = true;
|
||||||
|
console.log("userCredential", userCredential);
|
||||||
|
const res = await saveUserData(
|
||||||
|
user.uid,
|
||||||
|
dataValues,
|
||||||
|
email,
|
||||||
|
password,
|
||||||
|
customerId,
|
||||||
|
subscriptionCreated,
|
||||||
|
subscriptionPeriodStart,
|
||||||
|
subscriptionPeriodEnd,
|
||||||
|
subscriptionId,
|
||||||
|
isPromotionalMebership
|
||||||
|
);
|
||||||
|
console.log("res from saveUserData in handlePromoSignup", res);
|
||||||
|
setIsBusy(false);
|
||||||
|
navigate("/dashboard");
|
||||||
|
} catch (error) {
|
||||||
|
console.log("Error handling request", error, error.message);
|
||||||
|
setIsBusy(false);
|
||||||
|
setNotice("Sorry, something went wrong. Please try again.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleTryItButton = () => {
|
||||||
|
setShowPromoModal(true);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleLogin = () => {
|
const handleLogin = () => {
|
||||||
navigate("/login");
|
navigate("/login");
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const handleCancelModal = () => {
|
||||||
|
setShowPromoModal(!showPromoModal);
|
||||||
|
navigate("/signup");
|
||||||
|
};
|
||||||
|
|
||||||
const handleDemo = () => {
|
const handleDemo = () => {
|
||||||
const supReq = null;
|
const supReq = null;
|
||||||
navigate("/requestpage/supReq");
|
navigate("/requestpage/supReq");
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
const homeContent = (
|
||||||
<>
|
<div className="homepage-container">
|
||||||
<div className="homepage-container">
|
<section
|
||||||
<section
|
className="section-1"
|
||||||
className="section-1"
|
style={{
|
||||||
|
backgroundImage: `url(https://imagedelivery.net/OvFc3s8IYmBw7-_bogeTLg/ee5222a0-7480-43ba-0f14-0ea482f31300/public)`,
|
||||||
|
backgroundSize: "cover",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div className="first-section-subcontainer">
|
||||||
|
<div className="row upper-row-one">
|
||||||
|
<div className="col-md-12 mobile-col-up">
|
||||||
|
<div className="heading-one-container">
|
||||||
|
<h1 className="heading-1">Novodraft: Legal AI</h1>
|
||||||
|
<h1 className="heading-1-mobile">Novodraft</h1>
|
||||||
|
<h1 className="heading-2-mobile">AI-Assisted Legal Drafting</h1>
|
||||||
|
<h1 className="heading-2">
|
||||||
|
Draft documents faster <i>and </i> smarter
|
||||||
|
</h1>
|
||||||
|
</div>
|
||||||
|
<div className="mobile-lower-header-1">
|
||||||
|
<div className="mobile-lower-header-top">
|
||||||
|
<div className="mobile-sw-deck">Discovery requests</div>
|
||||||
|
<div className="mobile-sw-deck"> dramatically fast</div>
|
||||||
|
<div className="mobile-sw-reptwo">
|
||||||
|
<div className="ex-arca-two">Draft responses to</div>
|
||||||
|
<div className="ex-arca-two">demands in minutes</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="mobile-lower-header-bottom">
|
||||||
|
<div className="mobile-lower-header-bottom-up"></div>
|
||||||
|
<div className="mobile-lower-header-bottom-down">
|
||||||
|
<Button
|
||||||
|
className="primary-button homepage-button"
|
||||||
|
labelText="Try It For Free"
|
||||||
|
onClick={handleTryItButton}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p className="text-block-1">
|
||||||
|
Discovery requests done dramatically fast – discovery responses
|
||||||
|
ready in minutes.
|
||||||
|
</p>
|
||||||
|
<p className="text-block-two">
|
||||||
|
Reclaim hours every week. Spend time growing your practice, or
|
||||||
|
just get home by dinner.
|
||||||
|
</p>
|
||||||
|
<div className="try-it-button-box">
|
||||||
|
<Button
|
||||||
|
className="primary-button homepage-button"
|
||||||
|
labelText="Try It For Free"
|
||||||
|
onClick={handleTryItButton}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{/* Section 2 */}
|
||||||
|
<section className="section-2">
|
||||||
|
<div className="home-row">
|
||||||
|
<div className="home-col-50">
|
||||||
|
<div className="heading-2-mobile-box">
|
||||||
|
<h2 className="heading-2-mobile">
|
||||||
|
Made by Attorneys, for Attorneys
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="pad-2">
|
||||||
|
<img
|
||||||
|
src="https://imagedelivery.net/OvFc3s8IYmBw7-_bogeTLg/5f0f6f11-bb56-4f03-b05e-189d4f1a5600/public"
|
||||||
|
alt="image of a laptop computer"
|
||||||
|
className="img-2"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="home-col-50">
|
||||||
|
<div className="pad-2">
|
||||||
|
<h2 className="heading-2">Made by Attorneys, for Attorneys.</h2>
|
||||||
|
<div className="text-block-2-box">
|
||||||
|
<p className="text-block-2">
|
||||||
|
Legal tech developed by people that understand what you need.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p className="section-two-body">
|
||||||
|
Novodraft understands the demands on your time. For example,
|
||||||
|
that discovery request on your desk. With a few clicks, and
|
||||||
|
Novodraft's AI assistant on the task, you can draft a
|
||||||
|
ready-to-serve response in minutes. It's as easy as uploading a
|
||||||
|
.pdf file.
|
||||||
|
</p>
|
||||||
|
<p className="section-two-body">
|
||||||
|
Novodraft cuts through a mire of rote tasks, but does much more
|
||||||
|
than automate.
|
||||||
|
</p>
|
||||||
|
<p className="section-two-body">
|
||||||
|
Intellidraft AI technology powers persuasive arguments and
|
||||||
|
boosts bland, boilerplate objections. Configurable for level of
|
||||||
|
authoritative citation and for infering factual context from
|
||||||
|
pleadings and briefs. Use it to augment your drafting as much or
|
||||||
|
as little as you prefer.
|
||||||
|
</p>
|
||||||
|
<div className="home-link-box">
|
||||||
|
<a className="link">
|
||||||
|
Explore Novodraft
|
||||||
|
<img src={arrow} className="img-1" alt="" />
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{/* Section 3 */}
|
||||||
|
<section className="section-3">
|
||||||
|
<div className="section-three-header-box">
|
||||||
|
<h2 className="section-three-header">
|
||||||
|
AI-Powered Legal Drafting Technology{" "}
|
||||||
|
</h2>
|
||||||
|
<h2 className="section-three-header-mobile">
|
||||||
|
Novo Drafting Technology
|
||||||
|
</h2>
|
||||||
|
<p className="section-three-subhead">
|
||||||
|
Created by litigators to give you an edge.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div className="card-section-container">
|
||||||
|
{/*********** CARD ONE *********** */}
|
||||||
|
<div className="home-card">
|
||||||
|
<div className="card-image-container">
|
||||||
|
<img
|
||||||
|
src="https://imagedelivery.net/OvFc3s8IYmBw7-_bogeTLg/5ff0ba9e-298f-4ee1-88d4-e19a44a00900/public"
|
||||||
|
alt="ai hand"
|
||||||
|
width="100%"
|
||||||
|
className="card-image"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="card-body">
|
||||||
|
<div className="card-upper-box">
|
||||||
|
<div className="home-card-title">
|
||||||
|
<h3 className="foo-card-title">Discovery Requests</h3>
|
||||||
|
<div className="home-card-divider"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="home-card-text-box">
|
||||||
|
<p className="card-texts">
|
||||||
|
Generate interrogatories and requests for
|
||||||
|
production/admissions leveraging AI.
|
||||||
|
</p>
|
||||||
|
<p className="card-texts">
|
||||||
|
Edit or add special language with tags. Concise yet
|
||||||
|
comprehensive demands, done in minutes.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/*********** CARD TWO *********** */}
|
||||||
|
<div className="home-card">
|
||||||
|
<div className="card-image-container">
|
||||||
|
<img
|
||||||
|
src="https://imagedelivery.net/OvFc3s8IYmBw7-_bogeTLg/7a6dd50e-4d8f-4068-61b2-634dc5603f00/public"
|
||||||
|
alt="scales image"
|
||||||
|
width="100%"
|
||||||
|
className="card-image"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="card-body">
|
||||||
|
<div className="card-upper-box">
|
||||||
|
<div className="home-card-title">
|
||||||
|
<h3 className="foo-card-title">Discovery Responses</h3>
|
||||||
|
<div className="home-card-divider"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="home-card-text-box">
|
||||||
|
<p className="card-texts">
|
||||||
|
Use Novodraft AI to quickly draft responses including
|
||||||
|
compelling arguments about what you withhold from disclosure.
|
||||||
|
Finish in minutes with a downloadable .docx file.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{/*********** CARD THREE *********** */}
|
||||||
|
<div className="home-card">
|
||||||
|
<div className="card-image-container">
|
||||||
|
<img
|
||||||
|
src="https://imagedelivery.net/OvFc3s8IYmBw7-_bogeTLg/00667aa1-f847-430c-7a5e-d96abeed3300/public"
|
||||||
|
alt=""
|
||||||
|
className="card-image"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="card-body">
|
||||||
|
<div className="card-upper-box">
|
||||||
|
<div className="home-card-title">
|
||||||
|
<h3 className="foo-card-title">Proactive Alerts</h3>
|
||||||
|
<div className="home-card-divider"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="home-card-text-box">
|
||||||
|
<p className="card-texts">
|
||||||
|
Your dashboard displays important deadlines, alerts, and can
|
||||||
|
be configured to auto-draft documents with reminders for tasks
|
||||||
|
such as service or hearings.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section className="section-5 py-5">
|
||||||
|
<div
|
||||||
|
className="home-test-container"
|
||||||
style={{
|
style={{
|
||||||
backgroundImage: `url(https://imagedelivery.net/OvFc3s8IYmBw7-_bogeTLg/ee5222a0-7480-43ba-0f14-0ea482f31300/public)`,
|
backgroundImage: `url(https://imagedelivery.net/OvFc3s8IYmBw7-_bogeTLg/209dcf14-c086-42b4-ca72-f058d9ad1b00/public)`,
|
||||||
backgroundSize: "cover",
|
backgroundSize: "cover",
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div className="first-section-subcontainer">
|
<div className="row">
|
||||||
<div className="row upper-row-one">
|
<div className="col-md-6">
|
||||||
<div className="col-md-12 mobile-col-up">
|
<div className="bottom-header-box">
|
||||||
<div className="heading-one-container">
|
<h4 className="heading-6">
|
||||||
<h1 className="heading-1">Novodraft: Legal AI.</h1>
|
Questions about our services? <br></br>
|
||||||
<h1 className="heading-1-mobile">Novodraft</h1>
|
We're here to answer!
|
||||||
<h1 className="heading-2-mobile">
|
</h4>
|
||||||
AI-Assisted Legal Drafting
|
<h4 className="heading-6-mobile">
|
||||||
</h1>
|
Questions about our products and services?
|
||||||
<h1 className="heading-2">
|
</h4>
|
||||||
Draft documents faster <i>and </i> smarter.
|
<h4 className="heading-6-mobile">We're here to answer!</h4>
|
||||||
</h1>
|
|
||||||
</div>
|
|
||||||
<div className="mobile-lower-header-1">
|
|
||||||
<div className="mobile-lower-header-top">
|
|
||||||
<div className="mobile-sw-deck">Discovery requests</div>
|
|
||||||
<div className="mobile-sw-deck"> dramatically fast</div>
|
|
||||||
<div className="mobile-sw-reptwo">
|
|
||||||
<div className="ex-arca-two">Draft responses to</div>
|
|
||||||
<div className="ex-arca-two">demands in minutes</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="mobile-lower-header-bottom">
|
|
||||||
<div className="mobile-lower-header-bottom-up"></div>
|
|
||||||
<div className="mobile-lower-header-bottom-down">
|
|
||||||
<Button
|
|
||||||
className="primary-button homepage-button"
|
|
||||||
labelText="Try It For Free"
|
|
||||||
onClick={handleNavigate}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<p className="text-block-1">
|
|
||||||
Discovery requests done dramatically fast – discovery
|
|
||||||
responses ready in minutes
|
|
||||||
</p>
|
|
||||||
<p className="text-block-two">
|
|
||||||
Reclaim hours every week. Spend time growing your practice, or
|
|
||||||
just get home by dinner.
|
|
||||||
</p>
|
|
||||||
<div className="try-it-button-box">
|
|
||||||
<Button
|
|
||||||
className="primary-button homepage-button"
|
|
||||||
labelText="Try It For Free"
|
|
||||||
onClick={handleNavigate}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
<h6 className="join-heading">
|
||||||
|
Novodraft will revolutionize your practice.
|
||||||
|
</h6>
|
||||||
|
<h6 className="join-heading">
|
||||||
|
Request a demo - let us show you how.
|
||||||
|
</h6>
|
||||||
|
<h6 className="join-heading-mobile">
|
||||||
|
Revolutionize your practice.
|
||||||
|
</h6>
|
||||||
|
<h6 className="join-heading-mobile">Let us show you how.</h6>
|
||||||
|
</div>
|
||||||
|
<div className="col-md-6 d-flex">
|
||||||
|
<button className="button-2" onClick={handleDemo}>
|
||||||
|
Request a demo
|
||||||
|
</button>
|
||||||
|
<button className="button-2" onClick={handleLogin}>
|
||||||
|
Go to login
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</div>
|
||||||
{/* Section 2 */}
|
</section>
|
||||||
<section className="section-2">
|
{showPromoModal ? (
|
||||||
<div className="home-row">
|
<ConfirmModal
|
||||||
<div className="home-col-50">
|
titleText="Enter Promo Code"
|
||||||
<div className="heading-2-mobile-box">
|
onCancel={handleCancelModal}
|
||||||
<h2 className="heading-2-mobile">
|
buttonLabelText="Enter Code"
|
||||||
Made by Attorneys, for Attorneys
|
isPromoModal={true}
|
||||||
</h2>
|
onConfirm={handleProcessPromoSubscription}
|
||||||
</div>
|
cancelButtonText="I don't have a code"
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<></>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
<div className="pad-2">
|
return isBusy ? (
|
||||||
<img
|
<LoadingSpinner message={""} loaderType="MoonLoader" />
|
||||||
src="https://imagedelivery.net/OvFc3s8IYmBw7-_bogeTLg/5f0f6f11-bb56-4f03-b05e-189d4f1a5600/public"
|
) : (
|
||||||
alt="image of a laptop computer"
|
homeContent
|
||||||
className="img-2"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="home-col-50">
|
|
||||||
<div className="pad-2">
|
|
||||||
<h2 className="heading-2">Made by Attorneys, for Attorneys</h2>
|
|
||||||
<div className="text-block-2-box">
|
|
||||||
<p className="text-block-2">
|
|
||||||
Legal tech built by people that get it.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<p className="section-two-body">
|
|
||||||
Novodraft understands the demands on your time. For example,
|
|
||||||
that discovery request on your desk. With a few clicks, and
|
|
||||||
Novodraft's AI assistant on the task, you can draft a
|
|
||||||
ready-to-serve response in minutes. It's as easy as uploading
|
|
||||||
a .pdf file.
|
|
||||||
</p>
|
|
||||||
<p className="section-two-body">
|
|
||||||
Novodraft cuts through a mire of rote tasks, but does much
|
|
||||||
more than automate.
|
|
||||||
</p>
|
|
||||||
<p className="section-two-body">
|
|
||||||
Intellidraft AI technology powers persuasive arguments and
|
|
||||||
boosts bland, boilerplate objections. Configurable for level
|
|
||||||
of authoritative citation and for infering factual context
|
|
||||||
from pleadings and briefs. Use it to augment your drafting as
|
|
||||||
much or as little as you prefer.
|
|
||||||
</p>
|
|
||||||
<div className="home-link-box">
|
|
||||||
<a className="link">
|
|
||||||
Explore Novodraft
|
|
||||||
<img src={arrow} className="img-1" alt="" />
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
{/* Section 3 */}
|
|
||||||
<section className="section-3">
|
|
||||||
<div className="section-three-header-box">
|
|
||||||
<h2 className="section-three-header">
|
|
||||||
AI-Powered Legal Drafting Technology{" "}
|
|
||||||
</h2>
|
|
||||||
<h2 className="section-three-header-mobile">
|
|
||||||
Novo Drafting Technology
|
|
||||||
</h2>
|
|
||||||
<p className="section-three-subhead">
|
|
||||||
Created by litigators to give you an edge.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div className="card-section-container">
|
|
||||||
{/*********** CARD ONE *********** */}
|
|
||||||
<div className="home-card">
|
|
||||||
<div className="card-image-container">
|
|
||||||
<img
|
|
||||||
src="https://imagedelivery.net/OvFc3s8IYmBw7-_bogeTLg/5ff0ba9e-298f-4ee1-88d4-e19a44a00900/public"
|
|
||||||
alt="ai hand"
|
|
||||||
width="100%"
|
|
||||||
className="card-image"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="card-body">
|
|
||||||
<div className="card-upper-box">
|
|
||||||
<div className="home-card-title">
|
|
||||||
<h3 className="foo-card-title">Discovery Requests</h3>
|
|
||||||
<div className="home-card-divider"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="home-card-text-box">
|
|
||||||
<p className="card-texts">
|
|
||||||
Generate discovery requests with AI at your service, edit or
|
|
||||||
add special language with tags. Concise yet comprehensive
|
|
||||||
demands, done in minutes and downloadable as .docx.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/*********** CARD TWO *********** */}
|
|
||||||
<div className="home-card">
|
|
||||||
<div className="card-image-container">
|
|
||||||
<img
|
|
||||||
src="https://imagedelivery.net/OvFc3s8IYmBw7-_bogeTLg/7a6dd50e-4d8f-4068-61b2-634dc5603f00/public"
|
|
||||||
alt="scales image"
|
|
||||||
width="100%"
|
|
||||||
className="card-image"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="card-body">
|
|
||||||
<div className="card-upper-box">
|
|
||||||
<div className="home-card-title">
|
|
||||||
<h3 className="foo-card-title">Discovery Responses</h3>
|
|
||||||
<div className="home-card-divider"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="home-card-text-box">
|
|
||||||
<p className="card-texts">
|
|
||||||
Novodraft's AI powers responses with compelling arguments
|
|
||||||
about what you choose to disclose and withhold. You'll
|
|
||||||
finish in minutes with a downloadable .docx file.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{/*********** CARD THREE *********** */}
|
|
||||||
<div className="home-card">
|
|
||||||
<div className="card-image-container">
|
|
||||||
<img
|
|
||||||
src="https://imagedelivery.net/OvFc3s8IYmBw7-_bogeTLg/00667aa1-f847-430c-7a5e-d96abeed3300/public"
|
|
||||||
alt=""
|
|
||||||
className="card-image"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="card-body">
|
|
||||||
<div className="card-upper-box">
|
|
||||||
<div className="home-card-title">
|
|
||||||
<h3 className="foo-card-title">Proactive Alerts</h3>
|
|
||||||
<div className="home-card-divider"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="home-card-text-box">
|
|
||||||
<p className="card-texts">
|
|
||||||
Your dashboard displays important deadlines, alerts, and can
|
|
||||||
configure to auto-draft documents and remind you to serve
|
|
||||||
them.
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<section className="section-5 py-5">
|
|
||||||
<div
|
|
||||||
className="home-test-container"
|
|
||||||
style={{
|
|
||||||
backgroundImage: `url(https://imagedelivery.net/OvFc3s8IYmBw7-_bogeTLg/209dcf14-c086-42b4-ca72-f058d9ad1b00/public)`,
|
|
||||||
backgroundSize: "cover",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div className="row">
|
|
||||||
<div className="col-md-6">
|
|
||||||
<div className="bottom-header-box">
|
|
||||||
<h4 className="heading-6">
|
|
||||||
Questions about our services? <br></br>
|
|
||||||
We're here to answer!
|
|
||||||
</h4>
|
|
||||||
<h4 className="heading-6-mobile">
|
|
||||||
Questions about our products and services?
|
|
||||||
</h4>
|
|
||||||
<h4 className="heading-6-mobile">We're here to answer!</h4>
|
|
||||||
</div>
|
|
||||||
<h6 className="join-heading">
|
|
||||||
Novodraft will revolutionize your practice.
|
|
||||||
</h6>
|
|
||||||
<h6 className="join-heading">
|
|
||||||
Request a demo - let us show you how.
|
|
||||||
</h6>
|
|
||||||
<h6 className="join-heading-mobile">
|
|
||||||
Revolutionize your practice.
|
|
||||||
</h6>
|
|
||||||
<h6 className="join-heading-mobile">Let us show you how.</h6>
|
|
||||||
</div>
|
|
||||||
<div className="col-md-6 d-flex">
|
|
||||||
<button className="button-2" onClick={handleDemo}>
|
|
||||||
Request a demo
|
|
||||||
</button>
|
|
||||||
<button className="button-2" onClick={handleLogin}>
|
|
||||||
Go to login
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ const ConfirmModal = ({
|
|||||||
isPromoModal,
|
isPromoModal,
|
||||||
cancelButtonText,
|
cancelButtonText,
|
||||||
}) => {
|
}) => {
|
||||||
|
const [inputValue, setInputValue] = useState("");
|
||||||
const title = titleText ? titleText : "Confirmation";
|
const title = titleText ? titleText : "Confirmation";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -53,11 +54,11 @@ const ConfirmModal = ({
|
|||||||
<TextInput
|
<TextInput
|
||||||
key={"captionTwo"}
|
key={"captionTwo"}
|
||||||
name={"captionTwo"}
|
name={"captionTwo"}
|
||||||
value={issueText}
|
value={inputValue}
|
||||||
message={"data.captionTwo.message"}
|
message={"data.captionTwo.message"}
|
||||||
onChange={(e) => setIssueText(e.target.value)}
|
onChange={(e) => setInputValue(e.target.value)}
|
||||||
label={
|
label={
|
||||||
issueText
|
inputValue
|
||||||
? ""
|
? ""
|
||||||
: isPromoModal
|
: isPromoModal
|
||||||
? "Enter your promotional code"
|
? "Enter your promotional code"
|
||||||
@@ -79,7 +80,7 @@ const ConfirmModal = ({
|
|||||||
<Button
|
<Button
|
||||||
disabled={isBusy}
|
disabled={isBusy}
|
||||||
className="primary-button"
|
className="primary-button"
|
||||||
onClick={onConfirm}
|
onClick={() => onConfirm(inputValue)}
|
||||||
labelText={buttonLabelText}
|
labelText={buttonLabelText}
|
||||||
/>
|
/>
|
||||||
</Modal.Footer>
|
</Modal.Footer>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useState, useEffect } from "react";
|
import React, { useState } from "react";
|
||||||
import Col from "react-bootstrap/Col";
|
import Col from "react-bootstrap/Col";
|
||||||
import Form from "react-bootstrap/Form";
|
import Form from "react-bootstrap/Form";
|
||||||
import Row from "react-bootstrap/Row";
|
import Row from "react-bootstrap/Row";
|
||||||
@@ -75,9 +75,9 @@ const SignupPage = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleConfirmPromoCode = () => {
|
const handleConfirmPromoCode = (code) => {
|
||||||
if (issueText === marchEmailPrm) {
|
if (code === marchEmailPrm) {
|
||||||
handlePromoSignup();
|
handlePromoSignup(code);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -467,7 +467,7 @@ const SignupPage = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handlePromoSignup = async () => {
|
const handlePromoSignup = async (code) => {
|
||||||
let dataValues = validateUserData();
|
let dataValues = validateUserData();
|
||||||
if (dataValues === null) {
|
if (dataValues === null) {
|
||||||
return;
|
return;
|
||||||
@@ -540,7 +540,8 @@ const SignupPage = () => {
|
|||||||
<h1 className="signup-header-text">Create A Novodraft Account</h1>
|
<h1 className="signup-header-text">Create A Novodraft Account</h1>
|
||||||
{!isUpgrade ? (
|
{!isUpgrade ? (
|
||||||
<h5 className="signup-header-text trial">
|
<h5 className="signup-header-text trial">
|
||||||
Start a free trial - save hours and draft smarter discovery
|
Create an account to start a free trial - save time and draft
|
||||||
|
smarter
|
||||||
</h5>
|
</h5>
|
||||||
) : (
|
) : (
|
||||||
<></>
|
<></>
|
||||||
|
|||||||
@@ -2,7 +2,13 @@ import React, { createContext, useContext, useEffect, useReducer } from "react";
|
|||||||
import { useGroupReducer } from "../useReducer/reducers";
|
import { useGroupReducer } from "../useReducer/reducers";
|
||||||
import { AuthContext } from "../../Context/AuthProvider";
|
import { AuthContext } from "../../Context/AuthProvider";
|
||||||
import { db } from "../../firebase.js";
|
import { db } from "../../firebase.js";
|
||||||
import { collection, getDocs, query, where, onSnapshot } from "firebase/firestore";
|
import {
|
||||||
|
collection,
|
||||||
|
getDocs,
|
||||||
|
query,
|
||||||
|
where,
|
||||||
|
onSnapshot,
|
||||||
|
} from "firebase/firestore";
|
||||||
|
|
||||||
const initialState = {
|
const initialState = {
|
||||||
group: undefined,
|
group: undefined,
|
||||||
@@ -16,9 +22,9 @@ const AppContext = createContext({
|
|||||||
const AppProvider = ({ children }) => {
|
const AppProvider = ({ children }) => {
|
||||||
const { currentUserEmail } = useContext(AuthContext);
|
const { currentUserEmail } = useContext(AuthContext);
|
||||||
const [appState, appDispatch] = useReducer(useGroupReducer, initialState);
|
const [appState, appDispatch] = useReducer(useGroupReducer, initialState);
|
||||||
|
console.log("currentUserEmail in AppProvider", currentUserEmail);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (typeof currentUserEmail === 'undefined') {
|
if (typeof currentUserEmail === "undefined") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!currentUserEmail) {
|
if (!currentUserEmail) {
|
||||||
@@ -26,13 +32,10 @@ const AppProvider = ({ children }) => {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
return onSnapshot(
|
return onSnapshot(
|
||||||
query(
|
query(collection(db, "users"), where("email", "==", currentUserEmail)),
|
||||||
collection(db, "users"),
|
(snapshot) => {
|
||||||
where("email", "==", currentUserEmail)
|
|
||||||
),
|
|
||||||
snapshot => {
|
|
||||||
const doc = snapshot.docs[0];
|
const doc = snapshot.docs[0];
|
||||||
if (typeof doc === 'undefined') {
|
if (typeof doc === "undefined") {
|
||||||
appDispatch({ type: "DELETE_GROUP" });
|
appDispatch({ type: "DELETE_GROUP" });
|
||||||
} else {
|
} else {
|
||||||
appDispatch({ type: "CREATE_GROUP", payload: doc.data() });
|
appDispatch({ type: "CREATE_GROUP", payload: doc.data() });
|
||||||
|
|||||||
@@ -8,6 +8,40 @@
|
|||||||
margin: 30px 0px 0px 0px;
|
margin: 30px 0px 0px 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.dash-promo-first-box {
|
||||||
|
margin-top: 8px;
|
||||||
|
padding: 8px 48px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.user-name-span {
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
.dash-promo-first-wrap {
|
||||||
|
padding: 8px 0px;
|
||||||
|
background-color: var(--barely-there-accent);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
border: 1px solid orange;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dash-promo-first-textwrap {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
margin: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dash-promo-first-text {
|
||||||
|
font-size: 0.94rem;
|
||||||
|
letter-spacing: 0.03rem;
|
||||||
|
font-family: Roboto;
|
||||||
|
font-weight: 300;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
margin-left: 16px;
|
||||||
|
width: 680px;
|
||||||
|
color: #3b3b3b;
|
||||||
|
}
|
||||||
|
|
||||||
.dash-heading-text {
|
.dash-heading-text {
|
||||||
font-size: 1.3rem;
|
font-size: 1.3rem;
|
||||||
}
|
}
|
||||||
@@ -86,6 +120,11 @@
|
|||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
}
|
}
|
||||||
|
@media only screen and (max-width: 860px) {
|
||||||
|
.dash-promo-first-text {
|
||||||
|
width: 500px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@media only screen and (max-width: 430px) {
|
@media only screen and (max-width: 430px) {
|
||||||
.dashboard-header {
|
.dashboard-header {
|
||||||
|
|||||||
@@ -131,8 +131,8 @@ section.section-1 {
|
|||||||
font-family: Roboto;
|
font-family: Roboto;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
padding: 20px 0px 10px 0px;
|
padding: 20px 0px 10px 0px;
|
||||||
font-size: 20px;
|
font-size: 19px;
|
||||||
font-weight: 100;
|
font-weight: 300;
|
||||||
max-width: 370px;
|
max-width: 370px;
|
||||||
line-height: 29px;
|
line-height: 29px;
|
||||||
text-align: justify;
|
text-align: justify;
|
||||||
@@ -163,10 +163,10 @@ h1.heading-2 {
|
|||||||
p.text-block-1 {
|
p.text-block-1 {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
font-family: Roboto;
|
font-family: Roboto;
|
||||||
font-size: 25px;
|
font-size: 26px;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
line-height: 1.6;
|
line-height: 1.5;
|
||||||
width: 525px;
|
width: 525px;
|
||||||
margin-top: 24px;
|
margin-top: 24px;
|
||||||
}
|
}
|
||||||
@@ -325,7 +325,7 @@ p.card-texts {
|
|||||||
font-family: Roboto;
|
font-family: Roboto;
|
||||||
font-size: 1.7rem;
|
font-size: 1.7rem;
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
margin-top: 8px;
|
margin-top: 2px;
|
||||||
letter-spacing: -0.007rem;
|
letter-spacing: -0.007rem;
|
||||||
color: #1f74a7;
|
color: #1f74a7;
|
||||||
}
|
}
|
||||||
@@ -362,7 +362,7 @@ p.card-title {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.home-card-text-box {
|
.home-card-text-box {
|
||||||
padding: 8px 10px 0px 10px;
|
padding: 2px 10px 0px 10px;
|
||||||
width: 270px;
|
width: 270px;
|
||||||
height: 150px;
|
height: 150px;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,6 +57,7 @@
|
|||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
width: 167px;
|
width: 167px;
|
||||||
margin-top: -2px;
|
margin-top: -2px;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.novo-logo {
|
.novo-logo {
|
||||||
|
|||||||
Reference in New Issue
Block a user