Files
SkyArtShop/website/public/home.html
Local Server 2a2a3d99e5 webupdate
2026-01-18 02:22:05 -06:00

906 lines
31 KiB
HTML

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta
name="description"
content="Sky Art Shop - Your one-stop shop for scrapbooking, journaling, cardmaking, and collaging stationery."
/>
<title>Sky Art Shop - Creative Stationery & Crafting Supplies</title>
<!-- Fonts -->
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Poppins:wght@600;700;800&display=swap"
rel="stylesheet"
/>
<!-- Icons -->
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css"
/>
<!-- Modern Theme CSS -->
<link
rel="stylesheet"
href="/assets/css/modern-theme.css?v=20260118drawer"
/>
<link
rel="stylesheet"
href="/assets/css/mobile-fixes.css?v=20260119touch"
/>
<style>
/* Blog Grid for Get Inspired Section - Match Blog Page */
#inspirationGrid.blog-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: var(--spacing-lg);
max-width: 1100px;
margin: 0 auto;
}
/* Blog Card Styles for Get Inspired Section */
.blog-card {
position: relative;
border-radius: var(--radius-lg);
overflow: hidden;
background: var(--bg-white);
cursor: pointer;
box-shadow: var(--shadow-md);
transition: var(--transition-smooth);
display: flex;
flex-direction: column;
}
.blog-card:hover {
transform: translateY(-8px);
box-shadow: var(--shadow-lg);
}
.blog-card-image {
position: relative;
width: 100%;
aspect-ratio: 4/3;
overflow: hidden;
}
.blog-card-image img {
width: 100%;
height: 100%;
object-fit: cover;
transition: var(--transition-slow);
}
.blog-card:hover .blog-card-image img {
transform: scale(1.08);
}
.blog-card-overlay {
position: absolute;
inset: 0;
background: rgba(0, 0, 0, 0.4);
display: flex;
align-items: center;
justify-content: center;
opacity: 0;
transition: var(--transition-smooth);
}
.blog-card:hover .blog-card-overlay {
opacity: 1;
}
.blog-card-overlay .read-btn {
display: inline-flex;
align-items: center;
gap: var(--spacing-xs);
background: var(--bg-white);
color: var(--text-primary);
padding: var(--spacing-sm) var(--spacing-lg);
border-radius: var(--radius-full);
font-weight: 600;
font-size: 0.9rem;
transform: translateY(10px);
opacity: 0;
transition: var(--transition-fast);
}
.blog-card:hover .blog-card-overlay .read-btn {
transform: translateY(0);
opacity: 1;
}
.blog-card-info {
padding: var(--spacing-md);
flex: 1;
display: flex;
flex-direction: column;
}
.blog-card-category {
display: inline-block;
background: var(--primary-pink-light);
color: var(--text-primary);
padding: 4px 10px;
border-radius: var(--radius-full);
font-size: 0.65rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.5px;
margin-bottom: var(--spacing-xs);
align-self: flex-start;
}
.blog-card-info h3 {
font-size: 1rem;
color: var(--text-primary);
margin-bottom: 4px;
font-weight: 700;
line-height: 1.3;
}
.blog-card-info .blog-date {
font-size: 0.75rem;
color: var(--text-light);
margin-bottom: var(--spacing-xs);
display: flex;
align-items: center;
gap: var(--spacing-xs);
}
.blog-card-info p {
color: var(--text-secondary);
font-size: 0.8rem;
line-height: 1.5;
flex: 1;
}
@media (max-width: 992px) {
#inspirationGrid.blog-grid {
grid-template-columns: repeat(2, 1fr);
}
}
@media (max-width: 576px) {
#inspirationGrid.blog-grid {
grid-template-columns: 1fr;
}
}
</style>
</head>
<body>
<!-- Navigation -->
<header class="nav-wrapper">
<nav class="navbar">
<a href="/home" class="nav-brand">
<img
src="/uploads/cat-png-1767324141436-368259437.png"
alt="Sky Art Shop Logo"
/>
<span>Sky Art Shop</span>
</a>
<ul class="nav-menu">
<li><a href="/home" class="nav-link active">Home</a></li>
<li><a href="/shop" class="nav-link">Shop</a></li>
<li><a href="/portfolio" class="nav-link">Portfolio</a></li>
<li><a href="/blog" class="nav-link">Blog</a></li>
<li><a href="/about" class="nav-link">About</a></li>
<li><a href="/contact" class="nav-link">Contact</a></li>
</ul>
<div class="nav-actions">
<a href="/signin" class="nav-icon-btn" title="Sign In">
<i class="bi bi-person"></i>
</a>
<button class="nav-icon-btn wishlist-btn-nav" title="Wishlist">
<i class="bi bi-heart"></i>
<span class="badge wishlist-count" style="display: none">0</span>
</button>
<button class="nav-icon-btn cart-btn" title="Cart">
<i class="bi bi-bag"></i>
<span class="badge cart-count" style="display: none">0</span>
</button>
<button class="nav-mobile-toggle" aria-label="Toggle menu">
<span></span>
<span></span>
<span></span>
</button>
</div>
</nav>
</header>
<!-- Page Content -->
<main class="page-content">
<!-- Hero Slider - Dynamic content loaded from backend -->
<section class="hero-slider" id="heroSlider">
<!-- Slides will be loaded dynamically -->
<div class="slide active">
<div class="slide-overlay"></div>
<div class="slide-content">
<div class="loading-spinner"></div>
</div>
</div>
<!-- Slider Navigation - Generated dynamically -->
<div class="slider-nav" id="sliderNav"></div>
<!-- Slider Arrows -->
<div class="slider-arrows">
<button class="slider-arrow prev">
<i class="bi bi-chevron-left"></i>
</button>
<button class="slider-arrow next">
<i class="bi bi-chevron-right"></i>
</button>
</div>
</section>
<!-- Shop Our Collection -->
<section
class="section"
id="featured-products"
style="background: var(--primary-pink-light)"
>
<div class="container">
<div class="section-header">
<h2 class="section-title" id="featuredProductsTitle">
Shop Our Collection
</h2>
<p class="section-subtitle">
Discover our handpicked selection of premium stationery and
crafting supplies
</p>
</div>
<div class="products-grid" id="featuredProductsGrid">
<!-- Products loaded via JavaScript -->
<div
class="loading-spinner"
style="grid-column: 1/-1; margin: 40px auto"
></div>
</div>
<div class="text-center mt-5">
<a href="/shop" class="btn btn-outline">View All Products</a>
</div>
</div>
</section>
<!-- Get Inspired / About Section -->
<section
class="section inspiration-section"
id="get-inspired"
style="background: var(--accent-pink)"
>
<div class="container">
<div class="section-header">
<h2 class="section-title" id="blogSectionTitle">Get Inspired</h2>
<p class="section-subtitle">
Explore creative ideas and projects from our blog
</p>
</div>
<div class="blog-grid" id="inspirationGrid">
<!-- Blog posts loaded via JavaScript with same card style as blog page -->
<div
class="loading-spinner"
style="grid-column: 1/-1; margin: 40px auto"
></div>
</div>
<div class="text-center mt-5">
<a href="/blog" class="btn btn-outline">View All Blog Posts</a>
</div>
</div>
</section>
<!-- About Preview -->
<section
class="section"
id="about-preview"
style="background: var(--primary-pink-dark); padding: 0; margin: 0"
>
<div class="container">
<div class="about-content">
<div class="about-text">
<h2 id="aboutTitle">About Sky Art Shop</h2>
<div id="aboutDescription">
<p>
At Sky Art Shop, we believe in the power of creativity to
transform and inspire. Whether you're an experienced crafter
or just beginning your creative journey, we have everything
you need to bring your ideas to life.
</p>
</div>
<p>
Our carefully curated collection features the best in
stationery, washi tapes, stickers, stamps, and more. Quality
products, fast shipping, and excellent customer service - that's
the Sky Art Shop promise.
</p>
<a href="/about" class="btn btn-secondary">Learn More About Us</a>
</div>
<div
class="about-image"
style="box-shadow: none; border-radius: 0; overflow: visible"
>
<img
id="aboutImage"
src="https://images.unsplash.com/photo-1513519245088-0e12902e35a6?w=800&q=80"
alt="About Sky Art Shop"
style="
max-width: 450px;
width: 100%;
height: auto;
object-fit: cover;
"
/>
</div>
</div>
</div>
</section>
<!-- Newsletter -->
<section
class="section"
style="
background: linear-gradient(
135deg,
var(--primary-pink-light) 0%,
var(--primary-pink) 100%
);
"
>
<div class="container">
<div class="text-center">
<h2 class="section-title">Stay Connected</h2>
<p class="section-subtitle mb-4">
Subscribe to our newsletter for exclusive deals and creative
inspiration
</p>
<form
class="newsletter-form"
style="max-width: 500px; margin: 0 auto; display: flex; gap: 12px"
>
<input
type="email"
placeholder="Enter your email"
style="
flex: 1;
padding: 16px 24px;
border: none;
border-radius: 50px;
font-size: 1rem;
"
/>
<button type="submit" class="btn btn-primary">Subscribe</button>
</form>
</div>
</div>
</section>
</main>
<!-- Footer -->
<footer class="footer">
<div class="container">
<div class="footer-grid">
<div class="footer-about">
<div class="footer-brand">
<img
src="/uploads/cat-png-1767324141436-368259437.png"
alt="Sky Art Shop"
/>
<span>Sky Art Shop</span>
</div>
<p>
Your one-stop shop for scrapbooking, journaling, cardmaking, and
collaging stationery. Quality products for all your creative
needs.
</p>
<div class="footer-social">
<a href="#" class="social-link"><i class="bi bi-facebook"></i></a>
<a href="#" class="social-link"
><i class="bi bi-instagram"></i
></a>
<a href="#" class="social-link"
><i class="bi bi-pinterest"></i
></a>
<a href="#" class="social-link"><i class="bi bi-youtube"></i></a>
</div>
</div>
<div class="footer-column">
<h4>Quick Links</h4>
<ul class="footer-links">
<li><a href="/home">Home</a></li>
<li><a href="/shop">Shop</a></li>
<li><a href="/portfolio">Portfolio</a></li>
<li><a href="/blog">Blog</a></li>
<li><a href="/about">About Us</a></li>
<li><a href="/contact">Contact</a></li>
</ul>
</div>
<div class="footer-column">
<h4>Customer Service</h4>
<ul class="footer-links">
<li><a href="/faq">FAQ</a></li>
<li><a href="/shipping-info">Shipping Info</a></li>
<li><a href="/returns">Returns & Refunds</a></li>
<li><a href="/privacy">Privacy Policy</a></li>
</ul>
</div>
<div class="footer-column">
<h4>Contact Us</h4>
<ul class="footer-links">
<li><i class="bi bi-envelope"></i> hello@skyartshop.com</li>
<li><i class="bi bi-telephone"></i> (555) 123-4567</li>
<li><i class="bi bi-geo-alt"></i> 123 Creative Lane</li>
</ul>
</div>
</div>
<div class="footer-bottom">
<p>&copy; 2026 Sky Art Shop. All rights reserved.</p>
<p>
Made with
<i class="bi bi-heart-fill" style="color: var(--primary-pink)"></i>
for creative souls
</p>
</div>
</div>
</footer>
<!-- Cart Drawer -->
<div class="cart-overlay"></div>
<div class="cart-drawer">
<div class="cart-header">
<h3>Shopping Cart</h3>
<button class="cart-close"><i class="bi bi-x"></i></button>
</div>
<div class="cart-items">
<!-- Cart items rendered via JavaScript -->
</div>
<div class="cart-footer">
<div class="cart-total">
<span>Total:</span>
<span class="cart-total-amount">$0.00</span>
</div>
<a href="/checkout" class="btn btn-primary cart-checkout-btn"
>Checkout</a
>
</div>
</div>
<!-- Wishlist Drawer -->
<div class="wishlist-overlay"></div>
<div class="wishlist-drawer">
<div class="wishlist-header">
<h3><i class="bi bi-heart"></i> My Wishlist</h3>
<button class="wishlist-close"><i class="bi bi-x"></i></button>
</div>
<div class="wishlist-items">
<!-- Wishlist items rendered via JavaScript -->
</div>
<div class="wishlist-footer">
<a href="/shop" class="btn btn-outline">Continue Shopping</a>
</div>
</div>
<!-- Blog Detail View -->
<div class="portfolio-detail" id="blogDetail">
<header class="portfolio-detail-header">
<button class="back-btn" id="backToBlog">
<i class="bi bi-arrow-left"></i>
Back
</button>
<span id="blogDetailCategory" class="portfolio-detail-category"
>Blog</span
>
</header>
<div class="portfolio-detail-content">
<div class="portfolio-detail-image">
<img
src="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs="
alt="Blog post image"
id="blogDetailImage"
/>
</div>
<div class="portfolio-detail-info">
<div
class="blog-detail-date"
id="blogDetailDate"
style="
color: var(--text-light);
font-size: 0.9rem;
margin-bottom: var(--spacing-sm);
display: flex;
align-items: center;
gap: var(--spacing-xs);
"
>
<i class="bi bi-calendar3"></i>
<span></span>
</div>
<h1 class="portfolio-detail-title" id="blogDetailTitle"></h1>
<div class="portfolio-detail-desc" id="blogDetailContent"></div>
<div class="portfolio-detail-cta">
<p>Enjoyed this post? Check out more creative inspiration!</p>
<a href="/blog" class="btn btn-primary">View All Posts</a>
</div>
</div>
</div>
</div>
<!-- Scripts -->
<script src="/assets/js/mobile-touch-fix.js"></script>
<script src="/assets/js/modern-theme.js?v=20260119touch"></script>
<script src="/assets/js/customer-auth.js"></script>
<script>
// Homepage settings cache
let homepageSettings = null;
// Load homepage content from backend
document.addEventListener("DOMContentLoaded", async () => {
// Load homepage settings first
try {
const response = await fetch("/api/homepage/settings");
const data = await response.json();
if (data.success && data.settings) {
homepageSettings = data.settings;
}
} catch (error) {
console.error("Failed to load homepage settings:", error);
}
// Load and render hero slides
await loadHeroSlides();
// Reinitialize slider after dynamic content is loaded
if (window.SkyArtShop && typeof SkyArtShop.initSlider === "function") {
// Reset initialization flag
SkyArtShop.sliderInitialized = false;
const slider = document.querySelector(".hero-slider");
if (slider) slider.dataset.initialized = "false";
SkyArtShop.initSlider();
}
// Load products - only show featured products (max 4)
const featuredProducts = await API.loadFeaturedProducts();
const featuredGrid = document.getElementById("featuredProductsGrid");
// Update section title from settings
if (homepageSettings?.featuredProducts?.title) {
const titleEl = document.getElementById("featuredProductsTitle");
if (titleEl)
titleEl.textContent = homepageSettings.featuredProducts.title;
}
// Store products for detail view - only featured products, max 4
const homepageProducts = featuredProducts.slice(0, 4);
if (featuredGrid) {
if (homepageProducts.length > 0) {
await ProductRenderer.renderProducts(
featuredGrid,
homepageProducts,
);
} else {
featuredGrid.innerHTML =
'<p class="text-center" style="grid-column: 1/-1;">No featured products available.</p>';
}
}
// Update blog section title from settings
if (homepageSettings?.blog?.title) {
const blogTitleEl = document.getElementById("blogSectionTitle");
if (blogTitleEl)
blogTitleEl.textContent = homepageSettings.blog.title;
}
// Check if blog section is enabled
const blogSection = document.getElementById("get-inspired");
if (homepageSettings?.blog?.enabled === false && blogSection) {
blogSection.style.display = "none";
}
const blogCount = homepageSettings?.blog?.count || 3;
// Placeholder images for blog posts
const placeholderImages = [
"https://images.unsplash.com/photo-1544716278-ca5e3f4abd8c?w=600&q=80",
"https://images.unsplash.com/photo-1558618666-fcd25c85cd64?w=600&q=80",
"https://images.unsplash.com/photo-1513519245088-0e12902e35a6?w=600&q=80",
];
// Load blog posts for Get Inspired section
const inspirationGrid = document.getElementById("inspirationGrid");
let blogPostsData = [];
if (inspirationGrid) {
let blogPosts = await API.loadBlogPosts();
// Sample posts if no data
if (blogPosts.length === 0) {
blogPosts = [
{
id: 1,
title: "Getting Started with Bullet Journaling",
excerpt:
"Discover the art of bullet journaling and learn how to create beautiful spreads.",
content:
"Bullet journaling is a customizable organizational system that combines planning, journaling, and tracking. Start with a blank notebook and create your own layouts...",
createdat: new Date().toISOString(),
imageurl: placeholderImages[0],
},
{
id: 2,
title: "Top 10 Washi Tape Ideas",
excerpt:
"Creative ways to use washi tape in your crafting projects.",
content:
"Washi tape is incredibly versatile! Use it to decorate journals, create borders, label items, and add color to any project...",
createdat: new Date().toISOString(),
imageurl: placeholderImages[1],
},
{
id: 3,
title: "Scrapbooking for Beginners",
excerpt:
"Everything you need to know to start your scrapbooking journey.",
content:
"Scrapbooking is a wonderful way to preserve memories. Start with quality paper, photos, and embellishments...",
createdat: new Date().toISOString(),
imageurl: placeholderImages[2],
},
];
}
blogPostsData = blogPosts;
if (blogPosts.length > 0) {
// Show blog posts based on settings count
inspirationGrid.innerHTML = blogPosts
.slice(0, blogCount)
.map((post, index) => {
const date = new Date(post.createdat).toLocaleDateString(
"en-US",
{
year: "numeric",
month: "short",
day: "numeric",
},
);
return `
<article class="blog-card" data-post-index="${index}">
<div class="blog-card-image">
<img src="${
post.imageurl ||
placeholderImages[index % placeholderImages.length]
}" alt="${post.title}" loading="lazy">
<div class="blog-card-overlay">
<span class="read-btn"><i class="bi bi-eye"></i> Read Post</span>
</div>
</div>
<div class="blog-card-info">
<span class="blog-card-category">Blog</span>
<h3>${post.title}</h3>
<div class="blog-date"><i class="bi bi-calendar3"></i> ${date}</div>
<p>${post.excerpt || ""}</p>
</div>
</article>
`;
})
.join("");
}
}
// Setup blog detail view
const blogDetail = document.getElementById("blogDetail");
const blogDetailImage = document.getElementById("blogDetailImage");
const blogDetailTitle = document.getElementById("blogDetailTitle");
const blogDetailContent = document.getElementById("blogDetailContent");
const blogDetailDate = document.getElementById("blogDetailDate");
const backToBlogBtn = document.getElementById("backToBlog");
function openBlogDetail(post) {
const date = new Date(post.createdat).toLocaleDateString("en-US", {
year: "numeric",
month: "long",
day: "numeric",
});
const imageUrl = post.imageurl || placeholderImages[0];
blogDetailImage.src = imageUrl.replace("w=600", "w=1200");
blogDetailImage.alt = post.title;
blogDetailTitle.textContent = post.title;
blogDetailContent.innerHTML =
post.content || post.excerpt || "No content available.";
blogDetailDate.querySelector("span").textContent = date;
blogDetail.classList.add("open");
document.body.style.overflow = "hidden";
blogDetail.scrollTop = 0;
}
function closeBlogDetail() {
blogDetail.classList.remove("open");
document.body.style.overflow = "";
}
// Click handlers
document.addEventListener("click", (e) => {
// Product card click - navigate to product detail page
const productCard = e.target.closest(".product-card");
if (
productCard &&
!e.target.closest(".add-to-cart-btn") &&
!e.target.closest(".wishlist-btn") &&
!e.target.closest(".quick-view-btn")
) {
e.preventDefault();
// Use slug from data attribute, fallback to product lookup
const slug = productCard.dataset.productSlug;
if (slug) {
window.location.href = `/product/${slug}`;
return;
} else {
const productId = productCard.dataset.productId;
const product = [...allProducts, ...featuredProducts].find(
(p) => p.id === productId || p.id === parseInt(productId),
);
if (product) {
window.location.href = `/product/${product.slug || product.id}`;
return;
}
}
}
// Blog card click (Get Inspired section) - Navigate to blog page
const blogCard = e.target.closest(".blog-card");
if (blogCard && blogCard.dataset.postIndex !== undefined) {
window.location.href = "/blog";
}
});
if (backToBlogBtn) {
backToBlogBtn.addEventListener("click", closeBlogDetail);
}
document.addEventListener("keydown", (e) => {
if (e.key === "Escape") {
closeBlogDetail();
}
});
// Load about section from settings
if (homepageSettings?.about) {
const aboutSection = document.getElementById("about-preview");
if (aboutSection && homepageSettings.about.enabled === false) {
aboutSection.style.display = "none";
} else {
if (homepageSettings.about.title) {
const titleEl = document.getElementById("aboutTitle");
if (titleEl) titleEl.textContent = homepageSettings.about.title;
}
if (homepageSettings.about.description) {
const descEl = document.getElementById("aboutDescription");
if (descEl) descEl.innerHTML = homepageSettings.about.description;
}
if (homepageSettings.about.imageUrl) {
const imgEl = document.getElementById("aboutImage");
if (imgEl) imgEl.src = homepageSettings.about.imageUrl;
}
}
}
});
// Function to load hero slides from backend settings
async function loadHeroSlides() {
const heroSlider = document.getElementById("heroSlider");
const sliderNav = document.getElementById("sliderNav");
if (!heroSlider) return;
// Get slides from settings or use defaults
let slides = homepageSettings?.heroSlides || [];
// Default slides if none configured
if (slides.length === 0) {
slides = [
{
title: "Welcome to Sky Art Shop",
description:
"Discover our beautiful collection of stationery, washi tapes, stickers, and crafting supplies. Perfect for bullet journaling, scrapbooking, and all your creative projects.",
buttonText: "Shop Now",
buttonLink: "/shop",
imageUrl:
"https://images.unsplash.com/photo-1513519245088-0e12902e35a6?w=1920&q=80",
},
{
title: "Express Your Creativity",
description:
"From vibrant markers to elegant journals, find everything you need to bring your artistic vision to life. Quality supplies for every crafter.",
buttonText: "Explore Collection",
buttonLink: "/shop",
imageUrl:
"https://images.unsplash.com/photo-1456735190827-d1262f71b8a3?w=1920&q=80",
},
{
title: "New Arrivals Every Week",
description:
"Stay inspired with our constantly updated selection of unique and trendy stationery. Be the first to discover our latest additions.",
buttonText: "See What's New",
buttonLink: "/shop",
imageUrl:
"https://images.unsplash.com/photo-1452860606245-08befc0ff44b?w=1920&q=80",
},
];
}
// Render slides
const slidesHtml = slides
.map((slide, index) => {
const hasImage = slide.imageUrl && slide.imageUrl.trim() !== "";
return `
<div class="slide ${index === 0 ? "active" : ""} ${
hasImage ? "has-image" : ""
}">
${
hasImage
? `<img
src="${slide.imageUrl}"
alt="${slide.title}"
class="slide-bg"
/>`
: ""
}
<div class="slide-overlay"></div>
<div class="slide-content">
<h1>${slide.title}</h1>
<p>${slide.description}</p>
${
slide.buttonText
? `<a href="${
slide.buttonLink || "/shop"
}" class="btn btn-primary btn-lg">${slide.buttonText}</a>`
: ""
}
</div>
</div>
`;
})
.join("");
// Render navigation dots
const dotsHtml = slides
.map(
(_, index) => `
<button class="slider-dot ${
index === 0 ? "active" : ""
}" data-slide="${index}"></button>
`,
)
.join("");
// Keep the arrows
const arrowsHtml = `
<div class="slider-arrows">
<button class="slider-arrow prev">
<i class="bi bi-chevron-left"></i>
</button>
<button class="slider-arrow next">
<i class="bi bi-chevron-right"></i>
</button>
</div>
`;
// Update the slider
heroSlider.innerHTML =
slidesHtml + `<div class="slider-nav">${dotsHtml}</div>` + arrowsHtml;
}
</script>
<script src="/assets/js/accessibility.js"></script>
</body>
</html>