11 Commits

Author SHA1 Message Date
ea79c252a3 Update src/app/page.tsx 2026-03-14 18:34:31 +00:00
0088542b7f Merge version_2 into main
Merge version_2 into main
2026-03-14 18:30:43 +00:00
df3036a14b Update src/app/admin/page.tsx 2026-03-14 18:30:39 +00:00
1e9b6b4300 Merge version_2 into main
Merge version_2 into main
2026-03-14 18:30:15 +00:00
aefd386fa9 Update src/app/admin/page.tsx 2026-03-14 18:30:10 +00:00
bb10a104d4 Merge version_2 into main
Merge version_2 into main
2026-03-14 18:29:48 +00:00
c429eefdfe Update src/app/styles/variables.css 2026-03-14 18:29:44 +00:00
57fdfdb51f Update src/app/page.tsx 2026-03-14 18:29:43 +00:00
3d497284d3 Add src/app/admin/page.tsx 2026-03-14 18:29:43 +00:00
a7fba8c266 Merge version_1 into main
Merge version_1 into main
2026-03-14 18:26:10 +00:00
37206aaf0e Merge version_1 into main
Merge version_1 into main
2026-03-14 18:20:51 +00:00
3 changed files with 431 additions and 60 deletions

332
src/app/admin/page.tsx Normal file
View File

