From 2d88228eeb0a1976a6b3b1bf8906f60e1ef36d0f Mon Sep 17 00:00:00 2001 From: kingcoleschmo-coder Date: Thu, 6 Nov 2025 14:14:36 -0700 Subject: [PATCH] Update App.tsx --- framework-boilerplates/vite-react/src/App.tsx | 480 +++++++++++++++++- 1 file changed, 452 insertions(+), 28 deletions(-) diff --git a/framework-boilerplates/vite-react/src/App.tsx b/framework-boilerplates/vite-react/src/App.tsx index afe48ac750..f74ab66d52 100644 --- a/framework-boilerplates/vite-react/src/App.tsx +++ b/framework-boilerplates/vite-react/src/App.tsx @@ -1,35 +1,459 @@ -import { useState } from 'react' -import reactLogo from './assets/react.svg' -import viteLogo from '/vite.svg' -import './App.css' +import { useState } from "react"; +import { Check, MapPin, Bike, Clock, Mail, Phone, Menu as MenuIcon } from "lucide-react"; -function App() { - const [count, setCount] = useState(0) +// --- Simple data you can edit quickly --- +const BRAND = { + name: "CanvasBites", + tagline: "Fresh, affordable meals delivered to your door.", + phone: "(555) 123-4567", + email: "hello@canvasbites.com", + primary: "#16a34a", // Tailwind green-600 + accent: "#f97316", // Tailwind orange-500 + city: "Tempe, AZ", + deliveryWindows: [ + { label: "Lunch", time: "11:30 AM – 1:30 PM" }, + { label: "Dinner", time: "5:30 PM – 7:30 PM" }, + ], + orderLink: "https://forms.gle/your-google-form", + instagram: "https://instagram.com/yourhandle", +}; + +const MENU = [ + { + name: "Grilled Chicken Bowl", + desc: "Brown rice, roasted veggies, lemon herb sauce", + price: 10.0, + kcal: 520, + img: + "https://images.unsplash.com/photo-1604908812239-6ec6f0d7d1b6?q=80&w=1200&auto=format&fit=crop", + tags: ["Gluten-free", "High protein"], + }, + { + name: "Veggie Power Wrap", + desc: "Whole-wheat wrap, hummus, spinach, avo, quinoa", + price: 9.0, + kcal: 460, + img: + "https://images.unsplash.com/photo-1540420773420-3366772f4999?q=80&w=1200&auto=format&fit=crop", + tags: ["Vegan", "Fiber-rich"], + }, + { + name: "Beef Teriyaki Bento", + desc: "Jasmine rice, sesame broccoli, pickled carrot", + price: 11.0, + kcal: 610, + img: + "https://images.unsplash.com/photo-1544025162-d76694265947?q=80&w=1200&auto=format&fit=crop", + tags: ["Best seller"], + }, + { + name: "Greek Salad + Falafel", + desc: "Romaine, tomato, cucumber, olives, feta, tahini", + price: 9.5, + kcal: 390, + img: + "https://images.unsplash.com/photo-1568605114967-8130f3a36994?q=80&w=1200&auto=format&fit=crop", + tags: ["Vegetarian"], + }, +]; + +// ----------------------- +// Lightweight smoke tests (keep these!) +// ----------------------- +function runSmokeTests() { + try { + // Brand basics + console.assert(typeof BRAND.name === "string" && BRAND.name.length > 0, "BRAND.name required"); + console.assert(typeof BRAND.orderLink === "string" && BRAND.orderLink.startsWith("http"), "orderLink must be a URL"); + console.assert(Array.isArray(BRAND.deliveryWindows) && BRAND.deliveryWindows.length >= 2, "Need at least two delivery windows"); + for (const w of BRAND.deliveryWindows) { + console.assert(typeof (w as {label:string; time:string}).label === "string" && typeof (w as {label:string; time:string}).time === "string", "delivery window must have label/time strings"); + } + + // Menu integrity + console.assert(Array.isArray(MENU) && MENU.length >= 1, "MENU should have items"); + for (const m of MENU) { + console.assert(!!m.name, "Menu item needs a name"); + console.assert(typeof m.price === "number" && !Number.isNaN(m.price), "Menu item price must be a number"); + console.assert(Array.isArray(m.tags), "Menu item tags should be an array"); + console.assert(typeof m.img === "string" && m.img.startsWith("http"), "Menu item must have an image URL"); + } + + // Template-string content check (guards the original bug) + const a = BRAND.deliveryWindows?.[0]?.label ?? "Lunch"; + const b = BRAND.deliveryWindows?.[1]?.label ?? "Dinner"; + const how = `Select ${a} or ${b} delivery.`; + console.assert(how.includes(a) && how.includes(b) && how.endsWith("delivery."), "how-text template should compile correctly"); + } catch (err) { + console.error("Smoke tests failed:", err); + } +} + +runSmokeTests(); + +export default function App() { + const [mobileOpen, setMobileOpen] = useState(false); + + // Safe fallbacks for delivery window labels to prevent runtime errors + const windowA: string = BRAND.deliveryWindows?.[0]?.label ?? "Lunch"; + const windowB: string = BRAND.deliveryWindows?.[1]?.label ?? "Dinner"; + const howText: string = `Select ${windowA} or ${windowB} delivery.`; // fixed template string return ( - <> -
- - Vite logo - - - React logo - -
-

Vite + React

-
- -

- Edit src/App.tsx and save to test HMR +

+ {/* Navbar */} +
+ + {mobileOpen && ( +
+
+ {[ + ["Menu", "#menu"], + ["How it works", "#how"], + ["Delivery", "#delivery"], + ["FAQ", "#faq"], + ].map(([label, href]) => ( + setMobileOpen(false)} + > + {label} + + ))} + + Order now + +
+
+ )} +
+ + {/* Hero */} +
+
+
+
+

