import React, { useState } from 'react'; import { CheckCircle, AlertTriangle, Server, CreditCard, Code, Smartphone, ArrowRight, ShieldCheck, Loader2, HelpCircle, UserCheck, Zap, Coffee, Image as ImageIcon, UploadCloud, Copy, Trash2, FileUp, Terminal, Globe, Printer, X, Link as LinkIcon, ExternalLink, User, Mail, Tag, Info, Eye, Lock, Menu, Settings, UserPlus } from 'lucide-react'; // --- UI Components --- const Card = ({ children, className = "" }) => (
{children}
); const Button = ({ children, onClick, disabled, variant = "primary", className = "", ...props }) => { const baseStyle = "px-6 py-3 rounded-lg font-bold transition-all duration-200 flex items-center justify-center gap-2 tracking-wide"; const styles = { primary: "bg-stone-900 hover:bg-stone-800 text-white shadow-md disabled:opacity-50 disabled:cursor-not-allowed border border-stone-900", secondary: "bg-stone-50 border-2 border-stone-200 text-stone-700 hover:border-stone-400 hover:bg-stone-100", outline: "bg-transparent border border-stone-300 text-stone-700 hover:bg-stone-50", danger: "bg-red-50 text-red-800 border border-red-200 hover:bg-red-100", paypal: "bg-[#FFC439] hover:brightness-95 text-stone-900 shadow-sm disabled:opacity-50 disabled:cursor-not-allowed", venmo: "bg-[#008CFF] hover:brightness-95 text-white shadow-sm disabled:opacity-50 disabled:cursor-not-allowed", action: "px-3 py-1.5 text-xs bg-white border border-stone-200 shadow-sm hover:border-amber-500 hover:text-amber-800", checklist: "px-8 py-4 bg-stone-100 text-stone-900 border-2 border-stone-900 font-serif italic text-lg hover:bg-stone-200 shadow-sm" }; return ( ); }; const Input = ({ label, type = "text", value, onChange, placeholder, icon: Icon, required = false, error = "" }) => (
onChange(e.target.value)} className={`w-full pl-10 pr-4 py-3 border rounded-lg focus:ring-2 focus:ring-amber-600 focus:border-amber-600 transition-all bg-stone-50 focus:bg-white ${error ? 'border-red-500 ring-1 ring-red-200' : 'border-stone-300'}`} placeholder={placeholder} /> {Icon && }
{error &&

{error}

}
); export default function App() { const [step, setStep] = useState(0); const [deployMode, setDeployMode] = useState("concierge"); const [showChecklistModal, setShowChecklistModal] = useState(false); const [showDelegateGuide, setShowDelegateGuide] = useState(false); // Payment State const [price, setPrice] = useState(99); const [promoCode, setPromoCode] = useState(""); const [promoMessage, setPromoMessage] = useState(""); const [showPromoInput, setShowPromoInput] = useState(false); const [formData, setFormData] = useState({ domainName: "", gdEmail: "", htmlCode: "", customerName: "", customerEmail: "" }); const [uploadedFiles, setUploadedFiles] = useState([]); const [codeErrors, setCodeErrors] = useState([]); const [emailError, setEmailError] = useState(""); const [emailWarning, setEmailWarning] = useState(""); const [highlightUpload, setHighlightUpload] = useState(false); const [deployStatus, setDeployStatus] = useState("idle"); const [paymentProcessing, setPaymentProcessing] = useState(false); // --- Helpers --- const handleEmailChange = (val) => { setFormData({ ...formData, customerEmail: val }); const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/; if (val && !emailRegex.test(val)) { setEmailError("Please enter a valid email address."); } else { setEmailError(""); } if (val && formData.gdEmail && val !== formData.gdEmail) { setEmailWarning("Note: This is different from your GoDaddy email. That's okay, just checking!"); } else { setEmailWarning(""); } }; const applyPromoCode = () => { const code = promoCode.trim().toUpperCase(); if (code === "UPDATE") { setPrice(29); setPromoMessage("Success! Returning customer rate applied."); } else if (code === "FRIEND") { setPrice(84); setPromoMessage("Success! Friend discount applied."); } else { setPromoMessage("Invalid code."); setTimeout(() => setPromoMessage(""), 2000); } }; const handleFileUpload = (e) => { const newFiles = Array.from(e.target.files).map(f => ({ name: f.name, size: (f.size / 1024).toFixed(0) + 'KB', type: f.type })); setUploadedFiles([...uploadedFiles, ...newFiles]); setHighlightUpload(false); }; const removeFile = (fileName) => { setUploadedFiles(uploadedFiles.filter(f => f.name !== fileName)); }; const copySnippet = (fileName) => { alert(`Copied to clipboard: `); }; const handlePreviewCode = () => { if (!formData.htmlCode) return; const blob = new Blob([formData.htmlCode], { type: 'text/html' }); const url = URL.createObjectURL(blob); window.open(url, '_blank'); }; const validateCodeAndAssets = () => { const errors = []; const code = formData.htmlCode; // V23: Empty Code Check if (!code || code.trim().length < 20) { errors.push({ type: "empty_code", msg: "Error: Your code looks empty or too short." }); } const srcMatches = [...code.matchAll(/src=["']([^"']+)["']/g)]; srcMatches.forEach(match => { const srcValue = match[1]; if (srcValue.startsWith('http') || srcValue.startsWith('//') || srcValue.startsWith('data:')) return; const fileExists = uploadedFiles.some(f => f.name === srcValue); if (!fileExists) { errors.push({ type: "missing_file", file: srcValue, msg: `Missing file: "${srcValue}"` }); } }); if (code.match(/src=["'](file:|[A-Z]:\\|\/Users\/)/i)) { errors.push({ type: "local_path", msg: "Detected a local computer link (C:/...). Please replace it." }); } if (!code.toLowerCase().match(/paypal|venmo|stripe/)) { errors.push({ type: "business_logic", msg: "Warning: No payment link (PayPal/Venmo) found. Are you sure?" }); } setCodeErrors(errors); return errors.length === 0 || errors.every(e => e.type === "business_logic"); }; const handlePayment = (provider) => { setPaymentProcessing(true); setTimeout(() => { setPaymentProcessing(false); setStep(5); }, 2000); }; // --- Delegate Guide Modal --- const DelegateGuideModal = () => (

How to Grant Access

1

Account Settings

Log in to GoDaddy. Click your Name in the top right, then select Account Settings.

Account Settings
2

Delegate Access & Security

Click Delegate Access. GoDaddy will text a verification code to your phone. Enter it to proceed.

Verify Code
3

Invite to Access

Click "Invite to Access" on the right. Fill out the form exactly like this:

Name: 1845 Dev Team
Email: deploy@1845.ai
4

Access Level & Invite

Select "Products & Domains" and click Invite.

Products & Domains
); // --- Checklist Modal Component --- const ChecklistModal = () => (