@@ -0,0 +1,332 @@
"use client";
import { useState } from "react";
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import NavbarStyleCentered from '@/components/navbar/NavbarStyleCentered/NavbarStyleCentered';
import FooterLogoEmphasis from '@/components/sections/footer/FooterLogoEmphasis';
import HeroBillboardDashboard from '@/components/sections/hero/HeroBillboardDashboard';
import { Settings, Clock, DollarSign, UtensilsCrossed, LogOut } from 'lucide-react';
export default function AdminPage() {
const [activeTab, setActiveTab] = useState<'hours' | 'prices' | 'menu'>('hours');
const [hours, setHours] = useState({
monday: { open: 'Closed', close: '' },
tuesday: { open: '11:00 AM', close: '9:00 PM' },
wednesday: { open: '11:00 AM', close: '9:00 PM' },
thursday: { open: '11:00 AM', close: '9:00 PM' },
friday: { open: '11:00 AM', close: '9:30 PM' },
saturday: { open: '9:00 AM', close: '9:00 PM' },
sunday: { open: '11:00 AM', close: '9:00 PM' },
});
const [prices, setPrices] = useState([
{ id: 'camarones-diabla', name: 'Camarones a la Diabla', price: '24.00' },
{ id: 'ceviche-pina', name: 'Ceviche en su Piña', price: '28.00' },
{ id: 'molcajete-mixto', name: 'Molcajete Mixto', price: '38.99' },
{ id: 'tacos-camarones', name: 'Tacos de Camarón', price: '20.00' },
]);
const [menuItems, setMenuItems] = useState([
{ id: '1', name: 'Camarones a la Diabla', description: 'Spicy deviled shrimp', available: true },
{ id: '2', name: 'Ceviche en su Piña', description: 'Ceviche served in pineapple', available: true },
{ id: '3', name: 'Molcajete Mixto', description: 'Mixed molcajete stone bowl', available: true },
{ id: '4', name: 'Tacos de Camarón', description: 'Fresh shrimp tacos', available: true },
]);
const [newItem, setNewItem] = useState({ name: '', description: '' });
const handleHourChange = (day: string, field: 'open' | 'close', value: string) => {
setHours(prev => ({
...prev,
[day]: { ...prev[day as keyof typeof hours], [field]: value }
}));
};
const handlePriceChange = (id: string, price: string) => {
setPrices(prev => prev.map(p => p.id === id ? { ...p, price } : p));
};
const handleToggleMenuItem = (id: string) => {
setMenuItems(prev => prev.map(item => item.id === id ? { ...item, available: !item.available } : item));
};
const handleAddMenuItem = () => {
if (newItem.name && newItem.description) {
setMenuItems(prev => [...prev, { id: Date.now().toString(), name: newItem.name, description: newItem.description, available: true }]);
setNewItem({ name: '', description: '' });
}
};
const dashboardData = {
title: 'Admin Dashboard',
stats: [
{ label: 'Active Orders', value: '12', icon: Settings },
{ label: 'Menu Items', value: String(menuItems.length), icon: UtensilsCrossed },
{ label: 'Today\'s Revenue', value: '$1,240', icon: DollarSign }
] as [any, any, any],
logoIcon: Settings,
sidebarItems: [
{ label: 'Hours', icon: Clock, active: activeTab === 'hours' },
{ label: 'Prices', icon: DollarSign, active: activeTab === 'prices' },
{ label: 'Menu', icon: UtensilsCrossed, active: activeTab === 'menu' }
],
buttons: [
{ text: 'Save Changes', onClick: () => alert('Changes saved!') },
{ text: 'Preview', onClick: () => alert('Preview mode') }
],
listItems: [
{ title: 'Settings', status: 'active', icon: Settings },
{ title: 'Logout', status: 'active', icon: LogOut }
],
imageSrc: 'https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3Am2LJhLLWUokyhthLvKyFV0QpK/uploaded-1773512918447-hg7wldhe.png',
searchPlaceholder: 'Search orders...',
chartTitle: 'Weekly Revenue',
chartData: [
{ day: 'Mon', value: 450 },
{ day: 'Tue', value: 520 },
{ day: 'Wed', value: 480 },
{ day: 'Thu', value: 610 },
{ day: 'Fri', value: 890 },
{ day: 'Sat', value: 1200 },
{ day: 'Sun', value: 950 }
],
listTitle: 'Quick Actions'
};
return (
<ThemeProvider
defaultButtonVariant="elastic-effect"
defaultTextAnimation="entrance-slide"
borderRadius="pill"
contentWidth="small"
sizing="largeSizeMediumTitles"
background="none"
cardStyle="gradient-mesh"
primaryButtonStyle="flat"
secondaryButtonStyle="solid"
headingFontWeight="extrabold"
>
<div id="nav" data-section="nav">
<NavbarStyleCentered
brandName="Mariscos Mi Tierra - Admin"
navItems={[
{ name: "Dashboard", id: "dashboard" },
{ name: "Hours", id: "admin-hours" },
{ name: "Menu", id: "admin" },
{ name: "Prices", id: "admin-prices" }
]}
button={{ text: "Logout", href: "/" }}
/>
</div>
<div id="hero" data-section="hero">
<HeroBillboardDashboard
title="Restaurant Management"
description="Manage your restaurant's hours, prices, and menu items from one centralized dashboard."
background={{ variant: "plain" }}
dashboard={dashboardData}
/>
</div>
<div className="max-w-6xl mx-auto px-4 py-16">
<div className="flex gap-8">
{/* Sidebar Navigation */}
<div className="w-48 flex flex-col gap-4">
<button
onClick={() => setActiveTab('hours')}
className={`px-6 py-3 rounded-lg font-semibold transition-all ${
activeTab === 'hours'
? 'bg-primary-cta text-white'
: 'bg-card text-foreground hover:bg-card/80'
}`}
>
<Clock className="inline mr-2 w-4 h-4" />
Operating Hours
</button>
<button
onClick={() => setActiveTab('prices')}
className={`px-6 py-3 rounded-lg font-semibold transition-all ${
activeTab === 'prices'
? 'bg-primary-cta text-white'
: 'bg-card text-foreground hover:bg-card/80'
}`}
>
<DollarSign className="inline mr-2 w-4 h-4" />
Prices
</button>
<button
onClick={() => setActiveTab('menu')}
className={`px-6 py-3 rounded-lg font-semibold transition-all ${
activeTab === 'menu'
? 'bg-primary-cta text-white'
: 'bg-card text-foreground hover:bg-card/80'
}`}
>
<UtensilsCrossed className="inline mr-2 w-4 h-4" />
Menu Items
</button>
</div>
{/* Main Content */}
<div className="flex-1">
{/* Operating Hours Tab */}
{activeTab === 'hours' && (
<div className="bg-card p-8 rounded-xl">
<h2 className="text-3xl font-extrabold text-foreground mb-6">Operating Hours</h2>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
{Object.entries(hours).map(([day, times]) => (
<div key={day} className="flex flex-col gap-3">
<label className="text-lg font-semibold text-foreground capitalize">{day}</label>
{day === 'monday' && times.open === 'Closed' ? (
<div className="text-foreground/70 font-semibold">Closed</div>
) : (
<div className="flex gap-3">
<input
type="text"
value={times.open}
onChange={(e) => handleHourChange(day, 'open', e.target.value)}
placeholder="Opening time"
className="flex-1 px-4 py-2 bg-background border border-foreground/20 rounded-lg text-foreground"
/>
<input
type="text"
value={times.close}
onChange={(e) => handleHourChange(day, 'close', e.target.value)}
placeholder="Closing time"
className="flex-1 px-4 py-2 bg-background border border-foreground/20 rounded-lg text-foreground"
/>
</div>
)}
</div>
))}
</div>
<button className="mt-8 px-8 py-3 bg-primary-cta text-white font-semibold rounded-lg hover:opacity-90 transition-all">
Save Hours
</button>
</div>
)}
{/* Prices Tab */}
{activeTab === 'prices' && (
<div className="bg-card p-8 rounded-xl">
<h2 className="text-3xl font-extrabold text-foreground mb-6">Menu Prices</h2>
<div className="space-y-4">
{prices.map((item) => (
<div key={item.id} className="flex items-center gap-4 p-4 bg-background rounded-lg">
<div className="flex-1">
<p className="font-semibold text-foreground">{item.name}</p>
</div>
<div className="flex items-center gap-2">
<span className="text-foreground/70">$</span>
<input
type="number"
step="0.01"
value={item.price}
onChange={(e) => handlePriceChange(item.id, e.target.value)}
className="w-24 px-3 py-2 bg-card border border-foreground/20 rounded-lg text-foreground"
/>
</div>
</div>
))}
</div>
<button className="mt-8 px-8 py-3 bg-primary-cta text-white font-semibold rounded-lg hover:opacity-90 transition-all">
Save Prices
</button>
</div>
)}
{/* Menu Items Tab */}
{activeTab === 'menu' && (
<div className="bg-card p-8 rounded-xl">
<h2 className="text-3xl font-extrabold text-foreground mb-6">Menu Management</h2>
{/* Add New Item */}
<div className="mb-8 p-6 bg-background rounded-lg border border-foreground/10">
<h3 className="text-xl font-semibold text-foreground mb-4">Add New Item</h3>
<div className="flex flex-col gap-4">
<input
type="text"
value={newItem.name}
onChange={(e) => setNewItem({ ...newItem, name: e.target.value })}
placeholder="Item name"
className="px-4 py-2 bg-card border border-foreground/20 rounded-lg text-foreground"
/>
<input
type="text"
value={newItem.description}
onChange={(e) => setNewItem({ ...newItem, description: e.target.value })}
placeholder="Item description"
className="px-4 py-2 bg-card border border-foreground/20 rounded-lg text-foreground"
/>
<button
onClick={handleAddMenuItem}
className="px-6 py-2 bg-primary-cta text-white font-semibold rounded-lg hover:opacity-90 transition-all"
>
Add Item
</button>
</div>
</div>
{/* Menu Items List */}
<div className="space-y-3">
{menuItems.map((item) => (
<div key={item.id} className="flex items-center justify-between p-4 bg-background rounded-lg">
<div>
<p className="font-semibold text-foreground">{item.name}</p>
<p className="text-sm text-foreground/70">{item.description}</p>
</div>
<button
onClick={() => handleToggleMenuItem(item.id)}
className={`px-4 py-2 rounded-lg font-semibold transition-all ${
item.available
? 'bg-green-500/20 text-green-600 hover:bg-green-500/30'
: 'bg-red-500/20 text-red-600 hover:bg-red-500/30'
}`}
>
{item.available ? 'Available' : 'Unavailable'}
</button>
</div>
))}
</div>
<button className="mt-8 px-8 py-3 bg-primary-cta text-white font-semibold rounded-lg hover:opacity-90 transition-all">
Save Menu Changes
</button>
</div>
)}
</div>
</div>
</div>
<div id="footer" data-section="footer">
<FooterLogoEmphasis
logoText="Mariscos Mi Tierra Admin"
columns={[
{
items: [
{ label: "Dashboard", href: "/admin" },
{ label: "Settings", href: "#" },
]
},
{
items: [
{ label: "Back to Main", href: "/" },
{ label: "Help", href: "#" },
]
},
{
items: [
{ label: "Terms", href: "#" },
{ label: "Privacy", href: "#" },
]
},
{
items: [
{ label: "Logout", href: "/" },
]
}
]}
/>
</div>
</ThemeProvider>
);
}