+ Healthy campus meals, delivered fast. +

+

+ {BRAND.tagline} Pre-order by 10:00 AM for lunch or by 3:00 PM for dinner. Simple pricing, no surprises. +

+ +
    +
  • Chef-prepped, reheats in 2–3 min
  • +
  • Macros listed; vegetarian & GF options
  • +
  • Free delivery on campus
  • +
+
+
+ Bowls of fresh meals +
+ + Delivery in 30–45 min +
+
+
+
+ + {/* Menu */} + + + {/* How it works */} +
+
+ {[ + { + title: "Pick your meals", + icon: , + text: "Choose from weekly rotating bowls, wraps, and salads.", + }, + { + title: "Choose a window", + icon: , + text: howText, + }, + { + title: "We deliver fast", + icon: , + text: "Track your driver via text and meet at the door or lobby.", + }, + ].map((s) => ( +
+
{s.icon}
+
+

{s.title}

+

{s.text}

+
+
+ ))} +
+
+ + {/* Delivery */} +
+

Delivery in {BRAND.city}

+

+ Free delivery on campus. Off-campus within 2 miles: $2.99 flat fee. We currently deliver during these windows:

+
+ {BRAND.deliveryWindows.map((w) => ( +
+ {w.label}: {w.time} +
+ ))} +
+
+
+

Delivery area

+

ASU campus + 2 miles around Tempe. Enter your address at checkout to confirm.

+ + Check my address + +
+ Map placeholder +
+
+ + {/* Pricing blurb */} +
+
+
+

Simple pricing

+

Meals from $9–$11. Student bundle: 5 meals for $45. No hidden fees.

+
    +
  • Apple Pay • Google Pay • Credit Card
  • +
  • Cancel or edit up to 2 hours before window
  • +
  • Allergen info at checkout
  • +
+
+
+

Join the list for weekly menus

+ +

We’ll email once a week. No spam.

+
+
+
+ + {/* FAQ */} +
+

FAQ

+
+ + + + +
+
+ + {/* Contact */} +
+
+
+

Questions? Reach out.

+

We’re quick on text and email during delivery windows.

+
+
{BRAND.phone}
+
{BRAND.email}
+
+
+ +
+
+ + {/* Footer */} +
+
+
© {new Date().getFullYear()} {BRAND.name}. All rights reserved.
+ +
+
+
+ ); +} + +function NewsletterForm() { + const [email, setEmail] = useState(""); + const [sent, setSent] = useState(false); + + function submit(e: React.FormEvent) { + e.preventDefault(); + // Swap action to Formspree or Beehiiv embed later + setSent(true); + } + + if (sent) return
Thanks! You’re on the list.
; + + return ( +
+ setEmail(e.target.value)} + placeholder="you@asu.edu" + className="flex-1 rounded-xl border px-3 py-2" + /> + +
+ ); +} + +function ContactForm() { + const [status, setStatus] = useState<"idle" | "sent">("idle"); + type FormState = { name: string; email: string; message: string }; + const [form, setForm] = useState({ name: "", email: "", message: "" }); + + function submit(e: React.FormEvent) { + e.preventDefault(); + setStatus("sent"); + } + + return ( +
+
+
+ + setForm({ ...form, name: e.target.value })} + className="mt-1 w-full rounded-xl border px-3 py-2" + placeholder="Alex Johnson" + /> +
+
+ + setForm({ ...form, email: e.target.value })} + className="mt-1 w-full rounded-xl border px-3 py-2" + placeholder="you@asu.edu" + /> +
-

- Click on the Vite and React logos to learn more -

- - ) +
+ +