coockies und so

This commit is contained in:
Timo Knuth 2026-02-02 15:05:05 +01:00
parent b7cb413605
commit 609e3eb0ae
9 changed files with 1102 additions and 15 deletions

View File

@ -21,6 +21,12 @@ const Checkout = lazy(() => import('./pages/Checkout'));
const MockPayment = lazy(() => import('./pages/MockPayment'));
const Success = lazy(() => import('./pages/Success'));
const Admin = lazy(() => import('./pages/Admin'));
const FAQ = lazy(() => import('./pages/FAQ'));
const Shipping = lazy(() => import('./pages/Shipping'));
const Returns = lazy(() => import('./pages/Returns'));
const Contact = lazy(() => import('./pages/Contact'));
const Privacy = lazy(() => import('./pages/Privacy'));
const Cookies = lazy(() => import('./pages/Cookies'));
function App() {
return (
@ -42,6 +48,12 @@ function App() {
<Route path="/mock-payment" element={<MockPayment />} />
<Route path="/success" element={<Success />} />
<Route path="/admin" element={<Admin />} />
<Route path="/faq" element={<FAQ />} />
<Route path="/shipping" element={<Shipping />} />
<Route path="/returns" element={<Returns />} />
<Route path="/contact" element={<Contact />} />
<Route path="/privacy" element={<Privacy />} />
<Route path="/cookies" element={<Cookies />} />
</Routes>
</Suspense>
</RouteTransition>

View File

@ -1,4 +1,5 @@
import React from 'react';
import { Link } from 'react-router-dom';
import { FOOTER_LINKS } from '../constants';
const Footer: React.FC = () => {
@ -42,9 +43,9 @@ const Footer: React.FC = () => {
<ul className="space-y-6">
{FOOTER_LINKS[0].links.map((link) => (
<li key={link.label}>
<a className="text-lg font-light hover:text-stone-400 hover:pl-2 transition-all duration-300 block" href={link.href}>
<Link className="text-lg font-light hover:text-stone-400 hover:pl-2 transition-all duration-300 block" to={link.href}>
{link.label}
</a>
</Link>
</li>
))}
</ul>
@ -54,9 +55,9 @@ const Footer: React.FC = () => {
<ul className="space-y-6">
{FOOTER_LINKS[1].links.map((link) => (
<li key={link.label}>
<a className="text-lg font-light hover:text-stone-400 hover:pl-2 transition-all duration-300 block" href={link.href}>
<Link className="text-lg font-light hover:text-stone-400 hover:pl-2 transition-all duration-300 block" to={link.href}>
{link.label}
</a>
</Link>
</li>
))}
</ul>
@ -66,9 +67,9 @@ const Footer: React.FC = () => {
<ul className="space-y-6">
{FOOTER_LINKS[2].links.map((link) => (
<li key={link.label}>
<a className="text-lg font-light hover:text-stone-400 hover:pl-2 transition-all duration-300 block" href={link.href}>
<Link className="text-lg font-light hover:text-stone-400 hover:pl-2 transition-all duration-300 block" to={link.href}>
{link.label}
</a>
</Link>
</li>
))}
</ul>
@ -78,12 +79,12 @@ const Footer: React.FC = () => {
{/* Bottom Bar */}
<div className="border-t border-white/10 pt-12 flex flex-col md:flex-row justify-between items-center text-xs text-stone-500 tracking-widest uppercase font-light">
<p>© 2024 HOTSCHPOTSH Ceramics. All rights reserved.</p>
<p>© 2025 HOTSCHPOTSH Ceramics. All rights reserved.</p>
<div className="flex space-x-8 mt-6 md:mt-0">
<a className="hover:text-white transition-colors" href="#">Privacy</a>
<a className="hover:text-white transition-colors" href="#">Terms</a>
<a className="hover:text-white transition-colors" href="#">Cookies</a>
<a className="hover:text-white transition-colors" href="/admin">Admin</a>
<Link className="hover:text-white transition-colors" to="/privacy">Privacy</Link>
<Link className="hover:text-white transition-colors" to="/returns">Terms</Link>
<Link className="hover:text-white transition-colors" to="/cookies">Cookies</Link>
<Link className="hover:text-white transition-colors" to="/admin">Admin</Link>
</div>
</div>
</div>

View File

@ -139,10 +139,10 @@ export const FOOTER_LINKS: FooterSection[] = [
{
title: 'Support',
links: [
{ label: 'FAQ', href: '#' },
{ label: 'Shipping', href: '#' },
{ label: 'Returns', href: '#' },
{ label: 'Contact', href: '#' },
{ label: 'FAQ', href: '/faq' },
{ label: 'Shipping', href: '/shipping' },
{ label: 'Returns', href: '/returns' },
{ label: 'Contact', href: '/contact' },
],
},
];

View File

@ -0,0 +1,218 @@
import React, { useState } from 'react';
import { motion } from 'framer-motion';
const Contact: React.FC = () => {
const [formData, setFormData] = useState({
name: '',
email: '',
subject: '',
message: ''
});
const handleSubmit = (e: React.FormEvent) => {
e.preventDefault();
// Handle form submission
console.log('Form submitted:', formData);
alert('Thank you for your message! We\'ll get back to you within 1-2 business days.');
setFormData({ name: '', email: '', subject: '', message: '' });
};
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) => {
setFormData({
...formData,
[e.target.name]: e.target.value
});
};
const contactInfo = [
{
icon: "📧",
title: "Email",
detail: "support@hotchpotshceramics.com",
description: "Best for order inquiries or detailed questions"
},
{
icon: "📞",
title: "Phone",
detail: "(361) 555-1234",
description: "MonFri, 9am5pm CST"
},
{
icon: "📍",
title: "Workshop",
detail: "123 Artisan Lane, Corpus Christi, TX 78401",
description: "Please note: this is our workshop, not a retail store"
}
];
return (
<div className="bg-stone-50 dark:bg-stone-900 min-h-screen pt-32 pb-24">
<div className="max-w-[1400px] mx-auto px-6 md:px-12">
{/* Header */}
<div className="mb-24 max-w-3xl">
<motion.span
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 1 }}
className="block text-xs uppercase tracking-[0.3em] text-stone-400 mb-6"
>
Get in Touch
</motion.span>
<motion.h1
initial={{ y: 30, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ delay: 0.2, duration: 0.8 }}
className="font-display text-5xl md:text-7xl lg:text-8xl leading-none text-text-main dark:text-white mb-8"
>
Contact<br />Us
</motion.h1>
<motion.p
initial={{ y: 30, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ delay: 0.4, duration: 0.8 }}
className="font-body text-lg font-light text-stone-500 leading-relaxed"
>
We're happy to help with any questions, custom requests, or feedback. We usually reply to emails within 12 business days.
</motion.p>
</div>
<div className="grid grid-cols-1 lg:grid-cols-2 gap-16 mb-24">
{/* Contact Form */}
<motion.div
initial={{ y: 30, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ delay: 0.5, duration: 0.8 }}
>
<h2 className="font-display text-3xl mb-8 text-text-main dark:text-white">
Send us a message
</h2>
<form onSubmit={handleSubmit} className="space-y-6">
<div>
<label className="block text-xs uppercase tracking-widest text-stone-500 mb-3">
Name *
</label>
<input
type="text"
name="name"
value={formData.name}
onChange={handleChange}
required
className="w-full px-6 py-4 bg-white dark:bg-black border border-stone-200 dark:border-stone-800 focus:border-stone-400 dark:focus:border-stone-600 outline-none transition-colors text-text-main dark:text-white"
/>
</div>
<div>
<label className="block text-xs uppercase tracking-widest text-stone-500 mb-3">
Email *
</label>
<input
type="email"
name="email"
value={formData.email}
onChange={handleChange}
required
className="w-full px-6 py-4 bg-white dark:bg-black border border-stone-200 dark:border-stone-800 focus:border-stone-400 dark:focus:border-stone-600 outline-none transition-colors text-text-main dark:text-white"
/>
</div>
<div>
<label className="block text-xs uppercase tracking-widest text-stone-500 mb-3">
Subject
</label>
<select
name="subject"
value={formData.subject}
onChange={handleChange}
className="w-full px-6 py-4 bg-white dark:bg-black border border-stone-200 dark:border-stone-800 focus:border-stone-400 dark:focus:border-stone-600 outline-none transition-colors text-text-main dark:text-white"
>
<option value="">Select a subject</option>
<option value="order">Order Inquiry</option>
<option value="custom">Custom Request</option>
<option value="shipping">Shipping Question</option>
<option value="return">Return/Exchange</option>
<option value="other">Other</option>
</select>
</div>
<div>
<label className="block text-xs uppercase tracking-widest text-stone-500 mb-3">
Message *
</label>
<textarea
name="message"
value={formData.message}
onChange={handleChange}
required
rows={6}
className="w-full px-6 py-4 bg-white dark:bg-black border border-stone-200 dark:border-stone-800 focus:border-stone-400 dark:focus:border-stone-600 outline-none transition-colors resize-none text-text-main dark:text-white"
/>
</div>
<button
type="submit"
className="w-full bg-primary dark:bg-white text-white dark:text-black px-10 py-4 text-xs font-bold uppercase tracking-widest hover:bg-stone-800 dark:hover:bg-stone-200 transition-colors"
>
Send Message
</button>
</form>
</motion.div>
{/* Contact Information */}
<div className="space-y-8">
{contactInfo.map((info, index) => (
<motion.div
key={info.title}
initial={{ y: 20, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ delay: 0.6 + index * 0.1, duration: 0.6 }}
className="p-8 bg-white dark:bg-black border border-stone-200 dark:border-stone-800"
>
<div className="text-4xl mb-4">{info.icon}</div>
<h3 className="font-display text-2xl mb-2 text-text-main dark:text-white">
{info.title}
</h3>
<p className="font-body text-lg text-text-main dark:text-white mb-2">
{info.detail}
</p>
<p className="font-body font-light text-sm text-stone-500">
{info.description}
</p>
</motion.div>
))}
</div>
</div>
{/* Social Media */}
<motion.div
initial={{ y: 30, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ delay: 1, duration: 0.8 }}
className="text-center p-12 bg-stone-100 dark:bg-black border border-stone-200 dark:border-stone-800"
>
<h3 className="font-display text-3xl mb-4 text-text-main dark:text-white">
Follow Our Journey
</h3>
<p className="font-body font-light text-stone-500 mb-8">
Connect with us on Instagram or Facebook for new releases and behind-the-scenes peeks.
</p>
<div className="flex justify-center gap-6">
<a
href="https://instagram.com/hotchpotshceramics"
target="_blank"
rel="noopener noreferrer"
className="px-8 py-3 bg-white dark:bg-stone-900 text-black dark:text-white border border-stone-300 dark:border-stone-700 text-xs font-bold uppercase tracking-widest hover:bg-stone-100 dark:hover:bg-stone-800 transition-colors"
>
Instagram
</a>
<a
href="https://facebook.com/hotchpotshceramics"
target="_blank"
rel="noopener noreferrer"
className="px-8 py-3 bg-white dark:bg-stone-900 text-black dark:text-white border border-stone-300 dark:border-stone-700 text-xs font-bold uppercase tracking-widest hover:bg-stone-100 dark:hover:bg-stone-800 transition-colors"
>
Facebook
</a>
</div>
</motion.div>
</div>
</div>
);
};
export default Contact;

View File

@ -0,0 +1,194 @@
import React from 'react';
import { Link } from 'react-router-dom';
import { motion } from 'framer-motion';
const Cookies: React.FC = () => {
const cookieTypes = [
{
type: "Essential Cookies",
icon: "🔒",
description: "These are necessary for basic site functions (like keeping items in your cart, secure login, etc.) and cannot be turned off without affecting the site.",
canDisable: false
},
{
type: "Analytics Cookies",
icon: "📊",
description: "We use Google Analytics to learn how customers find and use our site. These cookies help us improve content, layout, and functionality.",
canDisable: true,
example: "Google Analytics"
},
{
type: "Marketing Cookies",
icon: "🎯",
description: "If you opt-in, we may use cookies to show you personalized ads or to measure ad performance (e.g. Facebook Pixel, Google AdWords). No personal information is stored just anonymous data to track which ads work best.",
canDisable: true,
example: "Facebook Pixel, Google AdWords"
}
];
return (
<div className="bg-stone-50 dark:bg-stone-900 min-h-screen pt-32 pb-24">
<div className="max-w-[1200px] mx-auto px-6 md:px-12">
{/* Header */}
<div className="mb-24">
<motion.span
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 1 }}
className="block text-xs uppercase tracking-[0.3em] text-stone-400 mb-6"
>
Legal Information
</motion.span>
<motion.h1
initial={{ y: 30, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ delay: 0.2, duration: 0.8 }}
className="font-display text-5xl md:text-7xl lg:text-8xl leading-none text-text-main dark:text-white mb-8"
>
Cookie<br />Policy
</motion.h1>
<motion.p
initial={{ y: 30, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ delay: 0.4, duration: 0.8 }}
className="font-body text-lg font-light text-stone-500 leading-relaxed max-w-3xl"
>
We use cookies and similar technologies to make our website work better for you. Cookies are small text files stored on your device. Here's how we use them and how you can control them.
</motion.p>
<motion.p
initial={{ y: 30, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ delay: 0.5, duration: 0.8 }}
className="font-body text-sm font-light text-stone-400 mt-4"
>
Last Updated: February 2, 2025
</motion.p>
</div>
{/* What Are Cookies */}
<motion.div
initial={{ y: 30, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ delay: 0.6, duration: 0.6 }}
className="mb-16 p-8 bg-amber-50 dark:bg-amber-900/10 border-l-4 border-amber-500"
>
<h2 className="font-display text-2xl mb-4 text-text-main dark:text-white">
What Are Cookies?
</h2>
<p className="font-body font-light text-stone-700 dark:text-stone-300 leading-relaxed">
Cookies are small text files that websites store on your computer or mobile device when you visit them. They help the website remember information about your visit, like your preferred language, items in your shopping cart, and other settings. This makes your next visit easier and the site more useful to you.
</p>
</motion.div>
{/* Cookie Types */}
<div className="mb-24">
<h2 className="font-display text-4xl md:text-5xl mb-12 text-text-main dark:text-white">
Types of Cookies We Use
</h2>
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
{cookieTypes.map((cookie, index) => (
<motion.div
key={cookie.type}
initial={{ y: 20, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ delay: 0.7 + index * 0.1, duration: 0.6 }}
className="p-8 bg-white dark:bg-black border border-stone-200 dark:border-stone-800"
>
<div className="text-5xl mb-6">{cookie.icon}</div>
<h3 className="font-display text-2xl mb-4 text-text-main dark:text-white">
{cookie.type}
</h3>
<p className="font-body font-light text-stone-600 dark:text-stone-400 leading-relaxed mb-4">
{cookie.description}
</p>
{cookie.example && (
<p className="font-body text-sm text-stone-500 italic">
Examples: {cookie.example}
</p>
)}
<div className="mt-6 pt-6 border-t border-stone-200 dark:border-stone-800">
<span className={`inline-block px-4 py-2 text-xs font-bold uppercase tracking-widest ${cookie.canDisable ? 'bg-green-100 dark:bg-green-900/30 text-green-800 dark:text-green-400' : 'bg-stone-200 dark:bg-stone-800 text-stone-600 dark:text-stone-400'}`}>
{cookie.canDisable ? 'Can be disabled' : 'Always active'}
</span>
</div>
</motion.div>
))}
</div>
</div>
{/* Managing Cookies */}
<motion.div
initial={{ y: 30, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ delay: 1, duration: 0.6 }}
className="mb-16 border-l-2 border-stone-300 dark:border-stone-700 pl-8"
>
<h2 className="font-display text-3xl md:text-4xl mb-6 text-text-main dark:text-white">
Managing Your Cookie Preferences
</h2>
<div className="space-y-4 font-body font-light text-stone-600 dark:text-stone-400 leading-relaxed">
<p>
You can control or disable cookies in your browser settings. However, disabling cookies may limit your ability to use some features (like staying logged in or completing a purchase).
</p>
<p>
By continuing to use our site without changing your settings, you consent to the use of cookies as described in this policy.
</p>
<p className="font-semibold text-text-main dark:text-white">
Browser Cookie Settings:
</p>
<ul className="list-disc list-inside space-y-2 ml-4">
<li><strong>Chrome:</strong> Settings Privacy and security Cookies and other site data</li>
<li><strong>Firefox:</strong> Preferences Privacy & Security Cookies and Site Data</li>
<li><strong>Safari:</strong> Preferences Privacy Manage Website Data</li>
<li><strong>Edge:</strong> Settings Cookies and site permissions Manage and delete cookies</li>
</ul>
</div>
</motion.div>
{/* Third-Party Cookies */}
<motion.div
initial={{ y: 30, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ delay: 1.2, duration: 0.6 }}
className="mb-16 p-8 bg-white dark:bg-black border border-stone-200 dark:border-stone-800"
>
<h2 className="font-display text-3xl mb-4 text-text-main dark:text-white">
Third-Party Cookies
</h2>
<p className="font-body font-light text-stone-600 dark:text-stone-400 leading-relaxed mb-4">
Some cookies on our site are set by third-party services we use, such as:
</p>
<ul className="list-disc list-inside space-y-2 font-body font-light text-stone-600 dark:text-stone-400 ml-4">
<li><strong>Google Analytics:</strong> To understand how visitors use our site</li>
<li><strong>Payment Processors:</strong> To securely process transactions</li>
<li><strong>Social Media Platforms:</strong> If you interact with embedded social media content</li>
</ul>
<p className="font-body font-light text-stone-600 dark:text-stone-400 leading-relaxed mt-4">
These third parties have their own privacy policies governing their use of your information. We recommend reviewing their policies to understand how they use cookies.
</p>
</motion.div>
{/* Contact */}
<motion.div
initial={{ y: 30, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ delay: 1.4, duration: 0.8 }}
className="p-12 bg-primary dark:bg-black text-white text-center border border-stone-800"
>
<h2 className="font-display text-3xl mb-4">Questions About Cookies?</h2>
<p className="font-body font-light text-stone-300 mb-8 max-w-2xl mx-auto">
For any questions about cookies or to opt-out of analytics tracking, please contact us at <strong>support@hotchpotshceramics.com</strong>
</p>
<Link
to="/contact"
className="inline-block bg-white text-black px-10 py-4 text-xs font-bold uppercase tracking-widest hover:bg-stone-200 transition-colors"
>
Contact Us
</Link>
</motion.div>
</div>
</div>
);
};
export default Cookies;

View File

@ -0,0 +1,161 @@
import React, { useState } from 'react';
import { Link } from 'react-router-dom';
import { motion, AnimatePresence } from 'framer-motion';
interface FAQItem {
question: string;
answer: string;
}
const faqData: FAQItem[] = [
{
question: "Are your ceramics safe for food, oven, and dishwasher use?",
answer: "Yes all our pottery is glazed and food-safe. We use durable, non-toxic glazes that are oven-, microwave-, and dishwasher-safe. To extend their life, we still recommend hand-washing and avoiding harsh scrubbing. Treat your ceramicware gently (like any quality dishware) to keep the colors vibrant and the glaze strong."
},
{
question: "How unique is each piece?",
answer: "Every piece in our shop is designed and handcrafted in small batches. That means no two pieces are exactly alike. You will see slight variations and unique markings that make each item one-of-a-kind. We do our best to photograph products accurately, but please allow for some artisanal differences. These natural imperfections are a sign of true craftsmanship."
},
{
question: "How long will it take to receive my order?",
answer: "Once you place an order, please allow 13 business days for us to carefully prepare and package your item (handmade pottery takes a bit of extra time). After that, standard shipping via USPS usually takes 35 business days within the U.S. You'll receive a tracking number by email as soon as your order ships."
},
{
question: "Do you ship outside the USA?",
answer: "Currently we ship nationwide within the U.S. only. We do not offer international shipping at this time. Orders ship from Corpus Christi, Texas. We focus on providing fast, reliable delivery to Texas and all U.S. customers."
},
{
question: "What if my order arrives damaged?",
answer: "We take great care in packaging each piece using recyclable and padded materials. Still, accidents happen. If any item arrives broken or damaged, please contact us immediately. Take a photo of the damage (and packaging, if possible), and email us within 7 days of receipt. All orders are fully insured during transit. Once we review the details, we'll be happy to repair, replace, or refund damaged items at no additional cost to you."
},
{
question: "What is your return/exchange policy?",
answer: "We want you to love your purchase. Because each piece is handmade and unique, all sales are final except in cases of damage or defect. If something isn't right with your order, please let us know. We handle returns or exchanges for defective items (typically within 14 days of delivery). You'll just need to return the piece unused, in its original condition and packaging. (Sorry, we cannot accept returns on change-of-mind or carelessly broken items.) See our Returns page for full details."
},
{
question: "How do I contact you with questions?",
answer: "We're here to help! Feel free to reach out anytime. You can email our customer support at support@hotchpotshceramics.com or use the contact form on our site. We aim to respond within 12 business days. Thank you for choosing Hotchpotsh we love answering your questions and hearing your feedback!"
}
];
const FAQ: React.FC = () => {
const [openIndex, setOpenIndex] = useState<number | null>(null);
const toggleFAQ = (index: number) => {
setOpenIndex(openIndex === index ? null : index);
};
return (
<div className="bg-stone-50 dark:bg-stone-900 min-h-screen pt-32 pb-24">
<div className="max-w-[1200px] mx-auto px-6 md:px-12">
{/* Header */}
<div className="mb-24">
<motion.span
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 1 }}
className="block text-xs uppercase tracking-[0.3em] text-stone-400 mb-6"
>
Help Center
</motion.span>
<motion.h1
initial={{ y: 30, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ delay: 0.2, duration: 0.8 }}
className="font-display text-5xl md:text-7xl lg:text-8xl leading-none text-text-main dark:text-white mb-8"
>
Frequently Asked<br />Questions
</motion.h1>
<motion.p
initial={{ y: 30, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ delay: 0.4, duration: 0.8 }}
className="font-body text-lg font-light text-stone-500 leading-relaxed max-w-2xl"
>
Find answers to common questions about our handcrafted ceramics, shipping, care instructions, and more.
</motion.p>
</div>
{/* FAQ Items */}
<div className="space-y-4">
{faqData.map((item, index) => (
<motion.div
key={index}
initial={{ y: 20, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ delay: index * 0.1, duration: 0.6 }}
className="border border-stone-200 dark:border-stone-800 bg-white dark:bg-black"
>
<button
onClick={() => toggleFAQ(index)}
className="w-full px-8 py-6 flex justify-between items-center hover:bg-stone-50 dark:hover:bg-stone-900 transition-colors"
>
<h3 className="font-body text-lg md:text-xl text-left text-text-main dark:text-white pr-8">
{item.question}
</h3>
<motion.div
animate={{ rotate: openIndex === index ? 45 : 0 }}
transition={{ duration: 0.3 }}
className="flex-shrink-0"
>
<svg
className="w-6 h-6 text-stone-400"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth={1.5}
d="M12 4v16m8-8H4"
/>
</svg>
</motion.div>
</button>
<AnimatePresence>
{openIndex === index && (
<motion.div
initial={{ height: 0, opacity: 0 }}
animate={{ height: "auto", opacity: 1 }}
exit={{ height: 0, opacity: 0 }}
transition={{ duration: 0.3 }}
className="overflow-hidden"
>
<div className="px-8 pb-6 border-t border-stone-100 dark:border-stone-800 pt-6">
<p className="font-body font-light text-stone-600 dark:text-stone-400 leading-relaxed">
{item.answer}
</p>
</div>
</motion.div>
)}
</AnimatePresence>
</motion.div>
))}
</div>
{/* Contact CTA */}
<motion.div
initial={{ y: 30, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ delay: 0.8, duration: 0.8 }}
className="mt-24 p-12 bg-primary dark:bg-black text-white text-center border border-stone-800"
>
<h2 className="font-display text-3xl md:text-4xl mb-4">Still have questions?</h2>
<p className="font-body font-light text-stone-400 mb-8 max-w-xl mx-auto">
We're here to help. Reach out to our customer support team.
</p>
<Link
to="/contact"
className="inline-block bg-white text-black px-10 py-4 text-xs font-bold uppercase tracking-widest hover:bg-stone-200 transition-colors"
>
Contact Us
</Link>
</motion.div>
</div>
</div>
);
};
export default FAQ;

View File

@ -0,0 +1,206 @@
import React from 'react';
import { Link } from 'react-router-dom';
import { motion } from 'framer-motion';
const Privacy: React.FC = () => {
const sections = [
{
title: "Information We Collect",
content: [
{
subtitle: "Account & Order Information",
text: "When you make a purchase or create an account, we collect your name, billing and shipping address, email, phone number, and payment information (handled securely by our payment processor)."
},
{
subtitle: "Site Usage",
text: "We may collect data about how you use our website (such as pages visited, items viewed) through cookies and analytics tools. This is non-identifying information to help us improve our site."
},
{
subtitle: "Communications",
text: "If you contact us by email or fill out our contact form, we collect your message and contact details to respond to you."
}
]
},
{
title: "How We Use Information",
content: [
{
subtitle: "To fulfill orders",
text: "Processing payments, shipping purchases, and sending order confirmations and updates."
},
{
subtitle: "Customer service",
text: "Answering your inquiries, providing support, and improving our products and services."
},
{
subtitle: "Marketing (with consent)",
text: "Sending you newsletters or promotional offers if you opt-in. You can unsubscribe at any time."
},
{
subtitle: "Site improvement",
text: "Analyzing site usage trends to enhance our website and customer experience."
}
]
},
{
title: "Sharing & Third Parties",
content: [
{
subtitle: "We do not sell your personal information",
text: "However, we share limited data with trusted third parties as needed:"
},
{
subtitle: "Shipping and Fulfillment",
text: "We provide your address and order details to USPS or other carriers to deliver your items."
},
{
subtitle: "Payment Processors",
text: "Secure payment details (e.g. credit card) are handled by Stripe/PayPal (your full card number is not stored on our site)."
},
{
subtitle: "Marketing Services",
text: "If you subscribe to our newsletter, we use email marketing platforms (e.g. Mailchimp) to send updates."
},
{
subtitle: "Analytics",
text: "We use Google Analytics to understand website traffic. This service may set cookies and collect usage data, but it does not identify you personally."
}
]
},
{
title: "Your Rights",
content: [
{
subtitle: "Data Access & Control",
text: "Depending on where you live (such as California), you may have certain rights regarding your data. Generally, you can: Access or correct the personal information we hold about you; Request deletion of your data (for example, if you delete your account or unsubscribe from communications); Opt-out of certain uses of your data, like marketing emails."
},
{
subtitle: "Exercise Your Rights",
text: "To exercise any of these rights or with questions about your data, contact us at privacy@hotchpotshceramics.com. We will respond within 30 days."
}
]
},
{
title: "Data Security",
content: [
{
subtitle: "Protection Measures",
text: "We take data security seriously. We use HTTPS/SSL for secure data transmission and follow industry-standard practices to protect your data. Only authorized staff have access to order details, and we never store sensitive payment data on our servers. If a data breach occurs, we will notify affected users in accordance with applicable laws."
}
]
},
{
title: "Children's Privacy",
content: [
{
subtitle: "Age Restrictions",
text: "Our site and products are not intended for children under 13. We do not knowingly collect information from children under 13. If we learn that we have collected such data, we will promptly delete it. If you are a parent or guardian and believe we have information about your child, please contact us."
}
]
}
];
return (
<div className="bg-stone-50 dark:bg-stone-900 min-h-screen pt-32 pb-24">
<div className="max-w-[1200px] mx-auto px-6 md:px-12">
{/* Header */}
<div className="mb-24">
<motion.span
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 1 }}
className="block text-xs uppercase tracking-[0.3em] text-stone-400 mb-6"
>
Legal Information
</motion.span>
<motion.h1
initial={{ y: 30, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ delay: 0.2, duration: 0.8 }}
className="font-display text-5xl md:text-7xl lg:text-8xl leading-none text-text-main dark:text-white mb-8"
>
Privacy<br />Policy
</motion.h1>
<motion.p
initial={{ y: 30, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ delay: 0.4, duration: 0.8 }}
className="font-body text-lg font-light text-stone-500 leading-relaxed max-w-3xl"
>
At HOTCHPOTSH Ceramics, your privacy and trust are important to us. We collect and handle your information responsibly, because 60% of people are more likely to trust brands that protect their data. This policy explains what data we collect, how we use it, and your rights.
</motion.p>
<motion.p
initial={{ y: 30, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ delay: 0.5, duration: 0.8 }}
className="font-body text-sm font-light text-stone-400 mt-4"
>
Last Updated: February 2, 2025
</motion.p>
</div>
{/* Policy Sections */}
<div className="space-y-16">
{sections.map((section, index) => (
<motion.div
key={section.title}
initial={{ y: 30, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ delay: 0.6 + index * 0.1, duration: 0.6 }}
className="border-l-2 border-stone-300 dark:border-stone-700 pl-8"
>
<h2 className="font-display text-3xl md:text-4xl mb-8 text-text-main dark:text-white">
{section.title}
</h2>
<div className="space-y-6">
{section.content.map((item, idx) => (
<div key={idx}>
<h3 className="font-body font-semibold text-lg text-text-main dark:text-white mb-2">
{item.subtitle}
</h3>
<p className="font-body font-light text-stone-600 dark:text-stone-400 leading-relaxed">
{item.text}
</p>
</div>
))}
</div>
</motion.div>
))}
</div>
{/* Contact & Updates */}
<motion.div
initial={{ y: 30, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ delay: 1.2, duration: 0.8 }}
className="mt-24 p-12 bg-primary dark:bg-black text-white border border-stone-800"
>
<h2 className="font-display text-3xl mb-4">Contact & Updates</h2>
<p className="font-body font-light text-stone-300 leading-relaxed mb-6 max-w-3xl">
If you have any privacy questions, or if you want to request or update your personal data, please contact us at <strong>privacy@hotchpotshceramics.com</strong> or use our contact page. We may update this Privacy Policy occasionally to reflect changes in our practices; the latest version will always be posted here with an updated date.
</p>
<p className="font-body font-light text-stone-400 text-sm">
By shopping with us, you acknowledge you have read and agree to this Privacy Policy.
</p>
</motion.div>
{/* Additional Contact */}
<motion.div
initial={{ y: 30, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ delay: 1.4, duration: 0.8 }}
className="mt-12 text-center"
>
<Link
to="/contact"
className="inline-block bg-white dark:bg-stone-800 text-black dark:text-white px-10 py-4 text-xs font-bold uppercase tracking-widest border border-stone-300 dark:border-stone-700 hover:bg-stone-100 dark:hover:bg-stone-700 transition-colors"
>
Contact Us
</Link>
</motion.div>
</div>
</div>
);
};
export default Privacy;

