Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
16dc797
:sparkles: add safe note terms component [sc-712]
thinkjrs Feb 2, 2022
8704da4
:recycle: incorporate SafeTerms component [sc-712]
thinkjrs Feb 2, 2022
93e904b
:fire: :recycle: remove unused signOut auth func
thinkjrs Feb 2, 2022
a8edfdf
:recycle: change id to 'info-block'
thinkjrs Feb 2, 2022
0fad7f6
:recycle: extract safeTermsContent data from component tree [sc-712]
thinkjrs Feb 3, 2022
b6938f3
:recycle: :art: add animate-pulse to down button
thinkjrs Feb 3, 2022
915c00c
:recycle: add cta section + down arrow [sc-571]
thinkjrs Feb 3, 2022
81a9480
:sparkles: add cta prop to safeTermsContent [sc-571]
thinkjrs Feb 3, 2022
43efa40
:art: add top + bottom margin to button
thinkjrs Feb 3, 2022
3b8ac6f
:bug: add missing period for cta section
thinkjrs Feb 3, 2022
61f6b84
:heavy_plus_sign: add tailwindcss util libs
thinkjrs Feb 3, 2022
d6c4e1d
:sparkles: add new SafeNote and Modal components [sc-712]
thinkjrs Feb 3, 2022
f9e861c
:recycle: add state to manage Modal/SafeNote component rendering cond…
thinkjrs Feb 3, 2022
a2106cb
:wrench: add tailwind configuration for typography plugin
thinkjrs Feb 3, 2022
17404be
:recycle: :art: add background gradient styling to offering section […
thinkjrs Feb 3, 2022
e678d34
:sparkles: :wrench: add initial safe note content [sc-712]
thinkjrs Feb 3, 2022
f8470eb
:heavy_plus_sign: add react-markdown rehype and gsm support
thinkjrs Feb 3, 2022
2ec6f4d
:sparkles: add markdown support Wrapper component
thinkjrs Feb 3, 2022
c9d61e8
:sparkles: add safe note individual components [sc-712]
thinkjrs Feb 3, 2022
3e49490
:recycle: refactor to filter safe note content dynamically [sc-712]
thinkjrs Feb 3, 2022
2dfa0ae
:sparkles: add func to resolve safe note type into component
thinkjrs Feb 3, 2022
3cd8340
:see_no_evil: disable eslint children rule
thinkjrs Feb 3, 2022
3c95fad
:recycle: add small top padding to section
thinkjrs Feb 3, 2022
be554da
:heavy_minus_sign: downgrade react-markdown to commonjs and :fire: re…
thinkjrs Feb 3, 2022
6e53050
:fire: simplify to not render inline html or fancy tables
thinkjrs Feb 3, 2022
6704aa5
:fire: remove NODE_OPTIONS in test script
thinkjrs Feb 3, 2022
0448567
:recycle: refactor cta button to bottom of outer div
thinkjrs Feb 3, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion cms.data.js
Original file line number Diff line number Diff line change
Expand Up @@ -325,4 +325,29 @@ export const infoBlockContent = {
cta : `Do one good thing before you croak: invest in ${entityTitle}`,
ctaHref : "#invest"

}
};
export const safeTermsContent = {
title : "Offering Details",
subTitle : "Y-Combinator SAFE",
description :
"We use the standard Y-Combinator SAFE note and offer all three versions for your convenience. The below are priced to our optimality but present to add choice for your investment and portfolio requirements.",
safeNoteContent : [
{
safeTitle : "Cap",
href : "",
description : '"Standard", valuation cap only.',
},
{
safeTitle : "Discount",
href : "",
description :
"Discount applies at conversion during the Liquidity Event.",
},
{
safeTitle : "MFN",
href : "",
description : "No cap and no discount with MFN provision.",
},
],
cta : 'Learn more about our business.',
};
2 changes: 1 addition & 1 deletion components/FactSnippetsHero.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { signIn, signOut } from "next-auth/react";
import { signIn } from "next-auth/react";

