493 lines
16 KiB
JavaScript
493 lines
16 KiB
JavaScript
import { useEffect, useState } from "react";
|
||
import { collection, setDoc, doc } from "firebase/firestore";
|
||
import { db, auth } from "../../firebase";
|
||
import Button from "../../pageElements/Button";
|
||
import { v4 as uuidv4 } from "uuid";
|
||
import arrow from "../../Assets/Images/Arrow.png";
|
||
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 LoadingSpinner from "../../pageElements/LoadingSpinner";
|
||
|
||
const HomePage = () => {
|
||
const navigate = useNavigate();
|
||
const [showPromoModal, setShowPromoModal] = useState(false);
|
||
const [isBusy, setIsBusy] = useState(false);
|
||
const [notice, setNotice] = useState("");
|
||
|
||
const apiUrl =
|
||
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 tempData = {
|
||
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,
|
||
};
|
||
|
||
function scrubUndef(obj) {
|
||
Object.keys(obj).forEach(function (key) {
|
||
if (obj[key] === undefined) {
|
||
obj[key] = "---";
|
||
}
|
||
});
|
||
console.log("new object", obj);
|
||
return obj;
|
||
}
|
||
|
||
const userData = scrubUndef(tempData);
|
||
|
||
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].mspall;
|
||
if (email && password) {
|
||
handlePromoSignup(userData, email, password);
|
||
} else {
|
||
setIsBusy(false);
|
||
setShowPromoModal(false);
|
||
}
|
||
}
|
||
|
||
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;
|
||
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 = () => {
|
||
navigate("/login");
|
||
};
|
||
|
||
const handleCancelModal = () => {
|
||
setShowPromoModal(!showPromoModal);
|
||
navigate("/signup");
|
||
};
|
||
|
||
const handleDemo = () => {
|
||
const supReq = null;
|
||
navigate("/requestpage/supReq");
|
||
};
|
||
|
||
const homeContent = (
|
||
<div className="homepage-container">
|
||
<section
|
||
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={{
|
||
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>
|
||
{showPromoModal ? (
|
||
<ConfirmModal
|
||
titleText="Enter Code"
|
||
onCancel={handleCancelModal}
|
||
buttonLabelText="Enter Code"
|
||
isPromoModal={true}
|
||
onConfirm={handleProcessPromoSubscription}
|
||
cancelButtonText="I don't have a code"
|
||
/>
|
||
) : (
|
||
<></>
|
||
)}
|
||
</div>
|
||
);
|
||
|
||
return isBusy ? (
|
||
<LoadingSpinner message={""} loaderType="MoonLoader" />
|
||
) : (
|
||
homeContent
|
||
);
|
||
};
|
||
|
||
export default HomePage;
|