HTMLtoWeb Checklist

Have these items ready for your concierge deployment.

{[ { icon: Globe, title: "1. Domain Name", desc: "Know exactly which URL you are updating." }, { icon: Server, title: "2. GoDaddy Login", desc: "You will need to log in to grant us access." }, { icon: UserCheck, title: "3. Delegate Access", desc: "We will ask you to invite 'deploy@1845.ai' in your settings." }, { icon: Code, title: "4. Your HTML Code", desc: "Your HTML code you created and tested on Gemini or Claude." } ].map((item, i) => (

{item.title}

{item.desc}

))}
); // --- Step 0: Preview --- const StepPreview = () => (
HTMLtoWeb

We Deploy Your AI Code
To GoDaddy

Your code is ready. You just need it online.
Secure "Delegate Access" Service. We never ask for your password.

Live within 2-4 hours of request.

{[ { icon: CreditCard, title: "1. One-Time Fee", desc: "$99 Service Fee. Returning customers get updates for $29." }, { icon: Code, title: "2. Paste Code", desc: "Your HTML code you created and tested on Gemini or Claude." }, { icon: Globe, title: "3. We Deploy", desc: "Our team securely uploads your files via Delegate Access." } ].map((item, i) => (

{item.title}

{item.desc}

))}

I have everything & am ready to launch.

); // --- Step 1: Checklist --- const StepChecklist = () => (

Pre-Flight Checklist

Gather these items before we begin.

{[ { icon: Server, title: "GoDaddy Login", desc: "Username & Password." }, { icon: UserCheck, title: "Delegate Access", desc: "You'll invite us to access your hosting safely." }, { icon: CreditCard, title: "Payment Method", desc: "For the $99 setup fee." } ].map((item, i) => (

{item.title}

{item.desc}

))}
); // --- Step 2: Config --- const StepConfig = () => (

Connect Host

Securely grant access to your hosting.

setFormData({...formData, domainName: val})} />

*Required so we know exactly which domain to update.

Delegate Access

GoDaddy makes this tricky to find. Click "Show me how" above if you get stuck.

1. Go to Account Settings {'>'} Delegate Access.

2. Invite Name: 1845 Dev Team

3. Invite Email: deploy@1845.ai

4. Access Level: Products & Domains (Required).

Confirm your GoDaddy Email

setFormData({...formData, gdEmail: val})} />

We use this to verify your invitation.

); // --- Step 3: Editor --- const StepEditor = () => (

Code & Assets

1. Upload Images. 2. Paste Code.

Upload Images

{uploadedFiles.map((file, idx) => (
{file.name}
))}