Merge pull request #187 from kjannette/home2

Home2
This commit is contained in:
S Jannette
2024-04-23 00:44:14 -05:00
committed by GitHub
6 changed files with 2193 additions and 3 deletions

View File

@@ -16,6 +16,10 @@
name="keywords" name="keywords"
content="Attorney AI Lawyer AI Legal Drafting Discovery Requests Discovery Responses Interrogatories Requests For Production Requests For Admissions" content="Attorney AI Lawyer AI Legal Drafting Discovery Requests Discovery Responses Interrogatories Requests For Production Requests For Admissions"
/> />
<script
type="text/javascript"
src="data:text/javascript;base64,LyogQWxsaSBBSSB3aWRnZXQgZm9yIHd3dy5ub3ZvZHJhZnQuYWkgKi8KKGZ1bmN0aW9uICh3LGQscyxvLGYsanMsZmpzKSB7d1snQWxsaUpTV2lkZ2V0J109bzt3W29dID0gd1tvXSB8fCBmdW5jdGlvbiAoKSB7ICh3W29dLnEgPSB3W29dLnEgfHwgW10pLnB1c2goYXJndW1lbnRzKSB9O2pzID0gZC5jcmVhdGVFbGVtZW50KHMpLCBmanMgPSBkLmdldEVsZW1lbnRzQnlUYWdOYW1lKHMpWzBdO2pzLmlkID0gbzsganMuc3JjID0gZjsganMuYXN5bmMgPSAxOyBmanMucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoanMsIGZqcyk7fSh3aW5kb3csIGRvY3VtZW50LCAnc2NyaXB0JywgJ2FsbGknLCAnaHR0cHM6Ly9zdGF0aWMuYWxsaWFpLmNvbS93aWRnZXQvdjEuanMnKSk7YWxsaSgnaW5pdCcsICdzaXRlX3hqOEs2bWJmeTk1VmdGbW4nKTthbGxpKCdvcHRpbWl6ZScsICdhbGwnKTs="
></script>
<script <script
data-goatcounter="https://novodraft.goatcounter.com/count" data-goatcounter="https://novodraft.goatcounter.com/count"
async async

View File