View File

@@ -197,55 +197,94 @@ export default function LandingPage() {
</div>
<div id="testimonials" data-section="testimonials">
<TestimonialCardSixteen
title="What Our Customers Say"
description="Hear from families and friends who have experienced our authentic Mexican seafood"
tag="Customer Reviews"
tagAnimation="slide-up"
testimonials={[
{
id: "testimonial-1", name: "Maria Rodriguez", role: "Family Visit", company: "Spokane Valley", rating: 5,
imageSrc: "http://img.b2bpic.net/free-photo/beautiful-woman-cafe_273609-12690.jpg", imageAlt: "Maria Rodriguez"
},
{
id: "testimonial-2", name: "Juan Martinez", role: "Regular Customer", company: "Local Business Owner", rating: 5,
imageSrc: "http://img.b2bpic.net/free-photo/life-after-covid-freedom-concept_23-2149068470.jpg", imageAlt: "Juan Martinez"
},
{
id: "testimonial-3", name: "Carmen Delgado", role: "Food Enthusiast", company: "Community Member", rating: 5,
imageSrc: "http://img.b2bpic.net/free-photo/young-woman-cafe-dines-traditional-shakshuka-ayran_169016-16512.jpg", imageAlt: "Carmen Delgado"
},
{
id: "testimonial-4", name: "Miguel Santos", role: "Weekly Visitor", company: "Spokane Valley Resident", rating: 5,
imageSrc: "http://img.b2bpic.net/free-photo/group-friends-having-lunch-together-restaurant_23-2150520106.jpg", imageAlt: "Miguel Santos"
},
{
id: "testimonial-5", name: "Rosa Hernandez", role: "Event Host", company: "Community Organizer", rating: 5,
imageSrc: "http://img.b2bpic.net/free-photo/adults-enjoying-mexican-food_23-2149663840.jpg", imageAlt: "Rosa Hernandez"
},
{
id: "testimonial-6", name: "Diego Flores", role: "Seafood Lover", company: "Restaurant Critic", rating: 5,
imageSrc: "http://img.b2bpic.net/free-photo/portrait-beautiful-afro-american-woman_23-2148332136.jpg", imageAlt: "Diego Flores"
}
]}
kpiItems={[
{ value: "4.9/5", label: "Average Rating" },
{ value: "500+", label: "Happy Customers" },
{ value: "15 Years", label: "Community Trust" }
]}
animationType="slide-up"
textboxLayout="default"
useInvertedBackground={true}
containerClassName="py-16 md:py-24"
textBoxTitleClassName="text-4xl md:text-5xl font-extrabold text-foreground"
textBoxDescriptionClassName="text-lg text-foreground/70 mt-2"
textBoxTagClassName="text-primary-cta font-semibold"
cardClassName="p-6 rounded-xl"
ratingClassName="text-primary-cta font-bold"
nameClassName="text-lg font-bold text-foreground mt-3"
roleClassName="text-sm text-foreground/70"
companyClassName="text-xs text-foreground/50 mt-1"
/>
<div className="w-full bg-background/50 py-16 md:py-24">
<div className="max-w-6xl mx-auto px-4">
<div className="mb-12">
<p className="text-primary-cta font-semibold mb-2">Menu Gallery</p>
<h2 className="text-4xl md:text-5xl font-extrabold text-foreground mb-4">Our Menu</h2>
<p className="text-lg text-foreground/70">Browse our complete menu of authentic Mexican seafood dishes</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
{[
{
id: "menu-1", src: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3Am2LJhLLWUokyhthLvKyFV0QpK/uploaded-1773513245125-nxkivr1l.jpg", alt: "Menu Page 1"
},
{
id: "menu-2", src: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3Am2LJhLLWUokyhthLvKyFV0QpK/uploaded-1773513245125-z5zcdzr7.jpg", alt: "Menu Page 2"
},
{
id: "menu-3", src: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3Am2LJhLLWUokyhthLvKyFV0QpK/uploaded-1773513245125-lmmbhlch.jpg", alt: "Menu Page 3"
},
{
id: "menu-4", src: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3Am2LJhLLWUokyhthLvKyFV0QpK/uploaded-1773513245125-gdotl1bc.jpg", alt: "Menu Page 4"
}
].map((menu) => (
<div
key={menu.id}
className="relative group cursor-pointer overflow-hidden rounded-xl shadow-lg hover:shadow-xl transition-all duration-300"
onClick={() => {
const modal = document.getElementById(`modal-${menu.id}`);
if (modal) modal.classList.remove('hidden');
}}
>
<img
src={menu.src}
alt={menu.alt}
className="w-full h-auto object-cover group-hover:scale-105 transition-transform duration-300"
/>
<div className="absolute inset-0 bg-black/0 group-hover:bg-black/30 transition-all duration-300 flex items-center justify-center">
<span className="text-white font-semibold text-lg opacity-0 group-hover:opacity-100 transition-opacity duration-300">
Click to Enlarge
</span>
</div>
</div>
))}
</div>
{/* Modal for enlarged images */}
{[
{
id: "menu-1", src: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3Am2LJhLLWUokyhthLvKyFV0QpK/uploaded-1773513245125-nxkivr1l.jpg", alt: "Menu Page 1"
},
{
id: "menu-2", src: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3Am2LJhLLWUokyhthLvKyFV0QpK/uploaded-1773513245125-z5zcdzr7.jpg", alt: "Menu Page 2"
},
{
id: "menu-3", src: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3Am2LJhLLWUokyhthLvKyFV0QpK/uploaded-1773513245125-lmmbhlch.jpg", alt: "Menu Page 3"
},
{
id: "menu-4", src: "https://webuild-dev.s3.eu-north-1.amazonaws.com/users/user_3Am2LJhLLWUokyhthLvKyFV0QpK/uploaded-1773513245125-gdotl1bc.jpg", alt: "Menu Page 4"
}
].map((menu) => (
<div
key={`modal-${menu.id}`}
id={`modal-${menu.id}`}
className="hidden fixed inset-0 bg-black/80 z-50 flex items-center justify-center p-4"
onClick={(e) => {
if (e.target === e.currentTarget) {
e.currentTarget.classList.add('hidden');
}
}}
>
<div className="relative max-w-4xl max-h-[90vh] w-full">
<img
src={menu.src}
alt={menu.alt}
className="w-full h-auto max-h-[90vh] object-contain"
/>
<button
onClick={() => {
const modal = document.getElementById(`modal-${menu.id}`);
if (modal) modal.classList.add('hidden');
}}
className="absolute top-4 right-4 bg-white text-black rounded-full w-10 h-10 flex items-center justify-center font-bold hover:bg-foreground hover:text-white transition-all"
>
</button>
</div>
</div>
))}
</div>
</div>
</div>
<div id="footer" data-section="footer">
@@ -279,7 +318,7 @@ export default function LandingPage() {
items: [
{ label: "Privacy Policy", href: "#" },
{ label: "Terms of Service", href: "#" },
{ label: "Contact", href: "tel:(509) 928-0513" }
{ label: "Admin", href: "/admin" }
]
}
]}
@@ -291,4 +330,4 @@ export default function LandingPage() {
</div>
</ThemeProvider>
);
}
}

View File

@@ -10,15 +10,15 @@
--accent: #ffffff;
--background-accent: #ffffff; */
--background: #f7f6f7;
--card: #ffffff;
--foreground: #25190c;
--primary-cta: #ff6207;
--primary-cta-text: #f7f6f7;
--secondary-cta: #ffffff;
--secondary-cta-text: #25190c;
--accent: #ffce93;
--background-accent: #e8cfa8;
--background: #e8dcc4;
--card: #f5f0e6;
--foreground: #3d2817;
--primary-cta: #a67c52;
--primary-cta-text: #ffffff;
--secondary-cta: #f5f0e6;
--secondary-cta-text: #3d2817;
--accent: #d4b896;
--background-accent: #c9a876;
/* text sizing - set by ThemeProvider */
/* --text-2xs: clamp(0.465rem, 0.62vw, 0.62rem);