fix blog page
This commit is contained in:
@@ -1,64 +1,11 @@
|
||||
import React from "react";
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import { ScrollReveal } from "@/animations/Reveal";
|
||||
import { blogPosts } from "@/data/blog";
|
||||
|
||||
export default function BlogGrid() {
|
||||
const blogs = [
|
||||
{
|
||||
title: "How AI Is Transforming Last-Mile EV Delivery",
|
||||
excerpt: "Machine learning and real-time data are reshaping how fleets plan, dispatch, and adapt — making every kilometre smarter than the last.",
|
||||
category: "Technology",
|
||||
image: "/images/blog-post-pic-17.png",
|
||||
},
|
||||
{
|
||||
title: "The EV Paradox: Solving Range Anxiety for Urban Fleets",
|
||||
excerpt: "Electric vehicles promise sustainability, but battery constraints introduce a new routing challenge. Here's how MileTruth™ AI solves it before dispatch.",
|
||||
category: "EV Fleet",
|
||||
image: "/images/ev-paradox.png",
|
||||
},
|
||||
{
|
||||
title: "42% Less Distance: Insights from Our Hyderabad Hub",
|
||||
excerpt: "A detailed look at how Doormile's MileTruth routing engine delivered measurable efficiency gains — fewer vehicles, less fuel, and zero SLA misses.",
|
||||
category: "Case Study",
|
||||
image: "/images/blog-post-pic-15.png",
|
||||
},
|
||||
{
|
||||
title: "MileTruth™ AI — 10 Stages to Smarter Dispatch",
|
||||
excerpt: "From order ingestion to final route output in under 45ms — a technical walkthrough of the ten-stage pipeline at the heart of our routing engine.",
|
||||
category: "MileTruth",
|
||||
image: "/images/blog-post-pic-31.png",
|
||||
},
|
||||
{
|
||||
title: "Why Mathematical Precision Beats Heuristics in Routing",
|
||||
excerpt: "Most routing tools guess. We calculate. Powered by Google OR-Tools, MileTruth evaluates six parallel strategy universes to select the optimal route every time.",
|
||||
category: "Technology",
|
||||
image: "/images/blog-post-pic-14.jpeg",
|
||||
},
|
||||
{
|
||||
title: "Fleet Reduction Without Compromising Delivery Volume",
|
||||
excerpt: "Deploying 37% fewer vehicles while handling the same order volumes isn't a trade-off — it's the result of smarter routing intelligence applied at every dispatch.",
|
||||
category: "Fleet Management",
|
||||
image: "/images/blog-post-pic-8.jpeg",
|
||||
},
|
||||
{
|
||||
title: "Building a Greener City: The Future of Urban Logistics",
|
||||
excerpt: "Cities are demanding cleaner delivery. We explore how AI-powered EV fleets and optimised routing create a path to zero-emission last-mile logistics at city scale.",
|
||||
category: "Sustainability",
|
||||
image: "/images/blog-post-pic-6.jpeg",
|
||||
},
|
||||
{
|
||||
title: "How Doormile Maintains 99.9% SLA Compliance at Scale",
|
||||
excerpt: "Hitting SLA targets 99.9% of the time isn't luck — it's the product of ETA pre-validation, real-time rebalancing, and a routing engine built with delivery reliability as its first constraint.",
|
||||
category: "Operations",
|
||||
image: "/images/last-mile-approach.jpg",
|
||||
},
|
||||
{
|
||||
title: "Battery Simulation: The Secret to EV Route Pre-Validation",
|
||||
excerpt: "Before a single rider leaves the hub, MileTruth™ simulates every route against real charge capacity — eliminating mid-route failures and protecting your fulfillment rate.",
|
||||
category: "EV Fleet",
|
||||
image: "/images/blog-post-pic-3.jpeg",
|
||||
},
|
||||
];
|
||||
const blogs = blogPosts;
|
||||
|
||||
return (
|
||||
<div className="elementor-element elementor-element-c70681e e-flex e-con-boxed cut-corner-no sticky-container-off e-con e-parent" data-id="c70681e" data-element_type="container" data-e-type="container">
|
||||
@@ -135,9 +82,18 @@ export default function BlogGrid() {
|
||||
font-family: var(--font-manrope), sans-serif !important;
|
||||
}
|
||||
|
||||
/* Bottom block pinned to the card base — keeps Read More + image at the
|
||||
same vertical position across cards with different text lengths. */
|
||||
.custom-blog-bottom {
|
||||
display: flex !important;
|
||||
flex-direction: column !important;
|
||||
margin-top: auto !important;
|
||||
}
|
||||
|
||||
.custom-blog-readmore {
|
||||
display: inline-flex !important;
|
||||
align-items: center !important;
|
||||
align-self: flex-start !important;
|
||||
gap: 6px !important;
|
||||
font-size: 13px !important;
|
||||
font-weight: 800 !important;
|
||||
@@ -162,7 +118,6 @@ export default function BlogGrid() {
|
||||
aspect-ratio: 4 / 3 !important;
|
||||
border-radius: 20px !important;
|
||||
overflow: hidden !important;
|
||||
margin-top: auto !important;
|
||||
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.05) !important;
|
||||
}
|
||||
|
||||
@@ -191,8 +146,8 @@ export default function BlogGrid() {
|
||||
<div className="custom-blog-grid">
|
||||
|
||||
{blogs.map((blog, i) => (
|
||||
<ScrollReveal key={i} delay={(i % 3) * 0.08} duration={0.8} yOffset={35}>
|
||||
<div className="custom-blog-card">
|
||||
<ScrollReveal key={blog.slug} delay={(i % 3) * 0.08} duration={0.8} yOffset={35}>
|
||||
<Link href={`/blog/${blog.slug}`} className="custom-blog-card" style={{ textDecoration: "none" }}>
|
||||
{/* Text Block at Top */}
|
||||
<div className="flex flex-col">
|
||||
{/* Bold Title */}
|
||||
@@ -206,21 +161,46 @@ export default function BlogGrid() {
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Image at Bottom */}
|
||||
<div className="custom-blog-img-container">
|
||||
<Image
|
||||
src={blog.image}
|
||||
alt={blog.title}
|
||||
fill
|
||||
style={{ objectFit: "cover" }}
|
||||
sizes="(max-width: 768px) 100vw, 33vw"
|
||||
/>
|
||||
{/* Category Badge overlay */}
|
||||
<span className="custom-blog-badge">
|
||||
{blog.category}
|
||||
{/* Bottom block: Read more + image, pinned to the card
|
||||
base so Read More aligns across every card regardless
|
||||
of title / excerpt length. */}
|
||||
<div className="custom-blog-bottom">
|
||||
{/* Read more affordance (whole card is the link) */}
|
||||
<span className="custom-blog-readmore">
|
||||
Read More
|
||||
<svg
|
||||
className="custom-blog-readmore-arrow"
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2.5"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
aria-hidden="true"
|
||||
>
|
||||
<line x1="5" y1="12" x2="19" y2="12" />
|
||||
<polyline points="12 5 19 12 12 19" />
|
||||
</svg>
|
||||
</span>
|
||||
|
||||
{/* Image */}
|
||||
<div className="custom-blog-img-container">
|
||||
<Image
|
||||
src={blog.image}
|
||||
alt={blog.title}
|
||||
fill
|
||||
style={{ objectFit: "cover" }}
|
||||
sizes="(max-width: 768px) 100vw, 33vw"
|
||||
/>
|
||||
{/* Category Badge overlay */}
|
||||
<span className="custom-blog-badge">
|
||||
{blog.category}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
</ScrollReveal>
|
||||
))}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user