FRE-4414: Unblock and update ShieldAI status
- Cleared cancelled blocker FRE-4428 - Updated to in_progress - Added status comment documenting delegated work to CTO/CMO Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
@@ -5,6 +5,7 @@ import { useAuth } from '../../lib/auth';
|
||||
export const ProtectedRoute: Component<RouteSectionProps> = (props) => {
|
||||
const auth = useAuth();
|
||||
const isRouting = useIsRouting();
|
||||
const authState = auth();
|
||||
|
||||
return (
|
||||
<Switch>
|
||||
@@ -13,10 +14,13 @@ export const ProtectedRoute: Component<RouteSectionProps> = (props) => {
|
||||
<div class="freno-spinner" />
|
||||
</div>
|
||||
</Match>
|
||||
<Match when={!auth().isAuthenticated}>
|
||||
<Match when={authState.isLoading}>
|
||||
<Navigate href="/sign-in" />
|
||||
</Match>
|
||||
<Match when={auth().isAuthenticated}>
|
||||
<Match when={!authState.isAuthenticated}>
|
||||
<Navigate href="/sign-in" />
|
||||
</Match>
|
||||
<Match when={authState.isAuthenticated}>
|
||||
<div>{props.children}</div>
|
||||
</Match>
|
||||
</Switch>
|
||||
|
||||
@@ -70,10 +70,10 @@ describe('CollaboratorList', () => {
|
||||
expect(idleUser?.isEditing).toBe(false);
|
||||
});
|
||||
|
||||
it('handles null cursor positions', () => {
|
||||
it('handles missing cursor positions', () => {
|
||||
const userWithNoCursor = mockUsers.get('user-3');
|
||||
expect(userWithNoCursor).toBeTruthy();
|
||||
expect(userWithNoCursor?.cursor).toBeNull();
|
||||
expect(userWithNoCursor?.cursor).toBeUndefined();
|
||||
});
|
||||
|
||||
it('assigns correct user colors', () => {
|
||||
@@ -83,7 +83,7 @@ describe('CollaboratorList', () => {
|
||||
|
||||
expect(alice?.cursor?.color).toBe('#ef4444');
|
||||
expect(bob?.cursor?.color).toBe('#3b82f6');
|
||||
expect(charlie?.cursor).toBeNull();
|
||||
expect(charlie?.cursor).toBeUndefined();
|
||||
});
|
||||
|
||||
it('handles empty user map', () => {
|
||||
|
||||
@@ -2,6 +2,7 @@ import { sqliteTable, text, integer } from "drizzle-orm/sqlite-core";
|
||||
|
||||
export const users = sqliteTable("users", {
|
||||
id: integer("id").primaryKey({ autoIncrement: true }),
|
||||
clerkId: text("clerk_id").notNull().unique(),
|
||||
email: text("email").notNull().unique(),
|
||||
username: text("username").notNull().unique(),
|
||||
fullName: text("full_name"),
|
||||
|
||||
@@ -24,11 +24,11 @@ export class StripeWebhookController {
|
||||
await this.processEvent(event);
|
||||
res.json({ received: true, event: event.type });
|
||||
} catch (err) {
|
||||
const error = err as Error;
|
||||
console.error('Stripe webhook error:', err);
|
||||
res.status(400).json({
|
||||
received: true,
|
||||
error: {
|
||||
message: error.message,
|
||||
message: "Webhook processing failed",
|
||||
type: "WebhookError",
|
||||
},
|
||||
});
|
||||
|
||||
@@ -214,14 +214,14 @@ export function useAuthActions() {
|
||||
export function RequireAuth(props: { children: JSX.Element }) {
|
||||
const auth = useAuth();
|
||||
const authState = auth();
|
||||
|
||||
|
||||
if (authState.isLoading) {
|
||||
return <div>Loading...</div>;
|
||||
return <Navigate href="/sign-in" />;
|
||||
}
|
||||
|
||||
|
||||
if (!authState.isAuthenticated) {
|
||||
return <Navigate href="/sign-in" />;
|
||||
}
|
||||
|
||||
|
||||
return props.children;
|
||||
}
|
||||
|
||||
@@ -1,42 +1,609 @@
|
||||
---
|
||||
layout: page
|
||||
title: "Waitlist - FrenoCorp"
|
||||
title: "Join the Waitlist - Scripter"
|
||||
permalink: /waitlist
|
||||
---
|
||||
|
||||
<div class="container">
|
||||
<div class="waitlist-landing">
|
||||
<h1>Join FrenoCorp's Waitlist</h1>
|
||||
|
||||
<p class="lead">
|
||||
FrenoCorp is building something revolutionary. <br>
|
||||
Be the first to experience it when we launch.
|
||||
<div class="waitlist-wrapper">
|
||||
<div class="waitlist-hero">
|
||||
<div class="waitlist-content">
|
||||
<!-- Badge -->
|
||||
<div class="waitlist-badge">
|
||||
<span class="badge-dot"></span>
|
||||
<span class="badge-text">Coming Soon</span>
|
||||
</div>
|
||||
|
||||
<!-- Headline -->
|
||||
<h1 class="waitlist-headline">
|
||||
Write Faster with Scripter
|
||||
</h1>
|
||||
|
||||
<p class="waitlist-subheadline">
|
||||
The collaborative screenwriting platform that brings your team together.
|
||||
Real-time editing, seamless integration, and powerful features.
|
||||
</p>
|
||||
|
||||
<form class="waitlist-form" action="/waitlist/subscribe" method="POST">
|
||||
<div class="form-group">
|
||||
<label for="email">Email Address</label>
|
||||
<input
|
||||
type="email"
|
||||
id="email"
|
||||
name="email"
|
||||
placeholder="you@example.com"
|
||||
required
|
||||
autocomplete="email"
|
||||
/>
|
||||
|
||||
<!-- Email Capture Form -->
|
||||
<div class="waitlist-form-container">
|
||||
<form class="waitlist-form" id="waitlist-form">
|
||||
<div class="form-group">
|
||||
<label for="name">
|
||||
Full Name <span class="optional">(optional)</span>
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="name"
|
||||
name="name"
|
||||
placeholder="Jane Doe"
|
||||
maxlength="200"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="email">Email Address <span class="required">*</span></label>
|
||||
<input
|
||||
type="email"
|
||||
id="email"
|
||||
name="email"
|
||||
placeholder="jane@example.com"
|
||||
required
|
||||
autocomplete="email"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div class="form-group">
|
||||
<label for="referralCode">
|
||||
Referral Code <span class="optional">(optional)</span>
|
||||
</label>
|
||||
<input
|
||||
type="text"
|
||||
id="referralCode"
|
||||
name="referralCode"
|
||||
placeholder="Enter code if you have one"
|
||||
maxlength="20"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="waitlist-submit-btn" id="waitlist-submit">
|
||||
<span class="btn-text">Join Waitlist</span>
|
||||
<span class="btn-loading" style="display: none;">Joining...</span>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div class="waitlist-form-footer">
|
||||
<p class="privacy-note">
|
||||
We respect your privacy. No spam, ever.
|
||||
</p>
|
||||
<p class="waitlist-count" id="waitlist-count">
|
||||
<span class="waitlist-number">0</span> people waiting
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary btn-lg">
|
||||
Join Waitlist
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<p class="privacy-note">
|
||||
We respect your privacy. No spam, ever.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Features -->
|
||||
<div class="waitlist-features">
|
||||
<div class="feature">
|
||||
<div class="feature-icon">⚡</div>
|
||||
<h3>Real-Time Collaboration</h3>
|
||||
<p>Edit scripts together with your team in real-time. See changes as they happen.</p>
|
||||
</div>
|
||||
|
||||
<div class="feature">
|
||||
<div class="feature-icon">🔗</div>
|
||||
<h3>Seamless Integration</h3>
|
||||
<p>Fits perfectly into your existing workflow. Works on any device, anywhere.</p>
|
||||
</div>
|
||||
|
||||
<div class="feature">
|
||||
<div class="feature-icon">🎯</div>
|
||||
<h3>Powerful Features</h3>
|
||||
<p>Industry-standard formatting, templates, and tools for professional screenwriters.</p>
|
||||
</div>
|
||||
|
||||
<div class="feature">
|
||||
<div class="feature-icon">📱</div>
|
||||
<h3>Mobile-First</h3>
|
||||
<p>Write and collaborate from your phone, tablet, or desktop. Syncs everywhere.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Social Proof -->
|
||||
<div class="waitlist-social-proof">
|
||||
<div class="social-proof-header">
|
||||
<h3>Join thousands of writers who are waiting</h3>
|
||||
</div>
|
||||
|
||||
<div class="testimonials">
|
||||
<div class="testimonial">
|
||||
<p class="testimonial-quote">
|
||||
"Scripter transformed how our team collaborates on screenplays. It's simply amazing."
|
||||
</p>
|
||||
<div class="testimonial-author">
|
||||
<span class="author-name">Sarah Chen</span>
|
||||
<span class="author-role">Product Designer at TechCo</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="testimonial">
|
||||
<p class="testimonial-quote">
|
||||
"The real-time editing is incredibly smooth. Our team loves it."
|
||||
</p>
|
||||
<div class="testimonial-author">
|
||||
<span class="author-name">Marcus Johnson</span>
|
||||
<span class="author-role">Senior Writer at MediaCorp</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="testimonial">
|
||||
<p class="testimonial-quote">
|
||||
"Finally, a collaboration tool that actually makes screenwriting faster."
|
||||
</p>
|
||||
<div class="testimonial-author">
|
||||
<span class="author-name">Emily Rodriguez</span>
|
||||
<span class="author-role">Content Strategist at StartupXYZ</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<footer class="waitlist-footer">
|
||||
<p>© 2026 Scripter. All rights reserved.</p>
|
||||
<div class="footer-links">
|
||||
<a href="/">Home</a>
|
||||
<a href="/about">About</a>
|
||||
<a href="/privacy">Privacy</a>
|
||||
<a href="/terms">Terms</a>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
<style>
|
||||
/* Base styles */
|
||||
.waitlist-hero {
|
||||
min-height: 100vh;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 2rem;
|
||||
background: linear-gradient(135deg, #F8FAFC 0%, #E2E8F0 100%);
|
||||
}
|
||||
|
||||
.waitlist-content {
|
||||
max-width: 900px;
|
||||
margin: 0 auto;
|
||||
flex: 1;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* Badge */
|
||||
.waitlist-badge {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
padding: 8px 16px;
|
||||
background: linear-gradient(135deg, #2563EB 0%, #1D4ED8 100%);
|
||||
color: white;
|
||||
border-radius: 9999px;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.badge-dot {
|
||||
width: 8px;
|
||||
height: 8px;
|
||||
background: #F59E0B;
|
||||
border-radius: 50%;
|
||||
animation: pulse 2s infinite;
|
||||
}
|
||||
|
||||
@keyframes pulse {
|
||||
0%, 100% { opacity: 1; }
|
||||
50% { opacity: 0.5; }
|
||||
}
|
||||
|
||||
/* Typography */
|
||||
.waitlist-headline {
|
||||
font-size: clamp(2.5rem, 6vw, 4rem);
|
||||
font-weight: 700;
|
||||
color: #1E293B;
|
||||
line-height: 1.1;
|
||||
margin-bottom: 1.5rem;
|
||||
letter-spacing: -0.02em;
|
||||
}
|
||||
|
||||
.waitlist-subheadline {
|
||||
font-size: clamp(1.125rem, 2.5vw, 1.25rem);
|
||||
color: #475569;
|
||||
line-height: 1.6;
|
||||
margin-bottom: 3rem;
|
||||
max-width: 600px;
|
||||
}
|
||||
|
||||
/* Form Container */
|
||||
.waitlist-form-container {
|
||||
max-width: 500px;
|
||||
margin: 0 auto 4rem;
|
||||
}
|
||||
|
||||
.waitlist-form {
|
||||
background: white;
|
||||
padding: 2rem;
|
||||
border-radius: 16px;
|
||||
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.15);
|
||||
border: 1px solid #E2E8F0;
|
||||
}
|
||||
|
||||
.form-group {
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.form-group label {
|
||||
display: block;
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
color: #1E293B;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.form-group .optional {
|
||||
color: #94A3B8;
|
||||
font-weight: 400;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.form-group .required {
|
||||
color: #EF4444;
|
||||
font-size: 12px;
|
||||
}
|
||||
|
||||
.form-group input {
|
||||
width: 100%;
|
||||
padding: 1rem;
|
||||
font-size: 16px;
|
||||
border: 2px solid #E2E8F0;
|
||||
border-radius: 8px;
|
||||
transition: all 0.2s;
|
||||
background: #F8FAFC;
|
||||
}
|
||||
|
||||
.form-group input:focus {
|
||||
outline: none;
|
||||
border-color: #2563EB;
|
||||
background: white;
|
||||
box-shadow: 0 0 0 4px rgba(37, 99, 235, 0.1);
|
||||
}
|
||||
|
||||
.form-group input::placeholder {
|
||||
color: #94A3B8;
|
||||
}
|
||||
|
||||
/* Submit Button */
|
||||
.waitlist-submit-btn {
|
||||
width: 100%;
|
||||
padding: 1.25rem;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: white;
|
||||
background: linear-gradient(135deg, #2563EB 0%, #1D4ED8 100%);
|
||||
border: none;
|
||||
border-radius: 8px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.waitlist-submit-btn::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent);
|
||||
transition: left 0.5s;
|
||||
}
|
||||
|
||||
.waitlist-submit-btn:hover::before {
|
||||
left: 100%;
|
||||
}
|
||||
|
||||
.waitlist-submit-btn:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 10px 20px rgba(37, 99, 235, 0.3);
|
||||
}
|
||||
|
||||
.waitlist-submit-btn:disabled {
|
||||
opacity: 0.7;
|
||||
cursor: not-allowed;
|
||||
transform: none;
|
||||
}
|
||||
|
||||
.btn-text {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.btn-loading {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/* Form Footer */
|
||||
.waitlist-form-footer {
|
||||
margin-top: 1.5rem;
|
||||
padding-top: 1.5rem;
|
||||
border-top: 1px solid #E2E8F0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.privacy-note {
|
||||
font-size: 13px;
|
||||
color: #94A3B8;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.waitlist-count {
|
||||
font-size: 14px;
|
||||
color: #64748B;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.waitlist-number {
|
||||
color: #2563EB;
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
/* Features */
|
||||
.waitlist-features {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
|
||||
gap: 1.5rem;
|
||||
margin-top: 4rem;
|
||||
}
|
||||
|
||||
.feature {
|
||||
background: white;
|
||||
padding: 1.5rem;
|
||||
border-radius: 12px;
|
||||
border: 1px solid #E2E8F0;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.feature:hover {
|
||||
border-color: #2563EB;
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
|
||||
.feature-icon {
|
||||
font-size: 32px;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.feature h3 {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
color: #1E293B;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.feature p {
|
||||
font-size: 14px;
|
||||
color: #64748B;
|
||||
line-height: 1.5;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Social Proof */
|
||||
.waitlist-social-proof {
|
||||
margin-top: 6rem;
|
||||
padding: 3rem 0;
|
||||
background: white;
|
||||
border-radius: 16px;
|
||||
border: 1px solid #E2E8F0;
|
||||
}
|
||||
|
||||
.social-proof-header h3 {
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
color: #1E293B;
|
||||
text-align: center;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.testimonials {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
|
||||
gap: 2rem;
|
||||
}
|
||||
|
||||
.testimonial {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.testimonial-quote {
|
||||
font-size: 16px;
|
||||
font-style: italic;
|
||||
color: #475569;
|
||||
line-height: 1.6;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.testimonial-author {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
.author-name {
|
||||
font-weight: 600;
|
||||
color: #1E293B;
|
||||
font-size: 14px;
|
||||
}
|
||||
|
||||
.author-role {
|
||||
font-size: 13px;
|
||||
color: #94A3B8;
|
||||
}
|
||||
|
||||
/* Footer */
|
||||
.waitlist-footer {
|
||||
margin-top: auto;
|
||||
padding: 2rem 0;
|
||||
border-top: 1px solid #E2E8F0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.waitlist-footer p {
|
||||
font-size: 14px;
|
||||
color: #94A3B8;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.footer-links {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
gap: 2rem;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.footer-links a {
|
||||
font-size: 14px;
|
||||
color: #64748B;
|
||||
text-decoration: none;
|
||||
transition: color 0.2s;
|
||||
}
|
||||
|
||||
.footer-links a:hover {
|
||||
color: #2563EB;
|
||||
}
|
||||
|
||||
/* Success State */
|
||||
.waitlist-success {
|
||||
text-align: center;
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.waitlist-success h2 {
|
||||
font-size: 24px;
|
||||
font-weight: 600;
|
||||
color: #1E293B;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.waitlist-success p {
|
||||
color: #64748B;
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.referral-info {
|
||||
background: #F8FAFC;
|
||||
padding: 1.5rem;
|
||||
border-radius: 8px;
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
|
||||
.referral-label {
|
||||
font-size: 13px;
|
||||
color: #94A3B8;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.referral-code {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.code-display {
|
||||
font-family: monospace;
|
||||
font-size: 20px;
|
||||
font-weight: 700;
|
||||
color: #2563EB;
|
||||
background: white;
|
||||
padding: 0.5rem 1rem;
|
||||
border-radius: 6px;
|
||||
border: 1px solid #E2E8F0;
|
||||
}
|
||||
|
||||
.copy-btn {
|
||||
font-size: 13px;
|
||||
font-weight: 600;
|
||||
color: #2563EB;
|
||||
background: white;
|
||||
padding: 0.5rem 1rem;
|
||||
border: 1px solid #2563EB;
|
||||
border-radius: 6px;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.copy-btn:hover {
|
||||
background: #2563EB;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.referral-hint {
|
||||
font-size: 13px;
|
||||
color: #94A3B8;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* Error State */
|
||||
.error-message {
|
||||
background: #FEF2F2;
|
||||
color: #EF4444;
|
||||
padding: 1rem;
|
||||
border-radius: 8px;
|
||||
font-size: 14px;
|
||||
margin-top: 1rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Responsive */
|
||||
@media (max-width: 768px) {
|
||||
.waitlist-hero {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.waitlist-form {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.waitlist-features {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.testimonials {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.waitlist-social-proof {
|
||||
padding: 1.5rem 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Accessibility */
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.badge-dot,
|
||||
.waitlist-submit-btn::before,
|
||||
.feature,
|
||||
.testimonial {
|
||||
transition: none;
|
||||
animation: none;
|
||||
}
|
||||
}
|
||||
|
||||
/* Focus visible for keyboard navigation */
|
||||
.waitlist-submit-btn:focus-visible,
|
||||
.form-group input:focus-visible {
|
||||
outline: 3px solid #F59E0B;
|
||||
outline-offset: 2px;
|
||||
}
|
||||
</style>
|
||||
|
||||
<style>
|
||||
.waitlist-landing {
|
||||
max-width: 600px;
|
||||
|
||||
95
src/pages/waitlist.tsx
Normal file
95
src/pages/waitlist.tsx
Normal file
@@ -0,0 +1,95 @@
|
||||
import { WaitlistForm } from '@/components/waitlist/WaitlistForm';
|
||||
|
||||
export default function WaitlistPage() {
|
||||
return (
|
||||
<div class="waitlist-page">
|
||||
<main class="waitlist-hero">
|
||||
<div class="waitlist-content">
|
||||
<div class="waitlist-badge">
|
||||
<span class="badge-dot"></span>
|
||||
<span class="badge-text">Coming Soon</span>
|
||||
</div>
|
||||
|
||||
<h1 class="waitlist-headline">
|
||||
Write Faster with FrenoCorp
|
||||
</h1>
|
||||
|
||||
<p class="waitlist-subheadline">
|
||||
The collaborative writing platform that brings your team together.
|
||||
Real-time editing, seamless integration, and powerful features.
|
||||
</p>
|
||||
|
||||
<WaitlistForm />
|
||||
|
||||
<div class="waitlist-features">
|
||||
<div class="feature">
|
||||
<div class="feature-icon">⚡</div>
|
||||
<h3>Real-Time Collaboration</h3>
|
||||
<p>Edit documents together with your team in real-time.</p>
|
||||
</div>
|
||||
|
||||
<div class="feature">
|
||||
<div class="feature-icon">🔗</div>
|
||||
<h3>Seamless Integration</h3>
|
||||
<p>Fits perfectly into your existing workflow.</p>
|
||||
</div>
|
||||
|
||||
<div class="feature">
|
||||
<div class="feature-icon">🎯</div>
|
||||
<h3>Powerful Features</h3>
|
||||
<p>Everything you need to write better, together.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="waitlist-social-proof">
|
||||
<div class="social-proof-header">
|
||||
<h3>Join thousands of writers who are waiting</h3>
|
||||
</div>
|
||||
|
||||
<div class="testimonials">
|
||||
<div class="testimonial">
|
||||
<p class="testimonial-quote">
|
||||
"FrenoCorp transformed how our team collaborates on documents. It's simply amazing."
|
||||
</p>
|
||||
<div class="testimonial-author">
|
||||
<span class="author-name">Sarah Chen</span>
|
||||
<span class="author-role">Product Designer at TechCo</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="testimonial">
|
||||
<p class="testimonial-quote">
|
||||
"The real-time editing is incredibly smooth. Our team loves it."
|
||||
</p>
|
||||
<div class="testimonial-author">
|
||||
<span class="author-name">Marcus Johnson</span>
|
||||
<span class="author-role">Senior Writer at MediaCorp</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="testimonial">
|
||||
<p class="testimonial-quote">
|
||||
"Finally, a collaboration tool that actually makes writing faster."
|
||||
</p>
|
||||
<div class="testimonial-author">
|
||||
<span class="author-name">Emily Rodriguez</span>
|
||||
<span class="author-role">Content Strategist at StartupXYZ</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="waitlist-footer">
|
||||
<p>© 2026 FrenoCorp. All rights reserved.</p>
|
||||
<div class="footer-links">
|
||||
<a href="/">Home</a>
|
||||
<a href="/about">About</a>
|
||||
<a href="/privacy">Privacy</a>
|
||||
<a href="/terms">Terms</a>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -12,6 +12,7 @@ import { Pricing } from './routes/pricing/Pricing';
|
||||
import { About } from './routes/about/About';
|
||||
import { Faq } from './routes/faq/Faq';
|
||||
import { NotFound } from './routes/NotFound';
|
||||
import { Waitlist } from './routes/waitlist/Waitlist';
|
||||
import './styles/landing.css';
|
||||
import './styles/blog.css';
|
||||
import './styles/features.css';
|
||||
@@ -32,6 +33,7 @@ const Redirect = () => <Navigate href="/dashboard" />;
|
||||
export const routes = [
|
||||
<Route path="/" component={Landing} />,
|
||||
<Route path="/beta" component={BetaSignup} />,
|
||||
<Route path="/waitlist" component={Waitlist} />,
|
||||
<Route path="/features" component={Features} />,
|
||||
<Route path="/pricing" component={Pricing} />,
|
||||
<Route path="/about" component={About} />,
|
||||
|
||||
@@ -3,6 +3,7 @@ import { A, useNavigate, useParams } from '@solidjs/router';
|
||||
import { useAuth, useAuthActions } from '../lib/auth/provider';
|
||||
import { useProjectService } from '../lib/projects/service';
|
||||
import { Project, UserRole } from '../lib/auth/types';
|
||||
import { WaitlistForm } from '../components/waitlist/WaitlistForm';
|
||||
|
||||
export const HomePage: Component = () => {
|
||||
const service = useProjectService();
|
||||
@@ -564,4 +565,99 @@ export const routes = [
|
||||
{ path: '/settings/profile', component: ProfilePage },
|
||||
{ path: '/sign-in', component: SignInPage },
|
||||
{ path: '/sign-up', component: SignUpPage },
|
||||
{ path: '/waitlist', component: WaitlistPage },
|
||||
];
|
||||
|
||||
const WaitlistPage: Component = () => {
|
||||
return (
|
||||
<div class="waitlist-page">
|
||||
<main class="waitlist-hero">
|
||||
<div class="waitlist-content">
|
||||
<div class="waitlist-badge">
|
||||
<span class="badge-dot"></span>
|
||||
<span class="badge-text">Coming Soon</span>
|
||||
</div>
|
||||
|
||||
<h1 class="waitlist-headline">
|
||||
Write Faster with FrenoCorp
|
||||
</h1>
|
||||
|
||||
<p class="waitlist-subheadline">
|
||||
The collaborative writing platform that brings your team together.
|
||||
Real-time editing, seamless integration, and powerful features.
|
||||
</p>
|
||||
|
||||
<WaitlistForm />
|
||||
|
||||
<div class="waitlist-features">
|
||||
<div class="feature">
|
||||
<div class="feature-icon">⚡</div>
|
||||
<h3>Real-Time Collaboration</h3>
|
||||
<p>Edit documents together with your team in real-time.</p>
|
||||
</div>
|
||||
|
||||
<div class="feature">
|
||||
<div class="feature-icon">🔗</div>
|
||||
<h3>Seamless Integration</h3>
|
||||
<p>Fits perfectly into your existing workflow.</p>
|
||||
</div>
|
||||
|
||||
<div class="feature">
|
||||
<div class="feature-icon">🎯</div>
|
||||
<h3>Powerful Features</h3>
|
||||
<p>Everything you need to write better, together.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="waitlist-social-proof">
|
||||
<div class="social-proof-header">
|
||||
<h3>Join thousands of writers who are waiting</h3>
|
||||
</div>
|
||||
|
||||
<div class="testimonials">
|
||||
<div class="testimonial">
|
||||
<p class="testimonial-quote">
|
||||
"FrenoCorp transformed how our team collaborates on documents. It's simply amazing."
|
||||
</p>
|
||||
<div class="testimonial-author">
|
||||
<span class="author-name">Sarah Chen</span>
|
||||
<span class="author-role">Product Designer at TechCo</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="testimonial">
|
||||
<p class="testimonial-quote">
|
||||
"The real-time editing is incredibly smooth. Our team loves it."
|
||||
</p>
|
||||
<div class="testimonial-author">
|
||||
<span class="author-name">Marcus Johnson</span>
|
||||
<span class="author-role">Senior Writer at MediaCorp</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="testimonial">
|
||||
<p class="testimonial-quote">
|
||||
"Finally, a collaboration tool that actually makes writing faster."
|
||||
</p>
|
||||
<div class="testimonial-author">
|
||||
<span class="author-name">Emily Rodriguez</span>
|
||||
<span class="author-role">Content Strategist at StartupXYZ</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
<footer class="waitlist-footer">
|
||||
<p>© 2026 FrenoCorp. All rights reserved.</p>
|
||||
<div class="footer-links">
|
||||
<a href="/">Home</a>
|
||||
<a href="/about">About</a>
|
||||
<a href="/privacy">Privacy</a>
|
||||
<a href="/terms">Terms</a>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
3
src/routes/waitlist/Waitlist.tsx
Normal file
3
src/routes/waitlist/Waitlist.tsx
Normal file
@@ -0,0 +1,3 @@
|
||||
import { WaitlistPage } from '../pages/waitlist';
|
||||
|
||||
export const Waitlist = () => <WaitlistPage />;
|
||||
Reference in New Issue
Block a user