View File

@ -0,0 +1,164 @@
import React from 'react';
import { Link } from 'react-router-dom';
import { motion } from 'framer-motion';
const Returns: React.FC = () => {
const returnSteps = [
{
step: "01",
title: "Contact Us",
description: "Email support@hotchpotshceramics.com within 14 days of delivery with your order number and photos of the item and packaging."
},
{
step: "02",
title: "Receive Instructions",
description: "Our team will review your request and provide detailed return instructions and a return authorization if approved."
},
{
step: "03",
title: "Ship Back",
description: "Carefully package the item with at least 1\" of padding around each piece. Use insured shipping and retain your tracking number."
},
{
step: "04",
title: "Get Refund",
description: "Once we receive and inspect the returned item, we'll process your exchange or refund within 57 business days."
}
];
return (
<div className="bg-stone-50 dark:bg-stone-900 min-h-screen pt-32 pb-24">
<div className="max-w-[1400px] mx-auto px-6 md:px-12">
{/* Header */}
<div className="mb-24 max-w-3xl">
<motion.span
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 1 }}
className="block text-xs uppercase tracking-[0.3em] text-stone-400 mb-6"
>
Customer Care
</motion.span>
<motion.h1
initial={{ y: 30, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ delay: 0.2, duration: 0.8 }}
className="font-display text-5xl md:text-7xl lg:text-8xl leading-none text-text-main dark:text-white mb-8"
>
Returns &<br />Exchanges
</motion.h1>
<motion.p
initial={{ y: 30, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ delay: 0.4, duration: 0.8 }}
className="font-body text-lg font-light text-stone-500 leading-relaxed"
>
We understand that buying handmade ceramics is different than buying mass-produced goods. Because each piece is made just for you, returns are limited. Please review our policy carefully.
</motion.p>
</div>
{/* Policy Details */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 mb-24">
<motion.div
initial={{ y: 20, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ delay: 0.5, duration: 0.6 }}
className="p-8 bg-white dark:bg-black border border-stone-200 dark:border-stone-800"
>
<h3 className="font-display text-2xl mb-4 text-text-main dark:text-white">Eligibility</h3>
<p className="font-body font-light text-stone-600 dark:text-stone-400 leading-relaxed">
We only accept returns for items that are <strong>defective, damaged, or incorrect</strong>. If your item arrived damaged, see the Damaged Items section below. For a refund or exchange, contact us within 14 days of delivery.
</p>
</motion.div>
<motion.div
initial={{ y: 20, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ delay: 0.6, duration: 0.6 }}
className="p-8 bg-white dark:bg-black border border-stone-200 dark:border-stone-800"
>
<h3 className="font-display text-2xl mb-4 text-text-main dark:text-white">Condition</h3>
<p className="font-body font-light text-stone-600 dark:text-stone-400 leading-relaxed">
Returned items must be <strong>unused and in their original packaging</strong> (minus the damage, if any). We reserve the right to refuse returns for pieces showing signs of use or abuse.
</p>
</motion.div>
<motion.div
initial={{ y: 20, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ delay: 0.7, duration: 0.6 }}
className="p-8 bg-white dark:bg-black border border-stone-200 dark:border-stone-800"
>
<h3 className="font-display text-2xl mb-4 text-text-main dark:text-white">Return Shipping</h3>
<p className="font-body font-light text-stone-600 dark:text-stone-400 leading-relaxed">
The customer is responsible for return shipping costs, <strong>except in the case of our error or damage</strong>. We strongly recommend insured shipping and adequate packaging.
</p>
</motion.div>
<motion.div
initial={{ y: 20, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ delay: 0.8, duration: 0.6 }}
className="p-8 bg-white dark:bg-black border border-stone-200 dark:border-stone-800"
>
<h3 className="font-display text-2xl mb-4 text-text-main dark:text-white">Exchanges & Refunds</h3>
<p className="font-body font-light text-stone-600 dark:text-stone-400 leading-relaxed">
Once we receive and inspect the returned item, we will process an exchange or refund promptly. Refunds are issued to the original payment method. Please allow 57 business days for the credit to appear.
</p>
</motion.div>
</div>
{/* Return Process */}
<div className="mb-24">
<h2 className="font-display text-4xl md:text-5xl mb-12 text-text-main dark:text-white">
Return Process
</h2>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
{returnSteps.map((item, index) => (
<motion.div
key={item.step}
initial={{ y: 20, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ delay: 0.9 + index * 0.1, duration: 0.6 }}
className="relative"
>
<div className="absolute top-0 left-0 font-display text-6xl text-stone-200 dark:text-stone-800 -z-10">
{item.step}
</div>
<div className="pt-16">
<h4 className="font-display text-xl mb-3 text-text-main dark:text-white">
{item.title}
</h4>
<p className="font-body font-light text-stone-600 dark:text-stone-400 leading-relaxed text-sm">
{item.description}
</p>
</div>
</motion.div>
))}
</div>
</div>
{/* Damaged Items */}
<motion.div
initial={{ y: 30, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ delay: 1.3, duration: 0.8 }}
className="p-8 md:p-12 bg-primary dark:bg-black text-white border border-stone-800"
>
<h3 className="font-display text-3xl mb-4">Damaged Items</h3>
<p className="font-body font-light text-stone-300 leading-relaxed max-w-3xl mb-6">
If your item arrived broken, please contact us immediately. Take a photo of the damage (and packaging, if possible), and email us within 7 days of receipt. All orders are fully insured during transit. We will cover shipping costs to replace or refund damaged goods.
</p>
<Link
to="/contact"
className="inline-block bg-white text-black px-8 py-3 text-xs font-bold uppercase tracking-widest hover:bg-stone-200 transition-colors"
>
Report Damage
</Link>
</motion.div>
</div>
</div>
);
};
export default Returns;