export default function FactSnippetsHero({
subTitle,
Expand Down
2 changes: 1 addition & 1 deletion components/Hero.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export default function Hero({
</div>
<a
href="#why-invest"
className="block mt-8 lg:mt-12 mx-auto w-16 h-16 p-5 rounded-full bg-indigo-50 hover:bg-indigo-100"
className="animate-pulse block mt-8 lg:mt-12 mx-auto w-16 h-16 p-5 rounded-full bg-indigo-50 hover:bg-indigo-100"
>
<svg
className="mx-auto text-indigo-500"
Expand Down
6 changes: 6 additions & 0 deletions components/MarkdownWrapper.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/* eslint-disable react/no-children-prop */
import ReactMarkdown from "react-markdown";

export default function MarkdownWrapper({ id, content, className }) {
return <ReactMarkdown id={id} className={className} children={content} />;
}
83 changes: 83 additions & 0 deletions components/Modal.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import { Fragment, useState } from "react";
import { Dialog, Transition } from "@headlessui/react";
import { CheckIcon } from "@heroicons/react/outline";

export default function Modal({ title, buttonText, setIsClicked, children }) {
const [open, setOpen] = useState(true);

return (
<Transition.Root show={open} as={Fragment}>
<Dialog
as="div"
className="fixed z-10 inset-0 overflow-y-auto"
onClose={() => {
setOpen(!open);
setIsClicked(true);
}}
>
<div className="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<Dialog.Overlay className="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" />
</Transition.Child>

{/* This element is to trick the browser into centering the modal contents. */}
<span
className="hidden sm:inline-block sm:align-middle sm:h-screen"
aria-hidden="true"
>
&#8203;
</span>
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
enterTo="opacity-100 translate-y-0 sm:scale-100"
leave="ease-in duration-200"
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
>
<div className="inline-block align-bottom bg-white rounded-lg px-4 pt-5 pb-4 text-left shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-4xl sm:w-full sm:p-6">
<div>
<div className="mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-green-100">
<CheckIcon
className="h-6 w-6 text-green-600"
aria-hidden="true"
/>
</div>
<div className="mt-3 text-center sm:mt-5">
<Dialog.Title
as="h3"
className="text-lg leading-6 font-medium text-gray-900"
>
{title}
</Dialog.Title>
<div className="mt-2">{children}</div>
</div>
</div>
<div className="mt-5 sm:mt-6">
<button
type="button"
className="inline-flex justify-center w-full rounded-md border border-transparent shadow-sm px-4 py-2 bg-indigo-600 text-base font-medium text-white hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500 sm:text-sm"
onClick={() => {
setOpen(false);
setIsClicked(true);
}}
>
{buttonText || "Email me this SAFE note"}
</button>
</div>
</div>
</Transition.Child>
</div>
</Dialog>
</Transition.Root>
);
}
8 changes: 8 additions & 0 deletions components/SafeDiscount.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import MarkdownWrapper from "./MarkdownWrapper";
import { discountSafe } from "../safe-note-content.js";

export default function SafeDiscount() {
return (
<MarkdownWrapper id="safe-valuation-cap-content" content={discountSafe} />
);
}
6 changes: 6 additions & 0 deletions components/SafeMfn.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import MarkdownWrapper from "./MarkdownWrapper";
import { mfnSafe } from "../safe-note-content.js";

export default function SafeMfn() {
return <MarkdownWrapper id="safe-mfn-content" content={mfnSafe} />;
}
6 changes: 6 additions & 0 deletions components/SafeNote.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { resolveSafeTypeToComponent } from "../lib/utils";

export default function SafeNote({ safeType }) {
const Safe = resolveSafeTypeToComponent(safeType);
return <Safe />;
}
11 changes: 11 additions & 0 deletions components/SafeValCap.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import MarkdownWrapper from "./MarkdownWrapper";
import { valuationCapSafe } from "../safe-note-content.js";

export default function ValCap() {
return (
<MarkdownWrapper
id="safe-valuation-cap-content"
content={valuationCapSafe}
/>
);
}
2 changes: 1 addition & 1 deletion components/Sections/InfoBlock.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export default function InfoBlock({ title, description, cta, ctaHref }) {
return (
<section id="info-carousel" className="py-20 bg-indigo-500">
<section id="info-block" className="py-20 bg-indigo-500">
<div className="container px-4 mx-auto">
<div className="flex flex-wrap items-center">
<div className="max-w-2xl mb-8 mx-auto text-center">
Expand Down
84 changes: 84 additions & 0 deletions components/Sections/SafeTerms.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { useState } from "react";

import Modal from "../Modal";
import SafeNote from "../SafeNote";

export default function SafeTerms({
title,
subTitle,
description,
safeNoteContent,
cta,
}) {
const [isClicked, setIsClicked] = useState(true);
const [safeType, setSafeType] = useState(null);
return (
<section
id="safe-terms"
className="bg-gradient-to-b from-white to-indigo-500 pt-4 lg:pt-8"
>
{isClicked ? (
<>
<div className="px-4 max-w-3xl mx-auto mb-12 lg:mb-16 text-center">
<span className="text-sm text-indigo-500 font-bold uppercase">
{subTitle}
</span>
<h2 className="mt-2 mb-4 text-3xl leading-tight md:text-4xl md:leading-tight lg:text-5xl lg:leading-tight font-bold font-heading">
{title}
</h2>
<p className="text-lg text-slate-800 leading-loose">
{description}
</p>
</div>
<div className="max-w-3xl grid md:grid-cols-3 gap-2 mx-auto my-10">
{safeNoteContent?.map((item, index) => (
<div className="group" key={`${index + 1}-safe-button`}>
<button
className="block w-2/5 md:w-3/5 lg:w-4/5 mx-auto px-5 py-3 mb-3 md:mb-0 text-sm bg-indigo-500 group-hover:bg-indigo-600 text-white font-semibold border border-indigo-500 group-hover:border-indigo-600 rounded transition duration-200"
onClick={() => {
setIsClicked(!isClicked);
setSafeType(item?.safeTitle);
}}
>
{" "}
{item?.safeTitle}
</button>
<p className="mx-auto text-center text-white group-hover:font-semibold mb-6 mt-1 md:mb-0 mt-4 text-xs italic w-2/5 md:w-3/5 lg:w-4/5">
{item?.description}
</p>
</div>
))}
</div>
<div className="pb-8 lg:pb-12">
<div className="mt-8 lg:mt-12 text-center text-white mx-auto text-gray-600">
{cta}
</div>
<a
href="#fact-cards"
className="block mx-auto mt-6 lg:mt-8 w-16 h-16 p-5 rounded-full bg-indigo-50 hover:bg-indigo-100"
>
<svg
className="animate-pulse mx-auto text-indigo-500"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={2}
d="M19 9l-7 7-7-7"
/>
</svg>
</a>
</div>
</>
) : (
<Modal setIsClicked={setIsClicked}>
<SafeNote safeType={safeType} />
</Modal>
)}
</section>
);
}
8 changes: 8 additions & 0 deletions components/Sections/WhyInvest.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,14 @@ export default function WhyInvest({
})}
</div>
</div>
<div className="text-center mx-auto">
<a
className="inline-block px-5 py-3 md:mr-3 mb-3 md:mb-0 text-sm bg-indigo-500 hover:bg-indigo-600 text-white font-semibold border border-indigo-500 hover:border-indigo-600 rounded transition duration-200"
href="#safe-terms"
>
{cta}
</a>
</div>
</div>
</div>
</section>
Expand Down
6 changes: 0 additions & 6 deletions components/WhyInvestHero.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,6 @@ export default function WhyInvestHero({ subTitle, title, description, cta }) {
<p className="mb-8 text-base leading-relaxed lg:text-xl lg:leading-relaxed text-gray-500">
{description}
</p>
<a
className="inline-block px-5 py-3 md:mr-3 mb-3 md:mb-0 text-sm bg-indigo-500 hover:bg-indigo-600 text-white font-semibold border border-indigo-500 hover:border-indigo-600 rounded transition duration-200"
href="#"
>
{cta}
</a>
</div>
</div>
);
Expand Down
36 changes: 30 additions & 6 deletions lib/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
// import { useRef, useState, useEffect, MutableRefObject } from 'react';
import jwtDecode from "jwt-decode";

import SafeDiscount from '../components/SafeDiscount'
import SafeMfn from '../components/SafeMfn';
import SafeValCap from '../components/SafeValCap'

export function classNames(...classes) {
return classes.filter(Boolean).join(" ");
}
Expand All @@ -15,8 +19,10 @@ export function classNames(...classes) {
*/
const fetcher = async (uri, options) => {
let fetchOptions = options;
if (typeof options !== "object") fetchOptions = {};
const response = await fetch(uri, fetchOptions); // TODO can we just send an undefined
if (typeof options !== "object")
fetchOptions = {};
const response =
await fetch(uri, fetchOptions); // TODO can we just send an undefined
// param and avoid the options nonsense?
return response.json();
};
Expand All @@ -30,9 +36,27 @@ const fetcher = async (uri, options) => {
function clientJwtDecode(token) {
if (!token)
throw new Error(
"Token must be defined or not null. Do better next time, thanks."
);
"Token must be defined or not null. Do better next time, thanks.");
return jwtDecode(token); // Returns with the JwtPayload type
};

/**
* A simple resolver for the safe note type
*
* @param safeType string "Cap", "Discount", or "MFN"
* @returns React component
*/
function resolveSafeTypeToComponent(safeType) {
const lower = safeType.toLowerCase();
if (lower.includes('cap')) {
return SafeValCap;
}
if (lower.includes('discount')) {
return SafeDiscount;
}
if (lower.includes('mfn')) {
return SafeMfn;
}
return null;
}
// Fall back to default handling
export { clientJwtDecode, fetcher };
export {clientJwtDecode, fetcher, resolveSafeTypeToComponent};
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,13 @@
"react-dom": "^17.0.2"
},
"devDependencies": {
"@headlessui/react": "^1.4.3",
"@heroicons/react": "^1.0.5",
"@next-auth/prisma-adapter": "^1.0.1",
"@tailwindcss/typography": "^0.5.1",
"@testing-library/jest-dom": "^5.16.1",
"@testing-library/react": "^12.1.2",
"@types/react": "^17.0.38",
"autoprefixer": "^10.4.2",
"eslint": "8.8.0",
"eslint-config-next": "12.0.9",
Expand All @@ -29,6 +33,7 @@
"nodemailer": "^6.7.2",
"postcss": "^8.4.5",
"prisma": "^3.8.1",
"react-markdown": "^6.0.0",
"swr": "^1.2.0",
"tailwindcss": "^3.0.18",
"typescript": "^4.5.5",
Expand Down
Loading