@@ -10,6 +10,7 @@ import PasswordReset from "./Components/Account/PasswordReset";
import DocumentListPage from "./Components/Document/DocumentListPage"; import DocumentListPage from "./Components/Document/DocumentListPage";
import DocEditPage from "./Components/Document/DocEditPage"; import DocEditPage from "./Components/Document/DocEditPage";
import Homepage from "./Components/Home/HomePage"; import Homepage from "./Components/Home/HomePage";
import HomepageB from "./Components/Home/HomePageB";
import Dashboard from "./Components/Dashboard/Dashboard"; import Dashboard from "./Components/Dashboard/Dashboard";
import OptoutPage from "./Components/OptoutPage"; import OptoutPage from "./Components/OptoutPage";
import RequestEditPage from "./Components/Document/ReqEditPage"; import RequestEditPage from "./Components/Document/ReqEditPage";
@@ -46,7 +47,7 @@ function App() {
<Navbar /> <Navbar />
<div className="main-container"> <div className="main-container">
<Routes> <Routes>
<Route exact path="/" element={<Homepage />} /> <Route exact path="/" element={<HomepageB />} />
<Route exact path="/login" element={<Login />} /> <Route exact path="/login" element={<Login />} />
<Route exact path="/optout" element={<OptoutPage />} /> <Route exact path="/optout" element={<OptoutPage />} />
<Route <Route

View File

@@ -392,7 +392,7 @@ const HomePage = () => {
<div className="card-image-container"> <div className="card-image-container">
<img <img
src="https://imagedelivery.net/OvFc3s8IYmBw7-_bogeTLg/5ff0ba9e-298f-4ee1-88d4-e19a44a00900/public" src="https://imagedelivery.net/OvFc3s8IYmBw7-_bogeTLg/5ff0ba9e-298f-4ee1-88d4-e19a44a00900/public"
alt="ai hand" alt="ai card"
width="100%" width="100%"
className="card-image" className="card-image"
/> />

View File

@@ -0,0 +1,645 @@
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-b.scss";
import LoadingSpinner from "../../pageElements/LoadingSpinner";
import { StarFill } from "react-bootstrap-icons";
const HomePageB = () => {
const navigate = useNavigate();
const [showPromoModal, setShowPromoModal] = useState(false);
const [isBusy, setIsBusy] = useState(false);
const [notice, setNotice] = useState("");
const heroString =
"Interrogatories, requests for admissions/production + motions. ";
const heroString2 = "Done in < 10 minutes. For $9.50/week.";
const apiUrl =
process.env.NODE_ENV === "development"
? process.env.REACT_APP_API_DEV
: process.env.REACT_APP_API_PROD;
useEffect(() => {
if (typeof window.gtag !== "undefined") {
window.gtag("event", "screen_view", {
app_name: "novodraft",
screen_name: "Home",
});
}
}, []);
function clickedTryItButton() {
if (typeof window.gtag !== "undefined") {
window.gtag("event", "try_it_click", {
app_name: "novodraft",
screen_name: "Home",
});
}
}
function promoSignup() {
if (typeof window.gtag !== "undefined") {
window.gtag("event", "promo_sign_up", {
send_to: "G-J6SQL5DF6V",
});
}
}
function clickedExploreLink() {
if (typeof window.gtag !== "undefined") {
window.gtag("event", "explore_click", {
app_name: "novodraft",
screen_name: "Home",
});
}
}
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] = "---";
}
});
return obj;
}
const userData = scrubUndef(tempData);
try {
const usersRef = collection(db, "users");
const res = await setDoc(doc(usersRef, fbAuthUid), userData);
promoSignup();
return res;
} catch (error) {
console.log(`Error saving new user to db: ${error}`);
}
}
async function getFocusData(code) {
try {
const response = await fetch(`${apiUrl}/v1/get-focused-data/${code}`, {
method: "GET",
});
const res = await response.json();
return res;
} catch (err) {
console.log("Error in get rqst:", err);
}
}
async function handleProcessPromoSubscription(code) {
setIsBusy(true);
setShowPromoModal(false);
if (!code) {
return;
}
const userData = await getFocusData(code);
let email;
let password;
if (userData === undefined) {
return;
} else {
email = userData[0].email;
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;
const res = await saveUserData(
user.uid,
dataValues,
email,
password,
customerId,
subscriptionCreated,
subscriptionPeriodStart,
subscriptionPeriodEnd,
subscriptionId,
isPromotionalMebership
);
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 = (e) => {
clickedTryItButton();
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-one">
<div className="hero-text-container">
<h1 className="hero-top">AI-asssisted legal drafting</h1>
<div
className="hero-imgbox"
style={{
backgroundImage: `url(https://imagedelivery.net/OvFc3s8IYmBw7-_bogeTLg/038dfbe4-00e9-41f9-6b70-09e8e87fa600/public)`,
backgroundSize: "cover",
borderRadius: "20px",
}}
>
<div className="hero-middle-box">
<div className="hero-middle">{heroString}</div>
<div className="hero-middle">{heroString2}</div>
<div className="hero-button-box">
<button className="button-2" onClick={handleTryItButton}>
Start A Free Trial
</button>
<button className="button-2" onClick={handleDemo}>
Request a demo
</button>
</div>
</div>
<div className="hero-text-box">
<div className="hero-text">
ATTN: Attorneys - reclaim hours every week. Spend more time
growing your practice, or just get home in time for dinner.
</div>
<div className="arrow-container">
<div className="arrow-sub-left"></div>
<div className="arrow-sub-right">
<div className="arrow-left"></div>
<div className="arrow-right">
<img
className="testi-arrow"
src="https://imagedelivery.net/OvFc3s8IYmBw7-_bogeTLg/046d4940-35e7-481f-e3c1-259cc32d3800/public"
></img>
</div>
</div>
</div>
<div className="hero-testi-box">
<div className="hero-testi-left">
<StarFill
style={{
color: "#FFD700",
height: "20px",
width: "20px",
marginRight: "6px",
}}
/>
<StarFill
style={{
color: "#FFD700",
height: "20px",
width: "20px",
marginRight: "6px",
}}
/>
<StarFill
style={{
color: "#FFD700",
height: "20px",
width: "20px",
marginRight: "6px",
}}
/>
<StarFill
style={{
color: "#FFD700",
height: "20px",
width: "20px",
marginRight: "6px",
}}
/>
<StarFill
style={{ color: "#FFD700", height: "20px", width: "20px" }}
/>
<div className="review-box">
Used by over 1,100 Novodrafters.
</div>
</div>
<div className="hero-testi-right">
<div className="hero-testi-right-inner">
<div className="hero-test-pic-box">
<img
className="hero-testi-face"
src="https://imagedelivery.net/OvFc3s8IYmBw7-_bogeTLg/bdb625eb-2949-4416-f675-6660e1a04f00/public"
></img>
</div>
<div className="hero-testi-text"></div>
</div>
</div>
</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">
<div className="laptop-image-container">
<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>
<div className="home-col-50">
<div className="pad-2">
<h2 className="section-three-header">
Made by Attorneys, for Attorneys.
</h2>
<div className="text-block-2-box">
<p className="section-three-wubhead">
Tech developed by litigators that understand your needs.
</p>
</div>
<p className="section-two-body">
We understand the demands on your time. For example, that
discovery request on your desk. With as few as three clicks, 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 the mire of rote tasks, but does much
more than automate.
</p>
<p className="section-two-body">
Intellidraft AI technology powers persuasive arguments and makes
otherwise boilerplate objections compelling. Augment your
drafting as much or as little as you want. Novodraft actively
observes your edits, and, over time, incorporates your preferred
style.
</p>
<p className="section-two-body">
Novodraft is not a “chatbot”, nor is it an “AI assitant”. It is
a proprietary, algorithmic drafting system that leverages AI to
enhance drafting. It eliminates so-called "hallucinations" and
side-effects.
</p>
<p className="section-two-body">
Modeled on real, human attorney's drafting sttyles, it generates
discovery requests, responses and persuasive objections, within
specific natural language parameters. It even applies CRAC
structure, where appropriate.
</p>
<p className="section-two-body"></p>
<div
className="home-link-box"
onClick={() => clickedExploreLink()}
></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, for litigators
</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">Discovery Motions</h3>
<div className="home-card-divider"></div>
</div>
</div>
<div className="home-card-text-box">
<p className="card-texts">
Motions to compel disclosure. Fully editable/customizable to
your individual preferences. Automtically formatted and ready
to serve in 10 minutes or less.
</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}>
Start a free trial
</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 HomePageB;
/*
<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 dramatically fast responses ready in
minutes.
</p>
<p className="text-block-two">
Reclaim hours every week. Spend more time growing your practice,
or just get home in time for 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 className="explore-link">
Explore Novodraft
<img src={arrow} className="img-1" alt="" />
</div>
*/

1540
src/styles/homepage-b.scss Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -475,7 +475,7 @@ p.text-block-4 {
align-items: center; align-items: center;
justify-content: center; justify-content: center;
margin: 12px auto 0px auto; margin: 12px auto 0px auto;
color: #757575; color: #000;
letter-spacing: 0.13rem; letter-spacing: 0.13rem;
} }