View File

@ -0,0 +1,131 @@
import React from 'react';
import { Link } from 'react-router-dom';
import { motion } from 'framer-motion';
const Shipping: React.FC = () => {
const shippingDetails = [
{
title: "Order Processing",
description: "Each item is handcrafted and inspected with care. Please allow up to 3 business days for us to prepare and pack your order.",
icon: "📦"
},
{
title: "Shipping Methods",
description: "We offer standard USPS shipping for most orders. For faster delivery, expedited shipping (such as USPS Priority or UPS) is available at checkout. Some oversized or multiple-item orders may ship via UPS Ground.",
icon: "🚚"
},
{
title: "Delivery Time",
description: "After processing, expect 35 business days transit time for standard domestic delivery. Expedited options can arrive in 12 days. Your order confirmation email will include a tracking number.",
icon: "⏱️"
},
{
title: "Free Shipping",
description: "We offer flat-rate shipping on orders under $75. Free standard shipping is available on all orders over $75. These promotions are subject to change, so check the cart for current offers.",
icon: "✨"
},
{
title: "Packaging",
description: "We reuse packing materials and eco-friendly fillers whenever possible to protect your ceramics and reduce waste. Every package is insured for its full value during transit.",
icon: "♻️"
},
{
title: "Shipping Restrictions",
description: "We do not ship to P.O. boxes. Unfortunately, we cannot ship internationally at this time (U.S. addresses only). If you need a rush order, please contact us we'll do our best to accommodate.",
icon: "🇺🇸"
}
];
return (
<div className="bg-stone-50 dark:bg-stone-900 min-h-screen pt-32 pb-24">
<div className="max-w-[1400px] mx-auto px-6 md:px-12">
{/* Header */}
<div className="mb-24 max-w-3xl">
<motion.span
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 1 }}
className="block text-xs uppercase tracking-[0.3em] text-stone-400 mb-6"
>
Delivery Information
</motion.span>
<motion.h1
initial={{ y: 30, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ delay: 0.2, duration: 0.8 }}
className="font-display text-5xl md:text-7xl lg:text-8xl leading-none text-text-main dark:text-white mb-8"
>
Shipping<br />Policy
</motion.h1>
<motion.p
initial={{ y: 30, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ delay: 0.4, duration: 0.8 }}
className="font-body text-lg font-light text-stone-500 leading-relaxed"
>
HOTCHPOTSH Ceramics proudly ships nationwide from our Texas studio. We strive to make delivery smooth and transparent for you.
</motion.p>
</div>
{/* Shipping Details Grid */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-24">
{shippingDetails.map((detail, index) => (
<motion.div
key={detail.title}
initial={{ y: 20, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ delay: index * 0.1, duration: 0.6 }}
className="p-8 bg-white dark:bg-black border border-stone-200 dark:border-stone-800 hover:border-stone-400 dark:hover:border-stone-600 transition-colors"
>
<div className="text-4xl mb-6">{detail.icon}</div>
<h3 className="font-display text-2xl mb-4 text-text-main dark:text-white">
{detail.title}
</h3>
<p className="font-body font-light text-stone-600 dark:text-stone-400 leading-relaxed">
{detail.description}
</p>
</motion.div>
))}
</div>
{/* Important Notice */}
<motion.div
initial={{ y: 30, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ delay: 0.8, duration: 0.8 }}
className="p-8 md:p-12 bg-amber-50 dark:bg-amber-900/10 border-l-4 border-amber-500"
>
<h3 className="font-display text-2xl mb-4 text-text-main dark:text-white">
Peak Season Notice
</h3>
<p className="font-body font-light text-stone-700 dark:text-stone-300 leading-relaxed">
Peak seasons and holidays may add 12 extra days to processing. We'll notify you of any anticipated delays. By having a clear, upfront shipping policy, we aim to boost your confidence and reduce checkout surprises.
</p>
</motion.div>
{/* CTA Section */}
<motion.div
initial={{ y: 30, opacity: 0 }}
animate={{ y: 0, opacity: 1 }}
transition={{ delay: 1, duration: 0.8 }}
className="mt-24 text-center"
>
<h2 className="font-display text-3xl md:text-4xl mb-6 text-text-main dark:text-white">
Questions about shipping?
</h2>
<p className="font-body font-light text-stone-500 mb-8 max-w-xl mx-auto">
Contact our team for specific shipping inquiries or rush orders.
</p>
<Link
to="/contact"
className="inline-block bg-primary dark:bg-white text-white dark:text-black px-10 py-4 text-xs font-bold uppercase tracking-widest hover:bg-stone-800 dark:hover:bg-stone-200 transition-colors"
>
Get in Touch
</Link>
</motion.div>
</div>
</div>
);
};
export default Shipping;