Menu
Public repository / 439f0dcabf5cdf2b120c7724be895cf1df30507f
AkurAI-Framework / site/frontend/ai/components/content/linkedin_post.js
Latest change 67a966d4abf972b300e8c6c214a30a0279103337 - feat(ai): Artifacts content components + geo map + item carousel (AB3-C) by Ólafur Búi Ólafsson
/**
* LinkedIn Post — Artifacts / content component.
* Payload: { name: string, headline?: string, text: string, stats?: { likes?: number, comments?: number } }
* Renders a LinkedIn-style post card.
*/
function esc(str) {
return String(str ?? "")
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """);
}
function fmt(n) {
if (n == null) return "0";
if (n >= 1_000) return (n / 1_000).toFixed(1) + "K";
return String(n);
}
function initials(name) {
return (name || "?")
.split(" ")
.slice(0, 2)
.map((w) => w[0] || "")
.join("")
.toUpperCase();
}
export const def = {
name: "linkedin_post",
category: "Artifacts",
title: "LinkedIn Post",
match(payload) {
return (
payload !== null &&
typeof payload === "object" &&
typeof payload.name === "string" &&
typeof payload.text === "string"
);
},
render(payload) {
const { name, headline = "", text, stats = {} } = payload;
const { likes = 0, comments = 0 } = stats;
const card = document.createElement("div");
card.className = "tc-content-lipost";
card.setAttribute("role", "article");
card.setAttribute("aria-label", `LinkedIn post by ${name}`);
card.innerHTML = `
<div class="tc-content-lipost__header">
<div class="tc-content-lipost__avatar" aria-label="${esc(name)}">${esc(initials(name))}</div>
<div class="tc-content-lipost__meta">
<span class="tc-content-lipost__name">${esc(name)}</span>
${headline ? `<span class="tc-content-lipost__headline">${esc(headline)}</span>` : ""}
</div>
<svg class="tc-content-lipost__logo" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" width="20" height="20">
<path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 0 1-2.063-2.065 2.064 2.064 0 1 1 2.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/>
</svg>
</div>
<div class="tc-content-lipost__text">${esc(text)}</div>
<div class="tc-content-lipost__stats">
<span class="tc-content-lipost__stat">
<svg viewBox="0 0 24 24" fill="currentColor" width="16" height="16" aria-hidden="true"><path d="M14.5 12c0 1.38-1.12 2.5-2.5 2.5S9.5 13.38 9.5 12s1.12-2.5 2.5-2.5 2.5 1.12 2.5 2.5z"/><path d="M12 3C7.45 3 3.57 5.68 2 9.5 3.57 13.32 7.45 16 12 16s8.43-2.68 10-6.5C20.43 5.68 16.55 3 12 3zm0 11a4.5 4.5 0 0 1 0-9 4.5 4.5 0 0 1 0 9z"/></svg>
${fmt(likes)} reactions
</span>
<span class="tc-content-lipost__stat">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" width="16" height="16" aria-hidden="true"><path d="M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z"/></svg>
${fmt(comments)} comments
</span>
</div>
`;
return card;
},
example: {
name: "Ólafur Búi Ólafsson",
headline: "Founder at AkurAI · AI solutions for Icelandic businesses",
text: "Excited to announce: AkurAI Framework now ships a native-ESM AI component library — no React, no bundler, zero deps. Just the browser. 🚀\n\nProduction-grade streaming chat UI, generative tool components, and approvals — all from hand-written ES modules.\n\n#AI #OpenSource #Iceland",
stats: { likes: 310, comments: 42 },
},
};