Files
industries/app/not-found.tsx
zeekay 49beb995f8 fix: production audit — security, content, and UX fixes
Security:
- Fix OAuth CSRF bypass: require state match instead of accepting when no state saved
- Remove query-param token fallback (tokens logged by CDN/analytics)
- Move auth token from localStorage to sessionStorage (XSS mitigation)
- Replace upstream model ID 'qwen3-32b' with branded 'zen' in chat widget
- Change analytics person_profiles from 'always' to 'identified_only' (GDPR)
- Replace deceptive auth page (collected + discarded credentials) with clean redirect

Content:
- Fix wrong Twitter handle (@hanaborobyai → @hanzoai)
- Fix privacy policy contradiction (removed "train on your data" claim)
- Remove internal Google Docs URLs from capabilities page
- Replace unverified "$50M Series B" with verified Techstars '17 milestone
- Replace 8 dead '#' news links with real product/resource links
- Fix Navbar "58 papers" → "130+ papers" to match all other surfaces
- Replace "Hanzo L1" (undefined product) with "Zen4 MoDE models" in hero
- Fix AI slop: "harness the power" → "deploy in production", "state-of-the-art" → "production-grade", "cutting-edge" → "frontier"
- Fix solutions page template filler descriptions
- Fix stat inconsistencies: careers AI models 50+ → 45+, help credits $10 → $5
- Fix zen-guard params 1B → 4B (matching canonical spec)
- Fix dead research sub-page links (/alignment, /safety → GitHub papers repos)
- Fix capabilities dead links → real product pages

UX:
- Wire contact form to api.hanzo.ai/v1/contact with Cal.com fallback
- Fix dead buttons on services page (Get Started → /contact, View Case Studies → /case-studies)
- Fix security whitepaper button → "Request Security Documentation" linking to /contact
- Fix help Live Chat button → hanzo.bot
- Fix Cal.com URLs (cal.com/hanzo → cal.com/hanzo/30min)
- Fix Cal.com template literal (${"dark"} → plain string)
- Replace console.error on 404 with analytics event tracking
2026-02-27 10:15:39 -08:00

128 lines
4.3 KiB
TypeScript

"use client";
import { useEffect, useState } from "react";
import { usePathname } from "next/navigation";
import { Bot, Send, XCircle } from "lucide-react";
import { Button } from "@hanzo/ui";
import { Drawer, DrawerContent, DrawerTrigger } from "@hanzo/ui/drawer";
import { cn } from "@/lib/utils";
import { useToast } from "@/hooks/use-toast";
type MessageRole = "user" | "assistant";
interface Message {
role: MessageRole;
content: string;
}
export default function NotFound() {
const pathname = usePathname();
const [isOpen, setIsOpen] = useState(false);
const [message, setMessage] = useState("");
const [messages, setMessages] = useState<Message[]>([]);
const { toast } = useToast();
useEffect(() => {
// Track 404 via analytics if available
if (typeof window !== "undefined" && (window as any).ha) {
(window as any).ha.capture("404_page_view", { path: pathname });
}
}, [pathname]);
const handleSendMessage = async () => {
if (!message.trim()) return;
const userMessage: Message = {
role: "user",
content: message
};
const newMessages = [...messages, userMessage];
setMessages(newMessages);
setMessage("");
// Simulate AI response - Replace with actual AI integration
setTimeout(() => {
const aiMessage: Message = {
role: "assistant",
content: `I noticed you're trying to access ${pathname}. This page doesn't exist, but I can help you find what you're looking for! What were you trying to find?`
};
setMessages([...newMessages, aiMessage]);
}, 1000);
toast({
title: "Message sent!",
description: "The AI assistant will respond shortly.",
});
};
return (
<div className="min-h-screen flex items-center justify-center bg-background text-foreground">
<div className="text-center">
<h1 className="text-4xl font-bold mb-4">404</h1>
<p className="text-xl mb-4 text-muted-foreground">Oops! Page not found</p>
<a href="/" className="underline text-foreground hover:text-muted-foreground">
Return to Home
</a>
</div>
<Drawer open={isOpen} onOpenChange={setIsOpen}>
<DrawerTrigger asChild>
<Button
className="fixed bottom-4 right-4 rounded-full p-4 shadow-lg animate-bounce bg-primary hover:bg-primary/90 text-primary-foreground"
size="icon"
>
<Bot className="h-6 w-6" />
</Button>
</DrawerTrigger>
<DrawerContent className="h-[500px] p-4 bg-background border-border">
<div className="flex flex-col h-full">
<div className="flex items-center justify-between mb-4">
<div className="flex items-center space-x-2">
<Bot className="h-6 w-6 text-foreground" />
<h2 className="text-lg font-semibold">AI Assistant</h2>
</div>
<Button
variant="ghost"
size="icon"
onClick={() => setIsOpen(false)}
>
<XCircle className="h-5 w-5" />
</Button>
</div>
<div className="flex-1 overflow-y-auto space-y-4 mb-4">
{messages.map((msg, index) => (
<div
key={index}
className={cn(
"p-3 rounded-lg max-w-[80%]",
msg.role === "user"
? "bg-primary text-primary-foreground ml-auto"
: "bg-foreground/10 text-muted-foreground"
)}
>
{msg.content}
</div>
))}
</div>
<div className="flex items-center space-x-2">
<input
type="text"
value={message}
onChange={(e) => setMessage(e.target.value)}
onKeyPress={(e) => e.key === "Enter" && handleSendMessage()}
placeholder="Ask me anything..."
className="flex-1 p-2 border rounded-md focus:outline-none focus:ring-2 bg-foreground/5 border-border text-foreground placeholder-muted-foreground focus:ring-ring"
/>
<Button onClick={handleSendMessage} size="icon">
<Send className="h-4 w-4" />
</Button>
</div>
</div>
</DrawerContent>
</Drawer>
</div>
);
}