working
This commit is contained in:
+242
-34
@@ -1065,9 +1065,96 @@
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.news-toolbar {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
gap: 16px;
|
||||
flex-wrap: wrap;
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
|
||||
.news-search {
|
||||
width: min(420px, 100%);
|
||||
padding: 14px 18px;
|
||||
border-radius: 999px;
|
||||
border: 1px solid rgba(230, 81, 0, 0.18);
|
||||
background: rgba(255, 243, 224, 0.8);
|
||||
color: var(--white);
|
||||
font: inherit;
|
||||
}
|
||||
|
||||
.news-search:focus {
|
||||
outline: none;
|
||||
border-color: var(--gold);
|
||||
box-shadow: 0 0 0 3px var(--gold-glow);
|
||||
}
|
||||
|
||||
.news-meta {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 10px;
|
||||
flex-wrap: wrap;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
.news-count {
|
||||
font-size: 0.72rem;
|
||||
letter-spacing: 0.12em;
|
||||
text-transform: uppercase;
|
||||
color: var(--grey);
|
||||
}
|
||||
|
||||
.news-pager {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.news-page-btn {
|
||||
padding: 12px 16px;
|
||||
border-radius: 999px;
|
||||
border: 1px solid rgba(93, 64, 55, 0.16);
|
||||
background: rgba(255, 243, 224, 0.82);
|
||||
color: var(--white);
|
||||
font-size: 0.72rem;
|
||||
font-weight: 700;
|
||||
letter-spacing: 0.12em;
|
||||
text-transform: uppercase;
|
||||
cursor: pointer;
|
||||
transition: border-color 0.2s, color 0.2s, background 0.2s;
|
||||
}
|
||||
|
||||
.news-page-btn:hover:not(:disabled) {
|
||||
border-color: var(--gold);
|
||||
color: var(--gold);
|
||||
}
|
||||
|
||||
.news-page-btn:disabled {
|
||||
opacity: 0.45;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
.news-card {
|
||||
padding: 22px;
|
||||
padding: 0;
|
||||
border-radius: 24px;
|
||||
overflow: hidden;
|
||||
background: var(--card);
|
||||
}
|
||||
|
||||
.news-card-image {
|
||||
width: 100%;
|
||||
height: 190px;
|
||||
object-fit: cover;
|
||||
}
|
||||
|
||||
.news-card-body {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
min-height: 210px;
|
||||
padding: 20px;
|
||||
background: var(--lift);
|
||||
}
|
||||
|
||||
.news-area,
|
||||
@@ -1108,6 +1195,29 @@
|
||||
color: var(--grey);
|
||||
}
|
||||
|
||||
.news-link {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: 8px;
|
||||
align-self: flex-start;
|
||||
margin-top: 18px;
|
||||
font-size: 0.72rem;
|
||||
font-weight: 700;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.12em;
|
||||
color: var(--gold);
|
||||
}
|
||||
|
||||
.news-empty {
|
||||
grid-column: 1 / -1;
|
||||
padding: 24px;
|
||||
border-radius: 24px;
|
||||
background: rgba(255, 243, 224, 0.82);
|
||||
border: 1px solid rgba(93, 64, 55, 0.12);
|
||||
color: var(--silver);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.pricing-grid {
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
align-items: stretch;
|
||||
@@ -1980,47 +2090,32 @@
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="news-toolbar">
|
||||
<input
|
||||
type="search"
|
||||
id="news-search"
|
||||
class="news-search"
|
||||
placeholder="Search headlines, verticals, and summaries"
|
||||
aria-label="Search blog posts"
|
||||
/>
|
||||
<div class="news-meta">
|
||||
<span class="news-count" id="news-count">Loading posts...</span>
|
||||
<div class="news-pager">
|
||||
<button type="button" class="news-page-btn" id="news-prev">Last Posts</button>
|
||||
<button type="button" class="news-page-btn" id="news-next">Next Posts</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="news-grid"
|
||||
id="news-grid"
|
||||
data-mf-stagger-animation="fade-up"
|
||||
data-mf-stagger-gap="100"
|
||||
data-mf-stagger-duration="650"
|
||||
data-mf-stagger-distance="28"
|
||||
data-mf-stagger-once="true"
|
||||
>
|
||||
<article class="news-card">
|
||||
<div class="news-area">NGO</div>
|
||||
<h3 class="news-title">How a regional NGO cut grant reporting time by 70%</h3>
|
||||
<p class="news-teaser">
|
||||
Donor reconciliation and project cost allocation moved into one
|
||||
workflow, returning 15 hours a week to mission work instead of admin.
|
||||
</p>
|
||||
<span class="news-date">June 2025</span>
|
||||
</article>
|
||||
<article class="news-card">
|
||||
<div class="news-area">Startups</div>
|
||||
<h3 class="news-title">Why investors love clean Odoo data rooms</h3>
|
||||
<p class="news-teaser">
|
||||
Founders shared how structured finance and CRM data reduced scramble during due diligence.
|
||||
</p>
|
||||
<span class="news-date">May 2025</span>
|
||||
</article>
|
||||
<article class="news-card">
|
||||
<div class="news-area">Manufacturing</div>
|
||||
<h3 class="news-title">Real-time BoM costing saved a factory $40k</h3>
|
||||
<p class="news-teaser">
|
||||
Live material cost tracking helped the team reprice before margin loss became irreversible.
|
||||
</p>
|
||||
<span class="news-date">April 2025</span>
|
||||
</article>
|
||||
<article class="news-card">
|
||||
<div class="news-area">Restaurants</div>
|
||||
<h3 class="news-title">Food cost under control before it hit the P&L</h3>
|
||||
<p class="news-teaser">
|
||||
Linking POS data to supplier invoices exposed a 12% creep in week one instead of month three.
|
||||
</p>
|
||||
<span class="news-date">March 2025</span>
|
||||
</article>
|
||||
<div class="news-empty">Loading posts...</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -2356,6 +2451,119 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
var POSTS_URL = "posts.json";
|
||||
var PAGE_SIZE = 8;
|
||||
var grid = document.getElementById("news-grid");
|
||||
var search = document.getElementById("news-search");
|
||||
var prevBtn = document.getElementById("news-prev");
|
||||
var nextBtn = document.getElementById("news-next");
|
||||
var count = document.getElementById("news-count");
|
||||
var allPosts = [];
|
||||
var filteredPosts = [];
|
||||
var currentPage = 0;
|
||||
|
||||
function formatDate(value) {
|
||||
var date = new Date(value);
|
||||
if (isNaN(date.getTime())) return value;
|
||||
return date.toLocaleDateString("en-US", {
|
||||
year: "numeric",
|
||||
month: "long",
|
||||
day: "numeric",
|
||||
});
|
||||
}
|
||||
|
||||
function postMarkup(post) {
|
||||
return [
|
||||
'<a class="news-card" href="' + post.link + '">',
|
||||
'<img class="news-card-image" src="' + post.image + '" alt="' + post.headline.replace(/"/g, """) + '">',
|
||||
'<div class="news-card-body">',
|
||||
'<div>',
|
||||
'<div class="news-area">' + post.vertical + '</div>',
|
||||
'<h3 class="news-title">' + post.headline + '</h3>',
|
||||
'<p class="news-teaser">' + post.shortText + '</p>',
|
||||
'<span class="news-date">' + formatDate(post.date) + '</span>',
|
||||
'</div>',
|
||||
'<span class="news-link">Read article →</span>',
|
||||
'</div>',
|
||||
'</a>',
|
||||
].join("");
|
||||
}
|
||||
|
||||
function emptyMarkup(text) {
|
||||
return '<div class="news-empty">' + text + '</div>';
|
||||
}
|
||||
|
||||
function updateCount() {
|
||||
var total = filteredPosts.length;
|
||||
if (!total) {
|
||||
count.textContent = "0 posts";
|
||||
return;
|
||||
}
|
||||
var start = currentPage * PAGE_SIZE + 1;
|
||||
var end = Math.min(start + PAGE_SIZE - 1, total);
|
||||
count.textContent = start + "-" + end + " of " + total + " posts";
|
||||
}
|
||||
|
||||
function render() {
|
||||
var start = currentPage * PAGE_SIZE;
|
||||
var pagePosts = filteredPosts.slice(start, start + PAGE_SIZE);
|
||||
if (!pagePosts.length) {
|
||||
grid.innerHTML = emptyMarkup("No posts match your search.");
|
||||
} else {
|
||||
grid.innerHTML = pagePosts.map(postMarkup).join("");
|
||||
}
|
||||
prevBtn.disabled = currentPage === 0;
|
||||
nextBtn.disabled = start + PAGE_SIZE >= filteredPosts.length;
|
||||
updateCount();
|
||||
}
|
||||
|
||||
function applyFilter() {
|
||||
var term = (search.value || "").trim().toLowerCase();
|
||||
filteredPosts = allPosts.filter(function (post) {
|
||||
if (!term) return true;
|
||||
var haystack = [post.headline, post.vertical, post.shortText]
|
||||
.join(" ")
|
||||
.toLowerCase();
|
||||
return haystack.indexOf(term) !== -1;
|
||||
});
|
||||
currentPage = 0;
|
||||
render();
|
||||
}
|
||||
|
||||
prevBtn.addEventListener("click", function () {
|
||||
if (currentPage === 0) return;
|
||||
currentPage -= 1;
|
||||
render();
|
||||
});
|
||||
|
||||
nextBtn.addEventListener("click", function () {
|
||||
if ((currentPage + 1) * PAGE_SIZE >= filteredPosts.length) return;
|
||||
currentPage += 1;
|
||||
render();
|
||||
});
|
||||
|
||||
search.addEventListener("input", applyFilter);
|
||||
|
||||
fetch(POSTS_URL)
|
||||
.then(function (response) {
|
||||
return response.json();
|
||||
})
|
||||
.then(function (posts) {
|
||||
allPosts = Array.isArray(posts) ? posts : [];
|
||||
filteredPosts = allPosts.slice();
|
||||
render();
|
||||
})
|
||||
.catch(function () {
|
||||
grid.innerHTML = emptyMarkup("Posts could not be loaded right now.");
|
||||
count.textContent = "Posts unavailable";
|
||||
prevBtn.disabled = true;
|
||||
nextBtn.disabled = true;
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
<script>
|
||||
(function () {
|
||||
"use strict";
|
||||
|
||||
+82
@@ -0,0 +1,82 @@
|
||||
[
|
||||
{
|
||||
"headline": "How a regional NGO cut grant reporting time by 70%",
|
||||
"vertical": "NGO",
|
||||
"date": "2025-06-12",
|
||||
"shortText": "Donor reconciliation and project cost allocation moved into one workflow, returning 15 hours a week to mission work instead of admin.",
|
||||
"image": "https://images.unsplash.com/photo-1559027615-cd4628902d4a?w=900&q=80&auto=format&fit=crop",
|
||||
"link": "https://ngo.my-biz.app"
|
||||
},
|
||||
{
|
||||
"headline": "Why investors love clean Odoo data rooms",
|
||||
"vertical": "Startups",
|
||||
"date": "2025-05-28",
|
||||
"shortText": "Founders shared how structured finance and CRM data reduced scramble during due diligence.",
|
||||
"image": "https://images.unsplash.com/photo-1522202176988-66273c2fd55f?w=900&q=80&auto=format&fit=crop",
|
||||
"link": "https://startups.my-biz.app"
|
||||
},
|
||||
{
|
||||
"headline": "Real-time BoM costing saved a factory $40k",
|
||||
"vertical": "Manufacturing",
|
||||
"date": "2025-04-21",
|
||||
"shortText": "Live material cost tracking helped the team reprice before margin loss became irreversible.",
|
||||
"image": "https://images.unsplash.com/photo-1565793298595-6a879b1d9492?w=900&q=80&auto=format&fit=crop",
|
||||
"link": "https://manufacturing.my-biz.app"
|
||||
},
|
||||
{
|
||||
"headline": "Food cost under control before it hit the P&L",
|
||||
"vertical": "Restaurants",
|
||||
"date": "2025-03-14",
|
||||
"shortText": "Linking POS data to supplier invoices exposed a 12% creep in week one instead of month three.",
|
||||
"image": "https://images.unsplash.com/photo-1414235077428-338989a2e8c0?w=900&q=80&auto=format&fit=crop",
|
||||
"link": "https://restaurants.my-biz.app"
|
||||
},
|
||||
{
|
||||
"headline": "Impact dashboards boards helped trustees decide faster",
|
||||
"vertical": "NGO",
|
||||
"date": "2025-02-10",
|
||||
"shortText": "Program leads and finance teams aligned on one dashboard instead of emailing static reports back and forth.",
|
||||
"image": "https://images.unsplash.com/photo-1519389950473-47ba0277781c?w=900&q=80&auto=format&fit=crop",
|
||||
"link": "https://ngo.my-biz.app"
|
||||
},
|
||||
{
|
||||
"headline": "Startup founders replaced five admin tools with one stack",
|
||||
"vertical": "Startups",
|
||||
"date": "2025-01-24",
|
||||
"shortText": "Sales, invoicing, and project workflows moved into one system and reduced duplicate entry across the team.",
|
||||
"image": "https://images.unsplash.com/photo-1552664730-d307ca884978?w=900&q=80&auto=format&fit=crop",
|
||||
"link": "https://startups.my-biz.app"
|
||||
},
|
||||
{
|
||||
"headline": "Maintenance planning cut line stoppages in week three",
|
||||
"vertical": "Manufacturing",
|
||||
"date": "2024-12-16",
|
||||
"shortText": "Production teams connected maintenance schedules with inventory and planning data before failures became emergencies.",
|
||||
"image": "https://images.unsplash.com/photo-1581092580497-e0d23cbdf1dc?w=900&q=80&auto=format&fit=crop",
|
||||
"link": "https://manufacturing.my-biz.app"
|
||||
},
|
||||
{
|
||||
"headline": "Restaurant groups finally saw payroll and stock in one view",
|
||||
"vertical": "Restaurants",
|
||||
"date": "2024-11-30",
|
||||
"shortText": "Managers connected staffing, purchasing, and daily sales to spot margin leaks earlier each week.",
|
||||
"image": "https://images.unsplash.com/photo-1552566626-52f8b828add9?w=900&q=80&auto=format&fit=crop",
|
||||
"link": "https://restaurants.my-biz.app"
|
||||
},
|
||||
{
|
||||
"headline": "Automation teams improved agent accuracy with structured records",
|
||||
"vertical": "Agentic Businesses",
|
||||
"date": "2024-10-18",
|
||||
"shortText": "AI workflows performed more reliably once customer, ops, and billing data shared the same foundation.",
|
||||
"image": "https://images.unsplash.com/photo-1516321318423-f06f85e504b3?w=900&q=80&auto=format&fit=crop",
|
||||
"link": "https://agentic.my-biz.app"
|
||||
},
|
||||
{
|
||||
"headline": "Cross-border teams chose regional servers without changing workflows",
|
||||
"vertical": "Infrastructure",
|
||||
"date": "2024-09-06",
|
||||
"shortText": "Distributed companies matched server location to their needs while keeping finance, CRM, and operations fully connected.",
|
||||
"image": "https://images.unsplash.com/photo-1460925895917-afdab827c52f?w=900&q=80&auto=format&fit=crop",
|
||||
"link": "#pricing"
|
||||
}
|
||||
]
|
||||
Reference in New Issue
Block a user