-
Notifications
You must be signed in to change notification settings - Fork 1
Update navigation and hero components with new messaging and links #55
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,44 +1,21 @@ | ||
| 'use client'; | ||
| import { zodResolver } from '@hookform/resolvers/zod'; | ||
| import { FC, useState, FormEvent, startTransition, useActionState, useRef } from 'react'; | ||
| import { useForm } from 'react-hook-form'; | ||
| import { formSchema } from '../utils/waitlist/schema'; | ||
| import { submitWaitlistForm } from '../utils/waitlist/action'; | ||
| import * as z from 'zod'; | ||
|
|
||
| type FormValues = z.infer<typeof formSchema>; | ||
| import { FC } from 'react'; | ||
| import { Chrome, Github } from 'lucide-react'; | ||
| import { CHROME_STORE_URL, GITHUB_REPO_URL } from '../utils/constant'; | ||
|
|
||
| export const CTA: FC = () => { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Cleanup — unused npm dependencies. With the waitlist form removed, these
Keeping unused dependencies inflates install time and bundle size.
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. They will be reused later |
||
| const [email, setEmail] = useState<string>(''); | ||
| const [submitted, setSubmitted] = useState<boolean>(false); | ||
| const [, formAction] = useActionState(submitWaitlistForm, { message: '' }); | ||
|
|
||
| const form = useForm<FormValues>({ | ||
| resolver: zodResolver(formSchema), | ||
| defaultValues: { email: '' }, | ||
| }); | ||
|
|
||
| const formRef = useRef<HTMLFormElement>(null); | ||
|
|
||
| const handleSubmit = (e: FormEvent<HTMLFormElement>): void => { | ||
| e.preventDefault(); | ||
| startTransition(() => { | ||
| formAction(new FormData(formRef.current!)); | ||
| form.reset(); | ||
| }); | ||
| setSubmitted(true); | ||
| }; | ||
|
|
||
| return ( | ||
| <section className="py-36 px-6 md:px-12 relative overflow-hidden bg-ink" id="get-access"> | ||
| <section | ||
| className="py-36 px-6 md:px-12 relative overflow-hidden bg-ink" | ||
| id="install" | ||
| > | ||
| <div className="absolute inset-0 grid-bg opacity-70" /> | ||
| <div className="absolute top-0 left-0 right-0 h-px bg-edge" /> | ||
|
|
||
| <div className="relative max-w-xl mx-auto text-center"> | ||
| <div className="inline-flex items-center gap-2 border border-edge bg-ink2/80 px-4 py-1.5 mb-10 rounded-full"> | ||
| <span className="w-1.5 h-1.5 rounded-full bg-amber animate-blink" /> | ||
| <span className="w-1.5 h-1.5 rounded-full bg-emerald-400 animate-blink" /> | ||
| <span className="font-mono text-[10px] tracking-[0.18em] uppercase text-fog"> | ||
| Early access open | ||
| Available now — free | ||
| </span> | ||
| </div> | ||
|
|
||
|
|
@@ -49,45 +26,31 @@ export const CTA: FC = () => { | |
| </h2> | ||
|
|
||
| <p className="text-[14px] text-mist mb-10 leading-relaxed font-body"> | ||
| Be among the first to bring persistent memory to every AI you use. | ||
| Install the extension and bring persistent memory to every AI you use. | ||
| <br className="hidden md:block" /> | ||
| No credit card. No setup fees. | ||
| Free, open-source, takes 30 seconds. | ||
| </p> | ||
|
|
||
| {!submitted ? ( | ||
| <form | ||
| ref={formRef} | ||
| onSubmit={handleSubmit} | ||
| className="flex flex-col sm:flex-row gap-3 max-w-sm mx-auto" | ||
| <div className="flex flex-col sm:flex-row items-center justify-center gap-4"> | ||
| <a | ||
| href={CHROME_STORE_URL} | ||
| target="_blank" | ||
| rel="noopener noreferrer" | ||
| className="inline-flex items-center gap-2.5 bg-amber text-white px-7 py-3.5 text-[12px] tracking-widest uppercase font-medium hover:bg-amber/90 transition-colors rounded-sm" | ||
| > | ||
| <input | ||
| type="email" | ||
| name="email" | ||
| value={email} | ||
| onChange={(e) => setEmail(e.target.value)} | ||
| placeholder="your@email.com" | ||
| className="flex-1 bg-ink2 border border-edge text-cream placeholder:text-fog px-4 py-3 text-[13px] font-body focus:outline-none focus:border-amber/40 transition-colors rounded-sm" | ||
| required | ||
| /> | ||
| <button | ||
| type="submit" | ||
| className="bg-amber text-white px-7 py-3 text-[11px] tracking-widest uppercase font-medium hover:bg-amber/90 transition-colors whitespace-nowrap rounded-sm" | ||
| > | ||
| Get Access | ||
| </button> | ||
| </form> | ||
| ) : ( | ||
| <div className="flex items-center justify-center gap-3 border border-edge bg-ink2/80 px-8 py-4 max-w-sm mx-auto animate-fade-in rounded-sm"> | ||
| <span className="text-amber">✦</span> | ||
| <span className="font-mono text-[12px] text-mist"> | ||
| You're on the list. We'll be in touch. | ||
| </span> | ||
| </div> | ||
| )} | ||
|
|
||
| <p className="mt-8 font-mono text-[10px] text-fog tracking-wide"> | ||
| Built with Go · Qdrant · PostgreSQL · MCP | ||
| </p> | ||
| <Chrome size={20} strokeWidth={1.75} /> | ||
| Add to Chrome | ||
| </a> | ||
| <a | ||
| href={GITHUB_REPO_URL} | ||
| target="_blank" | ||
| rel="noopener noreferrer" | ||
| className="inline-flex items-center gap-2.5 border border-edge bg-ink2/60 text-cream px-7 py-3.5 text-[12px] tracking-widest uppercase font-medium hover:bg-ink2 hover:border-edge2 transition-colors rounded-sm" | ||
| > | ||
| <Github size={18} strokeWidth={1.75} /> | ||
| Star on GitHub | ||
| </a> | ||
| </div> | ||
| </div> | ||
| </section> | ||
| ); | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,8 @@ | ||
| 'use client'; | ||
| import { FC, useState } from 'react'; | ||
| import { Chrome } from 'lucide-react'; | ||
| import { useScrolled } from '../utils/customState'; | ||
| import { CHROME_STORE_URL, GITHUB_REPO_URL } from '../utils/constant'; | ||
|
|
||
| export const Nav: FC = () => { | ||
| const scrolled = useScrolled(); | ||
|
|
@@ -19,7 +21,7 @@ export const Nav: FC = () => { | |
|
|
||
| <div className="hidden md:flex items-center gap-4"> | ||
| <a | ||
| href="https://github.com/freedisch/havril" | ||
| href={GITHUB_REPO_URL} | ||
| target="_blank" | ||
| rel="noopener noreferrer" | ||
| aria-label="View on GitHub" | ||
|
|
@@ -41,10 +43,13 @@ export const Nav: FC = () => { | |
| </svg> | ||
| </a> | ||
| <a | ||
| href="#get-access" | ||
| className="text-[11px] tracking-widest uppercase bg-amber text-white px-5 py-2.5 font-medium hover:bg-amber/90 transition-colors rounded-sm" | ||
| href={CHROME_STORE_URL} | ||
| target="_blank" | ||
| rel="noopener noreferrer" | ||
| className="inline-flex items-center gap-2 text-[11px] tracking-widest uppercase bg-amber text-white px-5 py-2.5 font-medium hover:bg-amber/90 transition-colors rounded-sm" | ||
| > | ||
| Get Early Access | ||
| <Chrome size={16} strokeWidth={1.75} /> | ||
| Add to Chrome | ||
| </a> | ||
| </div> | ||
|
|
||
|
|
@@ -66,7 +71,7 @@ export const Nav: FC = () => { | |
| {menuOpen && ( | ||
| <div className="absolute top-full left-0 right-0 bg-ink border-b border-edge p-8 flex flex-col gap-6 md:hidden"> | ||
| <a | ||
| href="https://github.com/freedisch/havril" | ||
| href={GITHUB_REPO_URL} | ||
| target="_blank" | ||
| rel="noopener noreferrer" | ||
| className="text-[11px] tracking-widest uppercase text-mist hover:text-cream transition-colors" | ||
|
|
@@ -83,8 +88,15 @@ export const Nav: FC = () => { | |
| > | ||
| X / Twitter | ||
| </a> | ||
| <a href="#get-access" className="text-[11px] uppercase bg-amber text-white px-5 py-3 font-medium text-center rounded-sm"> | ||
| Get Early Access | ||
| <a | ||
| href={CHROME_STORE_URL} | ||
| target="_blank" | ||
| rel="noopener noreferrer" | ||
| onClick={() => setMenuOpen(false)} | ||
| className="inline-flex items-center justify-center gap-2 text-[11px] uppercase bg-amber text-white px-5 py-3 font-medium text-center rounded-sm" | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Styling inconsistency — mobile CTA missing |
||
| > | ||
| <Chrome size={16} strokeWidth={1.75} /> | ||
| Add to Chrome | ||
| </a> | ||
| </div> | ||
| )} | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| export const CHROME_STORE_URL = | ||
| 'https://chromewebstore.google.com/detail/jjlelibnopjfeefpdplponpnocjfcega?utm_source=item-share-cb'; | ||
| export const GITHUB_REPO_URL = 'https://github.com/freedisch/havril'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Bug — dead code left behind: The waitlist form was the only consumer of
app/utils/waitlist/action.tsandapp/utils/waitlist/schema.ts. These files are now completely unreferenced dead code and should be deleted.Similarly,
components/ui/form.tsx(a shadcn/ui form component) importsreact-hook-formbut is no longer imported anywhere in the codebase — also dead code.