diff --git a/.gitignore b/.gitignore index 05c42ec..1bdf880 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ package-lock.json .astro/ *.local *.backup +*.draft.* \ No newline at end of file diff --git a/src/components/blocks.content.astro b/src/components/blocks.content.astro new file mode 100644 index 0000000..632a034 --- /dev/null +++ b/src/components/blocks.content.astro @@ -0,0 +1,353 @@ +--- +import { type ContentBlock } from "../types.d"; + +export interface Props { + content?: ContentBlock[]; + className?: string; +} + +const { content, className = "" } = Astro.props; +--- + +{ + content && content.length > 0 && ( +
+ {content.map((block) => ( + <> + {/* Paragraph blocks */} + {block.type === "paragraph" && ( +

+ {block.children.map((child) => ( + + {child.code && ( + + {child.text} + + )} + {child.type === "link" && !child.code && ( + + {child.children?.[0]?.text || child.text} + + )} + {!child.code && + child.type !== "link" && + (child.bold ? ( + {child.text} + ) : ( + {child.text} + ))} + + ))} +

+ )} + + {/* Heading blocks */} + {block.type === "heading" && block.level === 1 && ( +

+ {block.children.map((child) => ( + + {child.code ? ( + + {child.text} + + ) : child.type === "link" ? ( + + {child.children?.[0]?.text || child.text} + + ) : ( + {child.text} + )} + + ))} +

+ )} + + {block.type === "heading" && block.level === 2 && ( +

+ {block.children.map((child) => ( + + {child.code ? ( + + {child.text} + + ) : child.type === "link" ? ( + + {child.children?.[0]?.text || child.text} + + ) : ( + {child.text} + )} + + ))} +

+ )} + + {block.type === "heading" && block.level === 3 && ( +

+ {block.children.map((child) => ( + + {child.code ? ( + + {child.text} + + ) : child.type === "link" ? ( + + {child.children?.[0]?.text || child.text} + + ) : ( + {child.text} + )} + + ))} +

+ )} + + {block.type === "heading" && (block.level === 4 || !block.level) && ( +

+ {block.children.map((child) => ( + + {child.code ? ( + + {child.text} + + ) : child.type === "link" ? ( + + {child.children?.[0]?.text || child.text} + + ) : ( + {child.text} + )} + + ))} +

+ )} + + {block.type === "heading" && block.level === 5 && ( +
+ {block.children.map((child) => ( + + {child.code ? ( + + {child.text} + + ) : child.type === "link" ? ( + + {child.children?.[0]?.text || child.text} + + ) : ( + {child.text} + )} + + ))} +
+ )} + + {block.type === "heading" && block.level === 6 && ( +
+ {block.children.map((child) => ( + + {child.code ? ( + + {child.text} + + ) : child.type === "link" ? ( + + {child.children?.[0]?.text || child.text} + + ) : ( + {child.text} + )} + + ))} +
+ )} + + {/* Code blocks */} + {block.type === "code" && ( +
+
+                
+                  {block.children
+                    .map((child) => (child.code ? child.text : ""))
+                    .filter(Boolean)
+                    .join("\n")}
+                
+              
+
+ )} + + {/* List blocks */} + {block.type === "list" && ( + + )} + + {/* Quote blocks */} + {block.type === "quote" && ( +
+
+ {block.children.map((child) => ( + + {child.code ? ( + + {child.text} + + ) : child.type === "link" ? ( + + {child.children?.[0]?.text || child.text} + + ) : ( + {child.text} + )} + + ))} +
+
+ )} + + {/* Image blocks */} + {block.type === "image" && block.image?.url && ( +
+
+ { +
+ {((block.image as any).caption || + (block.image as any).alternativeText || + (block.image as any).name) && ( +
+ {(block.image as any).caption || + (block.image as any).alternativeText || + (block.image as any).name} +
+ )} +
+ )} + + ))} +
+ ) +} + + diff --git a/src/components/markket/pages.cards.astro b/src/components/markket/pages.cards.astro new file mode 100644 index 0000000..398d994 --- /dev/null +++ b/src/components/markket/pages.cards.astro @@ -0,0 +1,91 @@ +--- +/** + * pages: Array of either collection entries or raw page data objects + * Each item may be: { id, data } or the direct data object. + */ +const { pages = [], className = "" } = Astro.props; + +const href = (slug: string) => { + const map: Record = { + home: "/", + blog: "/blog", + newsletter: "/newsletter", + contact: "/contacto", + about: "/about", + products: "/servicios", + }; + + return map[slug] || `/about/${slug}`; +}; +--- + +
+ { + pages.map((entry: any) => { + const p = entry?.data ? entry.data : entry; + const title = p?.Title || p?.title || "Untitled"; + const slug = p?.slug || p?.Slug || p?.id || ""; + const img = p?.Cover?.url || p?.SEO?.socialImage?.url || ""; + const desc = + p?.SEO?.metaDescription || + (p?.Content && p.Content[0]?.children?.[0]?.text) || + ""; + + return ( + + ); + }) + } +
+ + diff --git a/src/components/navbar.tsx b/src/components/navbar.tsx index ae41e93..cbf1650 100644 --- a/src/components/navbar.tsx +++ b/src/components/navbar.tsx @@ -23,7 +23,7 @@ const Navbar = () => { diff --git a/src/components/products/cardProduct.tsx b/src/components/products/cardProduct.tsx deleted file mode 100644 index fee291d..0000000 --- a/src/components/products/cardProduct.tsx +++ /dev/null @@ -1,66 +0,0 @@ -import ProductBadge from './productBadge'; - -interface Props { - thumb_src: string; - thumb_alt: string; - title: string; - description: string; - price: number; - color: string; - colors: string[]; - position: string; -} - -export default function CardProduct({ - thumb_src, - thumb_alt, - title, - description, - price, - color, - colors, - position -}: Props) { - - const classList = "card-body " + "text-" + position; - - return ( - <> -
- -
- {thumb_alt} -
-
- {(color) && -
{color}
- } - {(title) && -

- {title} -

- } - - {(description) && -

{description}

- } - - {(colors) && - - } - - {(price) && -

- ${price.toLocaleString()} -

- } - - {!(description || colors || color) && -
Shop Now - } -
- -
- - ); -}; diff --git a/src/components/products/categoryFilters.tsx b/src/components/products/categoryFilters.tsx index 95cbd35..4a83b81 100644 --- a/src/components/products/categoryFilters.tsx +++ b/src/components/products/categoryFilters.tsx @@ -1,5 +1,5 @@ import data from '../../../public/data.json'; -import CardProduct from '../products/cardProduct'; +import CardProduct from './product.cards'; interface Props { title: string; @@ -13,7 +13,7 @@ export default function ProductOverview({ <>
- {(title.length != 0) && + {(title.length != 0) &&

{title}

}
@@ -157,9 +157,9 @@ export default function ProductOverview({
- {data.products.slice(0, 3).map(product => + {data.products.slice(0, 3).map(product =>
-
- )} + )}
diff --git a/src/components/products/product.cards.tsx b/src/components/products/product.cards.tsx new file mode 100644 index 0000000..839a9f7 --- /dev/null +++ b/src/components/products/product.cards.tsx @@ -0,0 +1,20 @@ +export default function CardProduct({ product, position }: { product: any, position: 'center' }) { + + const classList = 'card-body text-' + position; + + const href = `/servicios/${product.slug || product.id || ''}`; + + return ( + + ); +} diff --git a/src/components/simpleFooter.tsx b/src/components/simpleFooter.tsx new file mode 100644 index 0000000..9692fcf --- /dev/null +++ b/src/components/simpleFooter.tsx @@ -0,0 +1,106 @@ +import React from 'react'; + +interface SimpleFooterProps { + store?: any; +} + +const SimpleFooter: React.FC = ({ store = {} }) => { + const currentYear = new Date().getFullYear(); + + // Extract store information with fallbacks + const storeName = store?.title || "Markkët Express"; + const storeDescription = store?.Description || "Tu tienda online de confianza"; + const storeSettings = store?.settings || {}; + const storeMeta = storeSettings?.meta || {}; + const storeContact = { email: store?.settings?.support_email }; + const storeSocial = storeMeta?.social || {}; + + return ( +
+
+
+ {/* Store Info */} +
+
{storeName}
+

{storeDescription}

+
+ {/* {storeSocial?.facebook && ( + + + + )} + {storeSocial?.instagram && ( + + + + )} + {storeSocial?.twitter && ( + + + + )} */} + {/* Fallback social links if no store social data */} +
+
+ + {/* Quick Links */} +
+
Enlaces
+ +
+ + {/* Support */} +
+
Soporte
+ +
+ + {/* Contact Info */} +
+
Contacto
+
+
+ + {storeContact?.email || "info@markketexpress.com"} +
+
+ + {storeContact?.phone || "+1 (555) 123-4567"} +
+
+ + {storeContact?.address || "Ciudad, País"} +
+
+
+
+ +
+ + {/* Copyright */} +
+
+

+ © {currentYear} {storeName}. Todos los derechos reservados. + + Desarrollado con usando Astro + +

+
+
+
+
+ ); +}; + +export default SimpleFooter; \ No newline at end of file diff --git a/src/components/simpleNavbar.tsx b/src/components/simpleNavbar.tsx new file mode 100644 index 0000000..24f2f3b --- /dev/null +++ b/src/components/simpleNavbar.tsx @@ -0,0 +1,79 @@ +import React from 'react'; + +interface SimpleNavbarProps { + storeName?: string; + storeLogo?: string; +} + +const SimpleNavbar: React.FC = ({ storeName = "Markkët Express", storeLogo }) => { + return ( + + ); +}; + +export default SimpleNavbar; \ No newline at end of file diff --git a/src/content/config.ts b/src/content/config.ts index 45e6753..c4ee78f 100644 --- a/src/content/config.ts +++ b/src/content/config.ts @@ -53,13 +53,19 @@ const pages = defineCollection({ }) as Loader, }); - const store = defineCollection({ - loader: strapiLoader({ - contentType: "store", - filter: `filters[slug][$eq]=${config.store_slug}`, - populate: 'SEO.socialImage,Logo,URLS,Favicon,Cover' - }) as Loader, + loader: { + name: `strapi-store-info`, + schema: async () => await fetchStrapiSchema('store', config.api_url), + load: async ({ store, logger, meta }) => { + logger.info('fetch:store:info'); + const data = await fetch(new URL(`/api/stores/${config.store_slug}/info`, config.api_url)); + const posts = await data?.json(); + store.clear(); + posts?.data.forEach((item: any) => store.set({ id: item.id, data: item })); + meta.set("lastSynced", String(Date.now()));; + } + } as Loader, }); const stores = defineCollection({ diff --git a/src/layouts/BasicLayout.astro b/src/layouts/BasicLayout.astro new file mode 100644 index 0000000..a9595f0 --- /dev/null +++ b/src/layouts/BasicLayout.astro @@ -0,0 +1,47 @@ +--- +import Layout from "./Layout.astro"; +import SimpleNavbar from "../components/simpleNavbar"; +import SimpleFooter from "../components/simpleFooter"; +import { getCollection } from "astro:content"; + +const storeData = await getCollection("store"); +const store = storeData[0]?.data || {}; +const storeName = store.title || "Markkët Express"; +const storeDescription = + store.Description || + "Plantilla y tienda compatible con Markkët para prestar servicios y vender productos. Ejemplos, tutoriales y documentación en español."; +const storeLogo = store.Logo?.url || ""; +const storeSEO = store.SEO || {}; + +export interface Props { + title: string; + canonical?: string; + description?: string; + keywords?: string; + author?: string; + ogImage?: string; + favicon?: string; +} + +const { title, canonical, description, keywords, author, ogImage, favicon } = + Astro.props; +--- + + + + + +
+ +
+ + +
diff --git a/src/layouts/Layout.astro b/src/layouts/Layout.astro index 6f86c73..3431af6 100644 --- a/src/layouts/Layout.astro +++ b/src/layouts/Layout.astro @@ -9,12 +9,17 @@ export interface Props { favicon?: string; } +import { getCollection } from "astro:content"; + +const storeData = await getCollection("store"); +const store = storeData[0]?.data || {}; + const { title, canonical, description, keywords, author, ogImage, favicon } = Astro.props; --- - + @@ -49,10 +54,12 @@ const { title, canonical, description, keywords, author, ogImage, favicon } = href={favicon || `${import.meta.env.BASE_URL}favicon.svg`} /> - + @@ -60,33 +67,29 @@ const { title, canonical, description, keywords, author, ogImage, favicon } = rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css" /> + + + { + store?.settings?.meta?.head_scripts?.map( + (script: { url: string; defer: boolean }) => ( + - - + + + - diff --git a/src/pages/about/[slug].astro b/src/pages/about/[slug].astro new file mode 100644 index 0000000..6bb991d --- /dev/null +++ b/src/pages/about/[slug].astro @@ -0,0 +1,99 @@ +--- +import Layout from "../../layouts/BasicLayout.astro"; +import BlocksContent from "../../components/blocks.content.astro"; +import PageCards from "../../components/markket/pages.cards.astro"; +import { getCollection } from "astro:content"; + +export async function getStaticPaths() { + const pages = await getCollection("pages"); + + // Filter pages that should appear under /about + const aboutPages = pages.filter((p) => { + const slug = p.data?.slug || p.id; + if (!slug) return false; + // skip the index/about home or obvious root pages + if (slug === "about" || slug === "home") return false; + const pd = p.data as any; + // skip pages that point to external URLs + if (pd?.ExternalUrl) return false; + // allow an explicit opt-out via ShowInAbout = false + if (pd?.ShowInAbout === false) return false; + // if a Section field exists, only include pages explicitly in the 'about' section + if (pd?.Section && String(pd?.Section).toLowerCase() !== "about") + return false; + return true; + }); + + return aboutPages.map((p) => ({ params: { slug: p.data?.slug || p.id } })); +} + +const pages = await getCollection("pages"); + +const { slug } = Astro.params; +const current = pages.find((p) => p.data?.slug === slug || p.id === slug); +if (!current) throw new Error(`Page not found: ${slug}`); + +const relatedPages = pages.filter( + (p) => ![slug, "home", "about"].includes(p.data?.slug) +); + +const page = current.data; + +const storeData = await getCollection("store"); +const store = storeData[0]?.data || {}; +--- + + +
+ +
+
+
+
+

{page?.Title || "Acerca de"}

+ { + page?.SEO?.metaDescription ? ( +

{page.SEO.metaDescription}

+ ) : ( +

+ Conoce más sobre nosotros y lo que hacemos. +

+ ) + } +
+
+
+
+ + +
+
+
+
+ +
+
+
+
+ +
+
+
+

Paginas relacionadas

+
+
+
+ +
+
+
+
diff --git a/src/pages/about/index.astro b/src/pages/about/index.astro new file mode 100644 index 0000000..bcbc588 --- /dev/null +++ b/src/pages/about/index.astro @@ -0,0 +1,119 @@ +--- +import Layout from "../../layouts/BasicLayout.astro"; +import BlocksContent from "../../components/blocks.content.astro"; +import { getCollection } from "astro:content"; +import PageCards from "../../components/markket/pages.cards.astro"; + +const pages = await getCollection("pages"); +const pageEntry = pages.find((p) => p.data.slug === "about"); +const page = pageEntry?.data || null; +const storeData = await getCollection("store"); +const store = storeData[0]?.data || {}; +const relatedPages = pages.filter( + (p) => !["home", "about"].includes(p.data?.slug) +); +--- + + +
+
+
+
+
+

{page?.Title || "Acerca de"}

+ { + page?.SEO?.metaDescription && ( +

{page.SEO.metaDescription}

+ ) + } +
+
+
+
+ +
+ { + page?.Content ? ( + + ) : ( +
+
+

+ No hay contenido disponible para esta página. +

+
+
+ ) + } +
+
+
+

Nuestros Valores

+

Principios que nos guian

+
+
+
+
+ +

Pasión

+

+ Nos apasiona lo que hacemos y se refleja en cada producto y + servicio que ofrecemos. +

+
+
+
+
+ +

Integridad

+

+ Actuamos con honestidad y transparencia en todas nuestras + relaciones comerciales. +

+
+
+
+
+ +

Innovación

+

+ Buscamos constantemente nuevas formas de mejorar y evolucionar + nuestros servicios. +

+
+
+
+
+
+
+

¿Quieres saber más?

+

+ Estamos aquí para responder cualquier pregunta que puedas tener sobre { + store?.title + }, nuestros productos y servicios. +

+ + + Contáctanos + +
+
+ +
+
+
+

Paginas relacionadas

+
+
+
+ +
+
+
+
diff --git a/src/pages/astro-ecommerce.astro b/src/pages/astro-ecommerce.astro deleted file mode 100644 index 1b6ce03..0000000 --- a/src/pages/astro-ecommerce.astro +++ /dev/null @@ -1,386 +0,0 @@ ---- -import Layout from '../layouts/Layout.astro'; -import data from '../../public/data.json'; -import '../../assets/scss/astro-ecommerce.scss'; -import Navbar from '../components/navbar'; -import ComplexNavbar from '../components/complexNavbar'; -import ComplexNavbarDark from '../components/complexNavbarDark'; -import Footer from '../components/footer'; -import ComplexFooter from '../components/complexFooter'; -import CardProduct from '../components/products/cardProduct'; -import CardCategory from '../components/products/cardCategory'; -import ProductOverviewGrid from '../components/products/productOverviewGrid'; -import ProductOverviewGallery from '../components/products/productOverviewGallery'; -import ShoppingCart from '../components/cart/shoppingCart'; -import ShoppingCart2 from '../components/cart/shoppingCart2'; -import ProductQuickview from '../components/products/productQuickview'; -import ProductQuickview2 from '../components/products/productQuickview2'; -import ProductFeature from '../components/products/productFeature'; -import ProductFeature2 from '../components/products/productFeature2'; -import CategoryFilters from '../components/products/categoryFilters'; -import TestimonialsFade from '../components/promo/testimonialsFade'; -import PromoSectionLarge from '../components/promo/promoSectionLarge'; -import CheckoutOrderSummary from '../components/checkout/checkoutOrderSummary'; -import CheckoutMultiStep from '../components/checkout/checkoutMultiStep'; -import ReviewSimple from '../components/reviews/reviewSimple'; -import ReviewSummaryChart from '../components/reviews/reviewSummaryChart'; -import OrderSummaries from '../components/order/orderSummaries'; -import OrderHistory from '../components/order/orderHistory'; -import IncentiveLarge from '../components/incentives/incentiveLarge'; -import IncentiveCols from '../components/incentives/incentiveCols'; - -let cartItems = []; -data.shoppingCart.map(id => - data.products.filter(x => x.id == id).map(x => cartItems.push(x)) -) -let cartItems2 = []; -data.shoppingCart2.map(id => - data.products.filter(x => x.id == id).map(x => cartItems2.push(x)) -) - -// filter reviews with ID 01 -let productReviews = data.reviews.filter(x => x.productID == "01"); - -let orderProducts = []; - -data.orders[0].products.forEach(productDetails => { - data.products.forEach(product => { - if (product.id == productDetails.id) { - orderProducts.push(product); - } - }); -}) - -let orderHistoryProducts = new Set(); - -data.orders.forEach((order) => { - order.products.forEach(productDetails => { - data.products.forEach(product => { - if (product.id == productDetails.id) { - orderHistoryProducts.add(product); - } - }); - }) -}) - ---- - - - - -
- -
-

Product Lists

-

Components and blocks for Product Lists

-
- {data.products.map(product => -
- -
- )} -
- -

Product Lists

-

Cards with full details

-
- {data.products.map(product => -
- -
- )} -
- -
-
-

Shop by category

- Browse all categories > -
- {data.categories.slice(0, 4).map(category => -
- -
- )} -
- -
-
-

Shop by category

- Browse all categories > -
-
- -
-
-
- -
-
- -
-
-
- - -
-

Product Overview

-

With image grid

- - -
- -
-

Product Overview

-

Product Overviews with image gallery and expandable details

- - -
- - -
- -
- -
- -
- -
-

Category filters

-

With inline actions and expandable sidebar filters

- -
- -
-

Product Quickviewers

-

With color selector, size selector, and details link

- - - -

Product Quickviewers

-

With large size selector

- -
- -
- -
- -
- -
- -
-

Complex Navbar White

- Browse all categories > -

- -
- {data.products.map(product => -
- -
- )} -
- -

Complex Navbar Dark

- Browse all categories > -

- -
- {data.products.map(product => -
- -
- )} -
-
- -
-

Simple Footer

-
- -

Complex Footer

- -
- -
-

Promo Sections

-

Full-width with background image and large content

- -
- -
-

Promo Sections

-

With fading background image and testimonials

- -
- -
-

Checkout Forms

-

Split with order summary

- -
- -
-

Checkout Forms

-

SWith order summary sidebar

- -
- -
-

Product reviews

-

Simple with avatars

- -
- -
-

Product reviews

-

With summary chart

- -
- -
-

Order Summaries

-

With order summary sidebar

- -
- -
- -
- -
- -
- -
-

Features

-

3-column with illustrations and header

- -
- -
-
-
-
diff --git a/src/pages/blog/[slug].astro b/src/pages/blog/[slug].astro new file mode 100644 index 0000000..2595fee --- /dev/null +++ b/src/pages/blog/[slug].astro @@ -0,0 +1,100 @@ +--- +import Layout from "../../layouts/BasicLayout.astro"; +import BlocksContent from "../../components/blocks.content.astro"; +import { getCollection } from "astro:content"; + +export async function getStaticPaths() { + const posts = await getCollection("posts"); + + return posts.map((p) => ({ params: { slug: p.data?.slug || p.id } })); +} + +const pages = await getCollection("pages"); + +const { slug } = Astro.params; +const posts = await getCollection("posts"); +const current = posts.find((p) => p.data?.slug === slug || p.id === slug)?.data; +if (!current) throw new Error(`Page not found: ${slug}`); + +const relatedPosts = pages.filter( + (p) => ![slug,].includes(p.data?.slug) +).splice(0,3) +--- + + +
+
+
+
+
+

{current?.Title }

+

{current.SEO.metaDescription}

+
+
+
+
+ +
+
+
+
+ +
+
+
+
+ +
+
+
+

Articulos relacionados

+
+
+
+
+ { + relatedPosts.slice(1).map((post) => ( +
+
+ {post?.data?.Title} +
+
+ {'x'} +
+
{post.data.Title}
+

+ {post.data.SEO?.metaDescription} +

+
+ + {'x'} + + {'x'} +
+ + Leer Más + +
+
+
+ )) + } +
+
+
+
+
diff --git a/src/pages/blog/index.astro b/src/pages/blog/index.astro new file mode 100644 index 0000000..6cce8f2 --- /dev/null +++ b/src/pages/blog/index.astro @@ -0,0 +1,182 @@ +--- +import Layout from "../../layouts/BasicLayout.astro"; + +import { getCollection } from "astro:content"; + +const storeData = await getCollection("store"); +const store = storeData[0]?.data || {}; +const storeName = store.title || "Markkët Express"; +const storeSEO = store.SEO || {}; + +const articles = (await getCollection("posts")) || []; +const page = ((await getCollection("pages")) || [])?.find( + (p) => p?.data?.slug == "blog" +)?.data; +--- + + +
+
+
+
+
+

{page?.Title || "Blog"}

+

+ {page?.SEO?.metaDescription} +

+
+
+
+
+ +
+
+
+
+ {articles?.[0]?.data?.Title} +
+
+

{articles?.[0]?.data.Title}

+

+ {articles?.[0]?.data.SEO?.metaDescription} +

+
+ + {articles?.[0]?.data?.SEO?.metaAuthor} + + {articles?.[0]?.data?.SEO?.createdAt} + +
+ + Leer Artículo + + +
+
+
+
+
+
+

Últimos Artículos

+
+ +
+ +
+ { + articles.slice(1).map((post) => ( +
+
+ {post?.data?.Title} +
+
+ {"x"} +
+
{post.data.Title}
+

+ {post.data.SEO?.metaDescription} +

+
+ + {"x"} + + {"x"} +
+ + Leer Más + +
+
+
+ )) + } +
+
+ + +
+
+

¿No te quieres perder nada?

+

+ Suscríbete a nuestro boletín y recibe los últimos artículos + directamente en tu inbox +

+
+
+
+ + +
+
+
+
+
+ + +
+
+

Explora por Categorías

+
+
+
+
+ +
Guías
+

Consejos prácticos

+
+
+
+
+ +
Tips
+

Simples trucos

+
+
+
+
+ +
Noticias
+

Últimas novedades

+
+
+
+
+
+
+
diff --git a/src/pages/contacto.astro b/src/pages/contacto.astro new file mode 100644 index 0000000..0158045 --- /dev/null +++ b/src/pages/contacto.astro @@ -0,0 +1,258 @@ +--- +import Layout from "../layouts/Layout.astro"; +import SimpleNavbar from "../components/simpleNavbar"; +import SimpleFooter from "../components/simpleFooter"; + +import { getCollection } from "astro:content"; + +const storeData = await getCollection("store"); +const store = storeData[0]?.data || {}; +const storeName = store.title || "Markkët Express"; +const storeDescription = + store.Description || + "Plantilla y tienda compatible con Markkët para prestar servicios y vender productos."; +const storeLogo = store.Logo?.url || ""; +const storeSEO = store.SEO || {}; +--- + + + + + +
+ +
+
+
+
+

Contáctanos

+

+ Estamos aquí para ayudarte. No dudes en ponerte en contacto con nosotros +

+
+
+
+
+ +
+
+ +
+
+

Envíanos un mensaje

+
+
+
+ + +
+
+ + +
+
+
+
+ + +
+
+ + +
+
+
+ + +
+
+ + +
+
+ + +
+ +
+
+
+ + +
+
+ +
+

Información de Contacto

+ +
+
+ + Dirección +
+

+ 123 Calle Principal
+ Ciudad, País 12345 +

+
+ +
+
+ + Teléfono +
+

+1 (555) 123-4567

+
+ +
+
+ + Email +
+

{store?.settings?.support_email}

+
+ +
+
+ + Horario +
+

+ Lun - Vie: 9:00 AM - 6:00 PM
+ Sáb: 10:00 AM - 4:00 PM
+ Dom: Cerrado +

+
+
+ + +
+
Síguenos
+ +
+
+
+
+ + +
+
+

Preguntas Frecuentes

+

Quizás encuentres la respuesta a tu pregunta aquí

+
+
+
+
+
+

+ +

+
+
+ Aceptamos tarjetas de crédito y débito (Visa, MasterCard, American Express), PayPal, + transferencias bancarias y pagos en efectivo para entregas locales. +
+
+
+
+

+ +

+
+
+ Los envíos locales tardan de 1-3 días laborables, envíos nacionales de 3-7 días laborables, + y envíos internacionales de 7-15 días laborables dependiendo del destino. +
+
+
+
+

+ +

+
+
+ Sí, aceptamos devoluciones dentro de los 30 días posteriores a la compra. + El producto debe estar en condiciones originales y con el empaque original. +
+
+
+
+
+
+
+
+
+ + + +
+ + \ No newline at end of file diff --git a/src/pages/index.astro b/src/pages/index.astro index 00d1dac..31dc11e 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -1,13 +1,9 @@ --- import Layout from "../layouts/Layout.astro"; -import data from "../../public/data.json"; -import "../../assets/scss/astro-ecommerce.scss"; -import ComplexNavbar from "../components/complexNavbar"; -import ComplexFooter from "../components/complexFooter"; -import CardProduct from "../components/products/cardProduct"; -import CardCategory from "../components/products/cardCategory"; -import TestimonialsFade from "../components/promo/testimonialsFade"; -import IncentiveCols from "../components/incentives/incentiveCols"; +import SimpleNavbar from "../components/simpleNavbar"; +import SimpleFooter from "../components/simpleFooter"; +import CardProduct from "../components/products/product.cards"; +import PageCards from "../components/markket/pages.cards.astro"; import { getCollection } from "astro:content"; @@ -18,20 +14,11 @@ const storeDescription = store.Description || "Plantilla y tienda compatible con Markkët para prestar servicios y vender productos. Ejemplos, tutoriales y documentación en español."; const storeLogo = store.Logo?.url || ""; -const storeCover = store.Cover?.url || ""; const storeSEO = store.SEO || {}; +const pages = (await getCollection("pages"))?.splice(0, 3); +const products = (await getCollection("products"))?.splice(0, 2); --- - - -
- - + + - +
+
-
+
{ storeLogo && ( {`${storeName} ) } -

{storeName}

-

{storeDescription}

-
- - +
@@ -85,128 +70,72 @@ const storeSEO = store.SEO || {};
-
+
-

Productos Destacados

-

- Descubre nuestros artículos más populares -

+

Servicios Destacados

{ - data.products.slice(0, 4).map((product) => ( -
- -
- )) - } -
-
- - -
-
-
-

Comprar por Categoría

-

Encuentra exactamente lo que buscas

-
-
-
- { - data.categories.slice(0, 4).map((category) => ( -
- + products.map((product) => ( +
+
)) }
- -
- -
- -
-
-
-

¿Por qué elegir {storeName}?

-

- Estamos comprometidos a brindar la mejor experiencia de compra -

+
+
+
+

Conoce a {storeName}

+

{storeDescription}

+
+
+ +
Confiable
+ Seguro y confiable +
+
+ +
Envío Rápido
+ Entrega rápida +
+
+ +
Calidad
+ Productos premium +
+
+
-
-
-
-
-
-
-

Acerca de {storeName}

-

{storeDescription}

-
-
-
- -
Confiable
- Seguro y confiable -
-
-
-
- -
Envío Rápido
- Entrega rápida -
-
-
-
- -
Calidad
- Productos premium -
-
-
-
-
+
+
+

Acerca de Nosostros

+
+ +
- - -
+ + + diff --git a/src/pages/product.astro b/src/pages/product.astro deleted file mode 100644 index ca5bedc..0000000 --- a/src/pages/product.astro +++ /dev/null @@ -1,56 +0,0 @@ ---- -import Layout from '../layouts/Layout.astro'; -import data from '../../public/data.json'; -import '../../assets/scss/astro-ecommerce.scss'; -import Navbar from '../components/navbar'; -import CardProduct from '../components/products/cardProduct'; -import ProductOverviewGrid from '../components/products/productOverviewGrid'; -import StoreDoubleColumn from '../components/store/storeDoubleColumn'; -import ReviewSummaryChart from '../components/reviews/reviewSummaryChart'; - -// filter reviews with ID 01 -let productReviews = data.reviews.filter(x => x.productID == "01"); ---- - - -
- -
- - -
- -
- -
-
Customers also purchased
- {data.products.map(product => -
- -
- )} -
-
- -
-
- -
\ No newline at end of file diff --git a/src/pages/receipt.astro b/src/pages/receipt.astro new file mode 100644 index 0000000..30cc84d --- /dev/null +++ b/src/pages/receipt.astro @@ -0,0 +1,4 @@ +--- +--- + +
Transacción
diff --git a/src/pages/servicios/[slug].astro b/src/pages/servicios/[slug].astro new file mode 100644 index 0000000..bf0d0ab --- /dev/null +++ b/src/pages/servicios/[slug].astro @@ -0,0 +1,60 @@ +--- +import Layout from "../../layouts/BasicLayout.astro"; +import { getCollection } from "astro:content"; +import { marked } from "marked"; + +export async function getStaticPaths() { + const products = await getCollection("products"); + return products.map((p) => ({ params: { slug: p.data?.slug || p.id } })); +} + +const products = await getCollection("products"); +const { slug } = Astro.params; + +const entry = products.find((p) => (p.data?.slug || p.id) == slug); +if (!entry) throw new Error(`Producto no encontrado: ${slug}`); +const product = entry?.data; +if (!product) throw new Error(`Producto no encontrado o mal formado: ${slug}`); +--- + + +
+
+
+
+
+ {product.Name} +
+
+

{product.Name}

+

+ {product.SEO?.metaDescription} +

+

+ {product.PRICES?.[0]?.Price} +

+
+ + +
+
+
+
+
+ +
+
+
+
+
+
+
+
+
diff --git a/src/pages/servicios/index.astro b/src/pages/servicios/index.astro new file mode 100644 index 0000000..29965f6 --- /dev/null +++ b/src/pages/servicios/index.astro @@ -0,0 +1,84 @@ +--- +import Layout from "../../layouts/BasicLayout.astro"; +import CardProduct from "../../components/products/product.cards"; +import { getCollection } from "astro:content"; + +const storeData = await getCollection("store"); +const products = await getCollection("products"); +const pages = await getCollection("pages"); + +const page = pages.find((p) => p.data?.slug === "products")?.data; + +const store = storeData[0]?.data || {}; +const storeSEO = store.SEO || {}; +--- + + +
+
+
+
+
+

{page?.Title || "Servicios"}

+

+ {page?.SEO?.metaDEscription} +

+
+
+
+
+ +
+
+
+ { + products.map((product: any) => ( +
+ + + +
+ )) + } +
+
+ +
+
+

+ ¿Quieres ser el primero en saber sobre nuevos productos? +

+

+ Suscríbete a nuestro boletín y mantente al día con las últimas + novedades +

+
+
+
+ + +
+
+
+
+
+
+
+
diff --git a/src/pages/shopping-cart.astro b/src/pages/shopping-cart.astro deleted file mode 100644 index 425868b..0000000 --- a/src/pages/shopping-cart.astro +++ /dev/null @@ -1,44 +0,0 @@ ---- -import Layout from '../layouts/Layout.astro'; -import data from '../../public/data.json'; -import '../../assets/scss/astro-ecommerce.scss'; -import Navbar from '../components/navbar'; -import UpperNavbar from '../components/store/upperNavbar'; -import CardProduct from '../components/products/cardProduct'; -import ShoppingCart from '../components/cart/shoppingCart'; -import StoreDoubleColumn from '../components/store/storeDoubleColumn'; - -let cartItems = []; -data.shoppingCart.map(id => - data.products.filter(x => x.id == id).map(x => cartItems.push(x)) -) ---- - - -
- - - - -
-
-
You may also like...
- {data.products.map(product => -
- -
- )} -
-
- -
-
- -
\ No newline at end of file diff --git a/src/types.d.ts b/src/types.d.ts new file mode 100644 index 0000000..982a94b --- /dev/null +++ b/src/types.d.ts @@ -0,0 +1,39 @@ +interface BlockText { + text: string; + type?: 'text'; + bold?: boolean; +} + +interface BlockLink { + type: 'link'; + url: string; + children: BlockText[]; +} + +type BlockChild = BlockText | BlockLink; + +export interface ContentBlock { + type: 'paragraph' | 'heading' | 'list' | 'list-item' | 'image' | 'link' | 'quote' | 'code'; + type: string; + level?: number; + image?: { + url: string; + formats?: { + thumbnail?: { url: string }; + small?: { url: string }; + medium?: { url: string }; + large?: { url: string }; + }; + width: number; + height: number; + name: string; + }, + children: Array<{ + type: string; + code?: boolean; + text?: string; + bold?: boolean; + url?: string; + children?: Array<{ text: string; type: string; }>; + }>; +} \ No newline at end of file