mirror of
https://github.com/10h30/blog-balodeplao.git
synced 2026-05-12 15:21:15 +09:00
Initial commit
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
---
|
||||
import BaseLayout from "@/layouts/BaseLayout.astro";
|
||||
import Hero from "@/components/widgets/Hero.astro";
|
||||
|
||||
const metadata = {
|
||||
title: "404 - Page Not Found",
|
||||
description: "The page you're looking for doesn't exist.",
|
||||
ignoreTitleTemplate: true,
|
||||
};
|
||||
---
|
||||
|
||||
<BaseLayout {metadata}>
|
||||
<Hero
|
||||
title={`<h1 class="bg-linear-to-r from-blue-400 via-purple-400 to-pink-400 bg-clip-text text-transparent text-[12rem] font-extrabold tracking-tighter mb-4">404</h1>`}
|
||||
description="We're sorry, we can't find the page you're looking for. It may have been moved or deleted."
|
||||
actions={[
|
||||
{
|
||||
variant: "primary",
|
||||
text: "Back to Home",
|
||||
href: "/",
|
||||
icon: "lucide:home",
|
||||
},
|
||||
{
|
||||
variant: "secondary",
|
||||
text: "Contact",
|
||||
href: "/contact",
|
||||
icon: "lucide:phone",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</BaseLayout>
|
||||
@@ -0,0 +1,86 @@
|
||||
---
|
||||
import BaseLayout from "@/layouts/BaseLayout.astro";
|
||||
import { getImage } from "astro:assets";
|
||||
import Content2 from "@/components/widgets/Content2.astro";
|
||||
import Values from "@/components/widgets/Values.astro";
|
||||
import aboutImage from "@/assets/images/about-office.webp";
|
||||
|
||||
const metadata = {
|
||||
title: "About us",
|
||||
description:
|
||||
"Learn more about our vision, values, and the team behind Astro Starter Pro.",
|
||||
};
|
||||
|
||||
const values = [
|
||||
{
|
||||
title: "Innovation",
|
||||
description:
|
||||
"Curabitur dignissim, felis non sollicitudin molestie, urna mauris pellentesque velit, ut eleifend.",
|
||||
},
|
||||
{
|
||||
title: "Commitment",
|
||||
description:
|
||||
"Aenean condimentum finibus mauris, a fermentum justo pan eget. Sed ultricies, neque quis.",
|
||||
},
|
||||
{
|
||||
title: "Quality",
|
||||
description:
|
||||
"Donec sed orci tincidunt, aliquam nisl a, condimentum nunc. Nulla varius ex nec ante feugiat.",
|
||||
},
|
||||
{
|
||||
title: "Transparency",
|
||||
description:
|
||||
"Phasellus tristique, elit dapibus cursus facilisis, lorem augue fringilla nunc, vitae fermentum.",
|
||||
},
|
||||
{
|
||||
title: "Teamwork",
|
||||
description:
|
||||
"In hac habitasse platea dictumst. Vivamus adipiscing fermentum quam volutpat aliquam. Integer et.",
|
||||
},
|
||||
{
|
||||
title: "Excellence",
|
||||
description:
|
||||
"Fusce at massa nec sapien auctor gravida in in tellus. Vivamus a tristique metus, et molestie.",
|
||||
},
|
||||
];
|
||||
|
||||
const optimizedImage = await getImage({
|
||||
src: aboutImage,
|
||||
format: "webp",
|
||||
});
|
||||
---
|
||||
|
||||
<BaseLayout {metadata}>
|
||||
<link slot="head" rel="preload" href={optimizedImage.src} as="image" />
|
||||
<Content2
|
||||
title="Our Vision"
|
||||
description={[
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.",
|
||||
"Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
|
||||
]}
|
||||
tagline="About"
|
||||
image={aboutImage}
|
||||
imageAlt="Modern web development office"
|
||||
actions={[
|
||||
{
|
||||
text: "Contact Us",
|
||||
href: "/contact",
|
||||
variant: "primary",
|
||||
icon: "lucide:mail",
|
||||
},
|
||||
{
|
||||
text: "View Details",
|
||||
href: "#",
|
||||
variant: "secondary",
|
||||
icon: "lucide:arrow-right",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<Values
|
||||
items={values}
|
||||
columns={3}
|
||||
tagline="Our Values"
|
||||
title="What Defines Us"
|
||||
subtitle="Principles that guide our daily work"
|
||||
/>
|
||||
</BaseLayout>
|
||||
@@ -0,0 +1,54 @@
|
||||
---
|
||||
import BaseLayout from "@/layouts/BaseLayout.astro";
|
||||
import { getCollection } from "astro:content";
|
||||
import Headline from "@/components/ui/Headline.astro";
|
||||
import Pagination from "@/components/ui/Pagination.astro";
|
||||
import PostItem from "@/components/blog/PostItem.astro";
|
||||
import type { GetStaticPathsOptions } from "astro";
|
||||
|
||||
export async function getStaticPaths({ paginate }: GetStaticPathsOptions) {
|
||||
const blogEntries = await getCollection("blog");
|
||||
const sortedPosts = blogEntries
|
||||
.filter((post) => post.data && post.data.pubDate)
|
||||
.sort((a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf());
|
||||
|
||||
return paginate(sortedPosts, { pageSize: 6 });
|
||||
}
|
||||
|
||||
const { page } = Astro.props;
|
||||
const blog = page.data;
|
||||
|
||||
const metadata = {
|
||||
title: "Blog",
|
||||
description: "Latest news and updates from our team.",
|
||||
};
|
||||
---
|
||||
|
||||
<BaseLayout metadata={metadata}>
|
||||
<section class="relative px-4 py-8 sm:px-6 lg:px-8 md:py-12">
|
||||
<div class="absolute inset-0 z-0">
|
||||
<div
|
||||
class="absolute inset-0 bg-linear-to-br from-blue-500/5 via-transparent to-pink-500/5"
|
||||
>
|
||||
</div>
|
||||
</div>
|
||||
<div class="relative mx-auto max-w-5xl">
|
||||
<Headline
|
||||
tagline="Blog"
|
||||
title="Our Publications"
|
||||
subtitle="Explore the latest news, tutorials, and articles from our team."
|
||||
classes={{
|
||||
container: "reveal mb-12 text-center",
|
||||
title:
|
||||
"font-heading mb-4 text-4xl font-bold tracking-tight text-foreground md:text-6xl",
|
||||
subtitle: "mx-auto max-w-3xl text-xl text-muted-foreground",
|
||||
}}
|
||||
/>
|
||||
|
||||
<div class="grid gap-8 md:grid-cols-2 lg:grid-cols-3">
|
||||
{blog.map((post) => <PostItem post={post} />)}
|
||||
</div>
|
||||
<Pagination page={page} />
|
||||
</div>
|
||||
</section>
|
||||
</BaseLayout>
|
||||
@@ -0,0 +1,77 @@
|
||||
---
|
||||
import BaseLayout from "@/layouts/BaseLayout.astro";
|
||||
import Schema from "@/components/seo/Schema.astro";
|
||||
|
||||
import { getCollection, render } from "astro:content";
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const blog = await getCollection("blog");
|
||||
return blog.map((post) => ({
|
||||
params: { slug: post.id },
|
||||
props: { post },
|
||||
}));
|
||||
}
|
||||
|
||||
const { post } = Astro.props;
|
||||
const { Content, remarkPluginFrontmatter } = await render(post);
|
||||
const { title, description, pubDate, author, image } = post.data;
|
||||
|
||||
const formattedDate = pubDate.toLocaleDateString("es-ES", {
|
||||
year: "numeric",
|
||||
month: "long",
|
||||
day: "numeric",
|
||||
});
|
||||
|
||||
const readingTime = remarkPluginFrontmatter?.minutesRead
|
||||
? `${Math.ceil(remarkPluginFrontmatter.minutesRead)} min de lectura`
|
||||
: "";
|
||||
|
||||
const metadata = {
|
||||
title: title,
|
||||
description: description,
|
||||
ogImage: image,
|
||||
};
|
||||
---
|
||||
|
||||
<BaseLayout metadata={metadata}>
|
||||
<Schema
|
||||
type="BlogPosting"
|
||||
data={{
|
||||
title,
|
||||
description,
|
||||
image,
|
||||
pubDate,
|
||||
author,
|
||||
url: Astro.url.href,
|
||||
}}
|
||||
/>
|
||||
<section class="relative px-4 py-8 sm:px-6 lg:px-8 md:py-12">
|
||||
<div class="relative mx-auto max-w-3xl">
|
||||
<div class="reveal mb-10 text-center">
|
||||
<p class="text-sm font-semibold tracking-wide text-primary uppercase">
|
||||
{formattedDate} • {author}
|
||||
{readingTime && ` • ${readingTime}`}
|
||||
</p>
|
||||
<h1
|
||||
class="font-heading mt-2 text-3xl font-bold leading-tight tracking-tighter text-foreground sm:text-4xl md:text-5xl"
|
||||
>
|
||||
{title}
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
{
|
||||
image && (
|
||||
<div class="reveal relative mb-8 h-96 w-full overflow-hidden rounded-xl shadow-lg">
|
||||
<img src={image} alt={title} class="h-full w-full object-cover" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
<div
|
||||
class="reveal prose prose-lg dark:prose-invert mx-auto prose-headings:text-foreground prose-a:text-primary hover:prose-a:underline prose-p:text-muted-foreground prose-strong:text-foreground prose-li:text-muted-foreground prose-code:text-primary"
|
||||
>
|
||||
<Content />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</BaseLayout>
|
||||
@@ -0,0 +1,65 @@
|
||||
---
|
||||
import BaseLayout from "@/layouts/BaseLayout.astro";
|
||||
import { getCollection } from "astro:content";
|
||||
import Headline from "@/components/ui/Headline.astro";
|
||||
import PostItem from "@/components/blog/PostItem.astro";
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const allPosts = await getCollection("blog");
|
||||
const posts = allPosts.filter((post) => post.data && post.data.pubDate); // Ensure published
|
||||
|
||||
const categories = new Set();
|
||||
posts.forEach((post) => {
|
||||
if (post.data.category) {
|
||||
categories.add(post.data.category);
|
||||
}
|
||||
});
|
||||
|
||||
return Array.from(categories).map((category) => {
|
||||
return {
|
||||
params: { category: category as string },
|
||||
props: {
|
||||
category,
|
||||
posts: posts.filter((post) => post.data.category === category),
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
const { category, posts } = Astro.props;
|
||||
|
||||
const metadata = {
|
||||
title: `Category: ${category}`,
|
||||
description: `Articles in the ${category} category.`,
|
||||
};
|
||||
---
|
||||
|
||||
<BaseLayout metadata={metadata}>
|
||||
<section class="relative px-4 py-24 sm:px-6 lg:px-8 md:py-32">
|
||||
<div class="relative mx-auto max-w-5xl">
|
||||
<Headline
|
||||
tagline="Category"
|
||||
title={category}
|
||||
subtitle={`Showing ${posts.length} article${posts.length === 1 ? "" : "s"}.`}
|
||||
classes={{
|
||||
container: "mb-12 text-center",
|
||||
title:
|
||||
"font-heading mb-4 text-4xl font-bold tracking-tight text-foreground md:text-6xl capitalized",
|
||||
subtitle: "mx-auto max-w-3xl text-xl text-muted-foreground",
|
||||
}}
|
||||
/>
|
||||
|
||||
<div class="mb-8 text-center">
|
||||
<a href="/blog" class="text-primary hover:underline">← Back to blog</a>
|
||||
</div>
|
||||
|
||||
<div class="grid gap-8 md:grid-cols-2 lg:grid-cols-3">
|
||||
{
|
||||
posts
|
||||
.sort((a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf())
|
||||
.map((post) => <PostItem post={post} />)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</BaseLayout>
|
||||
@@ -0,0 +1,63 @@
|
||||
---
|
||||
import BaseLayout from "@/layouts/BaseLayout.astro";
|
||||
import { getCollection } from "astro:content";
|
||||
import Headline from "@/components/ui/Headline.astro";
|
||||
import PostItem from "@/components/blog/PostItem.astro";
|
||||
|
||||
export async function getStaticPaths() {
|
||||
const allPosts = await getCollection("blog");
|
||||
const posts = allPosts.filter((post) => post.data && post.data.pubDate); // Ensure published
|
||||
|
||||
const tags = new Set();
|
||||
posts.forEach((post) => {
|
||||
post.data.tags?.forEach((tag) => tags.add(tag));
|
||||
});
|
||||
|
||||
return Array.from(tags).map((tag) => {
|
||||
return {
|
||||
params: { tag: tag as string },
|
||||
props: {
|
||||
tag,
|
||||
posts: posts.filter((post) => post.data.tags?.includes(tag as string)),
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
const { tag, posts } = Astro.props;
|
||||
|
||||
const metadata = {
|
||||
title: `Posts tagged with '${tag}'`,
|
||||
description: `Explore our articles about ${tag}.`,
|
||||
};
|
||||
---
|
||||
|
||||
<BaseLayout metadata={metadata}>
|
||||
<section class="relative px-4 py-24 sm:px-6 lg:px-8 md:py-32">
|
||||
<div class="relative mx-auto max-w-5xl">
|
||||
<Headline
|
||||
tagline="Tag"
|
||||
title={`#${tag}`}
|
||||
subtitle={`Showing ${posts.length} article${posts.length === 1 ? "" : "s"}.`}
|
||||
classes={{
|
||||
container: "mb-12 text-center",
|
||||
title:
|
||||
"font-heading mb-4 text-4xl font-bold tracking-tight text-foreground md:text-6xl capitalized",
|
||||
subtitle: "mx-auto max-w-3xl text-xl text-muted-foreground",
|
||||
}}
|
||||
/>
|
||||
|
||||
<div class="mb-8 text-center">
|
||||
<a href="/blog" class="text-primary hover:underline">← Back to blog</a>
|
||||
</div>
|
||||
|
||||
<div class="grid gap-8 md:grid-cols-2 lg:grid-cols-3">
|
||||
{
|
||||
posts
|
||||
.sort((a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf())
|
||||
.map((post) => <PostItem post={post} />)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</BaseLayout>
|
||||
@@ -0,0 +1,66 @@
|
||||
---
|
||||
import BaseLayout from "@/layouts/BaseLayout.astro";
|
||||
import Features from "@/components/widgets/Features.astro";
|
||||
import Content from "@/components/widgets/Content.astro";
|
||||
import Form from "@/components/ui/Form.astro";
|
||||
|
||||
const metadata = {
|
||||
title: "Contact",
|
||||
description: "Get in touch with us to discuss your next project.",
|
||||
};
|
||||
|
||||
const visionText = ["Get in touch with us to discuss your next project."];
|
||||
---
|
||||
|
||||
<BaseLayout {metadata}>
|
||||
<Content tagline="Contact" title="Contact" description={visionText} />
|
||||
<div
|
||||
class="reveal mx-auto max-w-xl bg-card border border-border rounded-3xl p-8 shadow-sm mb-12 md:mb-16"
|
||||
>
|
||||
<Form />
|
||||
</div>
|
||||
<Features
|
||||
tagline="Contact Means"
|
||||
title="We are here to help you"
|
||||
subtitle="Choose the communication channel you prefer. We respond in less than 24 hours."
|
||||
classes={{ container: "pt-0 md:pt-0" }}
|
||||
features={[
|
||||
{
|
||||
title: "Phone",
|
||||
description: "+123 456 7890",
|
||||
icon: "lucide:phone",
|
||||
iconClass: "bg-green-500/10 text-green-400",
|
||||
},
|
||||
{
|
||||
title: "Email",
|
||||
description: "contact@company.com",
|
||||
icon: "lucide:mail",
|
||||
iconClass: "bg-yellow-500/10 text-yellow-400",
|
||||
},
|
||||
{
|
||||
title: "Location",
|
||||
description: "City, Country",
|
||||
icon: "lucide:map-pin",
|
||||
iconClass: "bg-red-500/10 text-red-400",
|
||||
},
|
||||
{
|
||||
title: "Personalized Attention",
|
||||
description: "We understand your needs to offer tailored solutions.",
|
||||
icon: "lucide:user-check",
|
||||
iconClass: "bg-blue-500/10 text-blue-400",
|
||||
},
|
||||
{
|
||||
title: "Technical Support",
|
||||
description: "We resolve any doubt or technical incident quickly.",
|
||||
icon: "lucide:wrench",
|
||||
iconClass: "bg-purple-500/10 text-purple-400",
|
||||
},
|
||||
{
|
||||
title: "Strategic Consulting",
|
||||
description: "We advise you to ensure the success of your project.",
|
||||
icon: "lucide:briefcase",
|
||||
iconClass: "bg-pink-500/10 text-pink-400",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
</BaseLayout>
|
||||
@@ -0,0 +1,134 @@
|
||||
---
|
||||
import BaseLayout from "@/layouts/BaseLayout.astro";
|
||||
import { siteConfig } from "@/config/site";
|
||||
import Hero from "@/components/widgets/Hero.astro";
|
||||
import Features from "@/components/widgets/Features.astro";
|
||||
import devImg from "@/assets/images/dev_balanced.png";
|
||||
import openSourceImg from "@/assets/images/open-source.png";
|
||||
import Content2 from "@/components/widgets/Content2.astro";
|
||||
const metadata = {
|
||||
title: `${siteConfig.name} — The next step for your project`,
|
||||
description:
|
||||
"A modern and professional template for your web projects with Astro and Tailwind CSS. Boost your development with a solid foundation.",
|
||||
ignoreTitleTemplate: true,
|
||||
};
|
||||
---
|
||||
|
||||
<BaseLayout {metadata}>
|
||||
<Hero
|
||||
title={`Starter Template for <br class="hidden md:block" /> <span class="bg-linear-to-r from-blue-400 via-purple-400 to-pink-400 bg-clip-text text-transparent">Web Developers</span>`}
|
||||
tagline="Astro v5 + Tailwind v4"
|
||||
description={`${siteConfig.description}`}
|
||||
actions={[
|
||||
{
|
||||
text: "Get Started",
|
||||
href: "https://github.com/devgelo-labs/astro-starter-pro",
|
||||
variant: "primary",
|
||||
icon: "lucide:github",
|
||||
},
|
||||
{
|
||||
text: "Our Services",
|
||||
href: "/services",
|
||||
variant: "secondary",
|
||||
icon: "lucide:arrow-right",
|
||||
ariaLabel: "Learn more about our services",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<Features
|
||||
tagline="Features"
|
||||
title="What's Included"
|
||||
subtitle="A selection of tools and configurations to streamline your workflow."
|
||||
features={[
|
||||
{
|
||||
title: "Optimized SEO",
|
||||
description:
|
||||
"Base configuration for Meta tags, Open Graph, and Sitemap generation.",
|
||||
icon: "lucide:scan-search",
|
||||
iconClass: "bg-blue-500/10 text-blue-400",
|
||||
},
|
||||
{
|
||||
title: "High Performance",
|
||||
description: "Lightweight structure for fast load times.",
|
||||
icon: "lucide:zap",
|
||||
iconClass: "bg-purple-500/10 text-purple-400",
|
||||
},
|
||||
{
|
||||
title: "Tailwind v4",
|
||||
description:
|
||||
"Integrated configuration with the latest version of Tailwind CSS.",
|
||||
icon: "lucide:palette",
|
||||
iconClass: "bg-pink-500/10 text-pink-400",
|
||||
},
|
||||
]}
|
||||
/>
|
||||
<Content2
|
||||
items={[
|
||||
{
|
||||
title: "Responsive Design",
|
||||
description:
|
||||
"Base configuration for Meta tags, Open Graph, and Sitemap generation.",
|
||||
icon: "lucide:scan-search",
|
||||
iconClass: "bg-blue-500/10 text-blue-400",
|
||||
},
|
||||
{
|
||||
title: "High Performance",
|
||||
description: "Lightweight structure for fast load times.",
|
||||
icon: "lucide:zap",
|
||||
iconClass: "bg-purple-500/10 text-purple-400",
|
||||
},
|
||||
{
|
||||
title: "Tailwind v4",
|
||||
description:
|
||||
"Integrated configuration with the latest version of Tailwind CSS.",
|
||||
icon: "lucide:palette",
|
||||
iconClass: "bg-pink-500/10 text-pink-400",
|
||||
},
|
||||
]}
|
||||
image={devImg}
|
||||
imageAlt="Development"
|
||||
>
|
||||
<Fragment>
|
||||
<h3 class="text-2xl font-bold tracking-tight sm:text-3xl mb-2">
|
||||
Development
|
||||
</h3>
|
||||
We provide a solid foundation to start your projects with best practices.
|
||||
</Fragment>
|
||||
</Content2>
|
||||
<Content2
|
||||
items={[
|
||||
{
|
||||
title: "Open Source",
|
||||
description:
|
||||
"Developed under the MIT license, free for personal and commercial use.",
|
||||
icon: "lucide:github",
|
||||
iconClass: "bg-indigo-500/10 text-indigo-400",
|
||||
},
|
||||
{
|
||||
title: "Community Driven",
|
||||
description:
|
||||
"Built with the feedback and contributions of the developer community.",
|
||||
icon: "lucide:users",
|
||||
iconClass: "bg-orange-500/10 text-orange-400",
|
||||
},
|
||||
{
|
||||
title: "Regular Updates",
|
||||
description:
|
||||
"Continuously improved with the latest technologies and best practices.",
|
||||
icon: "lucide:refresh-cw",
|
||||
iconClass: "bg-teal-500/10 text-teal-400",
|
||||
},
|
||||
]}
|
||||
image={openSourceImg}
|
||||
imageAlt="Community and Open Source"
|
||||
isReversed={true}
|
||||
>
|
||||
<Fragment>
|
||||
<h3 class="text-2xl font-bold tracking-tight sm:text-3xl mb-2">
|
||||
Open Source & Community
|
||||
</h3>
|
||||
Join the revolution of modern web development. This project is open for everyone
|
||||
to use, learn from, and contribute to.
|
||||
</Fragment>
|
||||
</Content2>
|
||||
</BaseLayout>
|
||||
@@ -0,0 +1,17 @@
|
||||
import type { APIRoute } from "astro";
|
||||
import { siteConfig } from "@/config/site";
|
||||
|
||||
const robotsTxt = `
|
||||
User-agent: *
|
||||
Allow: /
|
||||
|
||||
Sitemap: ${new URL("sitemap-index.xml", siteConfig.url).href}
|
||||
`.trim();
|
||||
|
||||
export const GET: APIRoute = () => {
|
||||
return new Response(robotsTxt, {
|
||||
headers: {
|
||||
"Content-Type": "text/plain; charset=utf-8",
|
||||
},
|
||||
});
|
||||
};
|
||||
@@ -0,0 +1,26 @@
|
||||
import rss from "@astrojs/rss";
|
||||
import { getCollection } from "astro:content";
|
||||
import { siteConfig } from "@/config/site";
|
||||
|
||||
export async function GET(context) {
|
||||
const blog = await getCollection("blog");
|
||||
|
||||
return rss({
|
||||
title: siteConfig.name,
|
||||
description: siteConfig.description,
|
||||
site: context.site,
|
||||
items: blog
|
||||
.sort((a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf())
|
||||
.map((post) => ({
|
||||
title: post.data.title,
|
||||
pubDate: post.data.pubDate,
|
||||
description: post.data.description,
|
||||
link: `/blog/${post.id}/`,
|
||||
content: post.body, // Optional: include full content
|
||||
customData: post.data.author
|
||||
? `<author>${post.data.author}</author>`
|
||||
: undefined,
|
||||
})),
|
||||
customData: `<language>${siteConfig.locale}</language>`,
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
---
|
||||
import BaseLayout from "@/layouts/BaseLayout.astro";
|
||||
import ServiceList from "@/components/widgets/ServiceList.astro";
|
||||
import Content from "@/components/widgets/Content.astro";
|
||||
import Content2 from "@/components/widgets/Content2.astro";
|
||||
import webDevImg from "@/assets/images/services/web-dev.webp";
|
||||
import seoImg from "@/assets/images/services/seo.webp";
|
||||
import consultingImg from "@/assets/images/services/consulting.webp";
|
||||
|
||||
const services = [
|
||||
{
|
||||
title: "Web Development",
|
||||
description: "Static and dynamic sites built for the modern era.",
|
||||
icon: "lucide:globe",
|
||||
},
|
||||
{
|
||||
title: "SEO Optimization",
|
||||
description: "We ensure your content is found by those looking for it.",
|
||||
icon: "lucide:search",
|
||||
},
|
||||
{
|
||||
title: "IT Consulting",
|
||||
description: "Technical advice to scale your projects to the next level.",
|
||||
icon: "lucide:rocket",
|
||||
},
|
||||
];
|
||||
const metadata = {
|
||||
title: "Services",
|
||||
description:
|
||||
"Discover our web development, SEO optimization, and technology consulting services.",
|
||||
};
|
||||
---
|
||||
|
||||
<BaseLayout {metadata}>
|
||||
<Content
|
||||
tagline="Services"
|
||||
title="Our Services"
|
||||
description={[
|
||||
"Comprehensive solutions designed to maximize the potential of your digital presence.",
|
||||
]}
|
||||
/>
|
||||
<ServiceList services={services} classes={{ container: "pt-0 md:pt-0" }} />
|
||||
<Content
|
||||
tagline="Web Development"
|
||||
title="Modern Web Development"
|
||||
description={[
|
||||
"We specialize in building fast, secure, and scalable websites using the latest technologies. We transform your vision into an impactful digital experience.",
|
||||
]}
|
||||
classes={{ container: "pb-0 md:pb-0" }}
|
||||
/>
|
||||
<Content2
|
||||
items={[
|
||||
{
|
||||
title: "Responsive Design",
|
||||
description:
|
||||
"Your site will look perfect on any device, from mobiles to desktop screens.",
|
||||
},
|
||||
{
|
||||
title: "Optimized Performance",
|
||||
description:
|
||||
"Fast loading to improve user experience and SEO positioning.",
|
||||
},
|
||||
]}
|
||||
image={webDevImg}
|
||||
imageAlt="Modern Web Development"
|
||||
classes={{ container: "pt-0 md:pt-0" }}
|
||||
>
|
||||
<Fragment>
|
||||
<h3 class="text-2xl font-bold tracking-tight sm:text-3xl mb-2">
|
||||
Modern Web Development
|
||||
</h3>
|
||||
We specialize in building fast, secure, and scalable websites using the latest
|
||||
technologies. We transform your vision into an impactful digital experience.
|
||||
</Fragment>
|
||||
</Content2>
|
||||
|
||||
<Content2
|
||||
isReversed={true}
|
||||
items={[
|
||||
{
|
||||
title: "SEO Audit",
|
||||
description:
|
||||
"We deeply analyze your website to identify technical and content improvement opportunities.",
|
||||
},
|
||||
{
|
||||
title: "Content Strategy",
|
||||
description:
|
||||
"We create relevant content plans that attract and retain your target audience.",
|
||||
},
|
||||
]}
|
||||
image={seoImg}
|
||||
imageAlt="SEO Strategies"
|
||||
>
|
||||
<Fragment>
|
||||
<h3 class="text-2xl font-bold tracking-tight sm:text-3xl mb-2">
|
||||
SEO Optimization
|
||||
</h3>
|
||||
We help your business get found by the right people. Our organic positioning
|
||||
strategies are designed to improve your organic visibility.
|
||||
</Fragment>
|
||||
</Content2>
|
||||
|
||||
<Content2
|
||||
items={[
|
||||
{
|
||||
title: "Digital Transformation",
|
||||
description:
|
||||
"We guide you in adopting new technologies to optimize your business processes.",
|
||||
},
|
||||
{
|
||||
title: "Software Architecture",
|
||||
description:
|
||||
"We design robust and scalable systems prepared for future growth.",
|
||||
},
|
||||
]}
|
||||
image={consultingImg}
|
||||
imageAlt="Technology Consulting"
|
||||
>
|
||||
<Fragment>
|
||||
<h3 class="text-2xl font-bold tracking-tight sm:text-3xl mb-2">
|
||||
Technology Consulting
|
||||
</h3>
|
||||
We accompany you in critical decision-making. We evaluate your current infrastructure
|
||||
and design personalized roadmaps to take your company to the next technological
|
||||
level.
|
||||
</Fragment>
|
||||
</Content2>
|
||||
</BaseLayout>
|
||||
@@ -0,0 +1,231 @@
|
||||
---
|
||||
import BaseLayout from "@/layouts/BaseLayout.astro";
|
||||
import Hero from "@/components/widgets/Hero.astro";
|
||||
import Features from "@/components/widgets/Features.astro";
|
||||
import Content from "@/components/widgets/Content.astro";
|
||||
import Content2 from "@/components/widgets/Content2.astro";
|
||||
import ServiceList from "@/components/widgets/ServiceList.astro";
|
||||
import Values from "@/components/widgets/Values.astro";
|
||||
import aboutImage from "@/assets/images/about-office.webp";
|
||||
|
||||
const heroProps = {
|
||||
title: "Lorem Ipsum Dolor Sit Amet",
|
||||
tagline: "Hero",
|
||||
description:
|
||||
"Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.",
|
||||
actions: [
|
||||
{
|
||||
text: "Get Started",
|
||||
href: "https://github.com/devgelo-labs/astro-starter-pro",
|
||||
variant: "primary",
|
||||
icon: "lucide:github",
|
||||
},
|
||||
{
|
||||
text: "View Details",
|
||||
href: "#",
|
||||
variant: "secondary",
|
||||
icon: "lucide:arrow-right",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const featuresProps = {
|
||||
title: "Quis Nostrud Exercitation",
|
||||
subtitle: "Ullamco laboris nisi ut aliquip ex ea commodo",
|
||||
tagline: "Features",
|
||||
features: [
|
||||
{
|
||||
title: "Lorem Ipsum",
|
||||
description: "Dolor sit amet, consectetur adipiscing elit.",
|
||||
icon: "lucide:box",
|
||||
},
|
||||
{
|
||||
title: "Sed Do Eiusmod",
|
||||
description: "Tempor incididunt ut labore et dolore magna aliqua.",
|
||||
icon: "lucide:check",
|
||||
},
|
||||
{
|
||||
title: "Ut Enim Ad",
|
||||
description: "Minim veniam, quis nostrud exercitation ullamco.",
|
||||
icon: "lucide:eye",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const contentProps = {
|
||||
title: "Duis Aute Irure Dolor",
|
||||
description: [
|
||||
"In reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
|
||||
"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium.",
|
||||
],
|
||||
tagline: "Content",
|
||||
image: aboutImage,
|
||||
imageAlt: "Placeholder image",
|
||||
isReversed: false,
|
||||
actions: [
|
||||
{
|
||||
text: "Call to Action",
|
||||
href: "#",
|
||||
variant: "primary",
|
||||
icon: "lucide:github",
|
||||
},
|
||||
{
|
||||
text: "View details",
|
||||
href: "#",
|
||||
variant: "secondary",
|
||||
icon: "lucide:arrow-right",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const content2Props = {
|
||||
title: "Duis Aute Irure Dolor",
|
||||
description: [
|
||||
"In reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
|
||||
"Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium.",
|
||||
],
|
||||
tagline: "Content2",
|
||||
image: aboutImage,
|
||||
imageAlt: "Placeholder image",
|
||||
isReversed: false,
|
||||
actions: [
|
||||
{
|
||||
text: "Call to Action",
|
||||
href: "#",
|
||||
variant: "primary",
|
||||
icon: "lucide:github",
|
||||
},
|
||||
{
|
||||
text: "View details",
|
||||
href: "#",
|
||||
variant: "secondary",
|
||||
icon: "lucide:arrow-right",
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const content2InvertedProps = {
|
||||
items: [
|
||||
{
|
||||
title: "Open Source",
|
||||
description:
|
||||
"Developed under the MIT license, free for personal and commercial use.",
|
||||
icon: "lucide:github",
|
||||
iconClass: "bg-indigo-500/10 text-indigo-400",
|
||||
},
|
||||
{
|
||||
title: "Community Driven",
|
||||
description:
|
||||
"Built with the feedback and contributions of the developer community.",
|
||||
icon: "lucide:users",
|
||||
iconClass: "bg-orange-500/10 text-orange-400",
|
||||
},
|
||||
{
|
||||
title: "Regular Updates",
|
||||
description:
|
||||
"Continuously improved with the latest technologies and best practices.",
|
||||
icon: "lucide:refresh-cw",
|
||||
iconClass: "bg-teal-500/10 text-teal-400",
|
||||
},
|
||||
],
|
||||
image: aboutImage,
|
||||
imageAlt: "Community and Open Source",
|
||||
isReversed: true,
|
||||
actions: [
|
||||
{
|
||||
text: "Call to Action",
|
||||
href: "#",
|
||||
variant: "primary",
|
||||
icon: "lucide:github",
|
||||
},
|
||||
{
|
||||
text: "View details",
|
||||
href: "#",
|
||||
variant: "secondary",
|
||||
icon: "lucide:arrow-right",
|
||||
},
|
||||
],
|
||||
title: "Open Source",
|
||||
subtitle:
|
||||
"Built with the feedback and contributions of the developer community.",
|
||||
tagline: "Content2",
|
||||
};
|
||||
|
||||
const serviceListProps = {
|
||||
services: [
|
||||
{
|
||||
title: "Voluptatem Accusantium",
|
||||
description: "Doloremque laudantium, totam rem aperiam.",
|
||||
icon: "lucide:rocket",
|
||||
},
|
||||
{
|
||||
title: "Ipsa Quae Ab",
|
||||
description: "Illo inventore veritatis et quasi architecto.",
|
||||
icon: "lucide:lightbulb",
|
||||
},
|
||||
{
|
||||
title: "Beatae Vitae Dicta",
|
||||
description: "Sunt explicabo. Nemo enim ipsam voluptatem.",
|
||||
icon: "lucide:wrench",
|
||||
},
|
||||
],
|
||||
title: "Services that will help you achieve your goals",
|
||||
subtitle: "What we offer",
|
||||
tagline: "Services",
|
||||
};
|
||||
|
||||
const valuesProps = {
|
||||
items: [
|
||||
{
|
||||
title: "Corporate",
|
||||
description:
|
||||
"Curabitur dignissim, felis non sollicitudin molestie, urna mauris pellentesque velit, ut eleifend.",
|
||||
},
|
||||
{
|
||||
title: "Creative",
|
||||
description:
|
||||
"Aenean condimentum finibus mauris, a fermentum justo pan eget. Sed ultricies, neque quis.",
|
||||
},
|
||||
{
|
||||
title: "Startups",
|
||||
description:
|
||||
"Donec sed orci tincidunt, aliquam nisl a, condimentum nunc. Nulla varius ex nec ante feugiat.",
|
||||
},
|
||||
{
|
||||
title: "SaaS",
|
||||
description:
|
||||
"Phasellus tristique, elit dapibus cursus facilisis, lorem augue fringilla nunc, vitae fermentum.",
|
||||
},
|
||||
{
|
||||
title: "Education",
|
||||
description:
|
||||
"In hac habitasse platea dictumst. Vivamus adipiscing fermentum quam volutpat aliquam. Integer et.",
|
||||
},
|
||||
{
|
||||
title: "Real Estate",
|
||||
description:
|
||||
"Fusce at massa nec sapien auctor gravida in in tellus. Vivamus a tristique metus, et molestie.",
|
||||
},
|
||||
],
|
||||
columns: 3 as const,
|
||||
tagline: "Values",
|
||||
title: "What defines us",
|
||||
subtitle: "Principles that guide our daily work",
|
||||
};
|
||||
|
||||
const metadata = {
|
||||
title: "Widgets - Astro Starter Pro",
|
||||
description: "Showcase of available components and widgets.",
|
||||
ignoreTitleTemplate: true,
|
||||
};
|
||||
---
|
||||
|
||||
<BaseLayout {metadata}>
|
||||
<Hero {...heroProps} />
|
||||
<Features {...featuresProps} />
|
||||
<Content {...contentProps} />
|
||||
<Content2 {...content2Props} />
|
||||
<Content2 {...content2InvertedProps} />
|
||||
<ServiceList {...serviceListProps} />
|
||||
<Values {...valuesProps} />
|
||||
</BaseLayout>
|
||||
Reference in New Issue
Block a user