// Projects — SaaS-card grid with featured first
const colorMap = {
violet: { bg: "rgba(124, 92, 255, 0.08)", border: "rgba(124, 92, 255, 0.25)", text: "#a18bff" },
cyan: { bg: "rgba(0, 212, 255, 0.08)", border: "rgba(0, 212, 255, 0.25)", text: "#5ee0ff" },
green: { bg: "rgba(74, 222, 128, 0.08)", border: "rgba(74, 222, 128, 0.25)", text: "#7ee8a3" },
amber: { bg: "rgba(251, 191, 36, 0.08)", border: "rgba(251, 191, 36, 0.25)", text: "#fcd34d" },
};
const PROJ_TXT = {
en: { liveUseCase: "Live Use Case", noRepo: "No repository linked", viewRepo: "View repository" },
bn: { liveUseCase: "লাইভ ব্যবহার দেখুন", noRepo: "রিপোজিটরি যুক্ত নেই", viewRepo: "রিপোজিটরি দেখুন" },
};
const ProjectCard = ({ p, lang = "en" }) => {
const tint = colorMap[p.color] || colorMap.violet;
const [hover, setHover] = React.useState(false);
const t = PROJ_TXT[lang] || PROJ_TXT.en;
const bn = lang === "bn";
return (
setHover(true)}
onMouseLeave={() => setHover(false)}
style={{
position: "relative",
gridColumn: "span 1",
background: "var(--bg-card)",
border: "1px solid var(--line)",
borderRadius: 16,
overflow: "hidden",
cursor: "pointer",
transition: "all 0.25s ease",
transform: hover ? "translateY(-2px)" : "none",
boxShadow: hover ? `0 24px 60px -20px ${tint.border}` : "none",
}}>
{/* hover sheen */}
{/* Decorative top — small visual specific to service type */}
{bn ? p.kindBn : p.kind}
{bn ? p.kindBn : p.kind}
{bn && p.nameBn ? p.nameBn : p.name}
{bn && p.descriptionBn ? p.descriptionBn : p.description}
{/* Stack badges */}
{p.stack.map(s => (
{s}
))}
{/* Footer: impact + actions */}
{p.impact.primary}
{p.impact.secondary}
);
};
// Tiny SVG visual per service — gives each card a distinct "product preview"
const ProjectVisual = ({ id, tint, hover }) => {
if (id === "ai-agent-automation") {
return (
{/* nodes */}
{[
[120, 60], [220, 110], [320, 70], [420, 130], [500, 90],
[180, 160], [280, 180], [380, 50], [460, 180],
].map(([x, y], i) => (
))}
{/* connectors */}
);
}
if (id === "scraping-data-pipeline") {
// bar chart
const bars = [40, 64, 52, 78, 92, 70, 110, 95, 130, 118, 142];
return (
{bars.map((h, i) => (
))}
);
}
if (id === "web3-blockchain") {
// chain dots
const chains = ["ETH","ARB","OP","BASE","SOL","ZK","POL","BNB","AVAX","CELO","XLM","TRX"];
return (
{chains.map((c, i) => (
{c}
))}
);
}
if (id === "mt5-ea-trading") {
// line chart
return (
{[60,180,300,420,540].map((x, i) => (
))}
);
}
if (id === "web-app-dev") {
// schema → grid morph
return (
{/* schema box */}
{[20, 40, 60, 80].map(y => )}
{[20, 40, 60, 80].map(y => )}
{/* arrow */}
{/* dashboard grid */}
);
}
if (id === "infra-devops") {
// chat bubbles
return (
How do I rotate my API key?
Settings → API → Rotate. New key live in <5s.
);
}
return null;
};
// Merge Dashboard API data (demo/repo links) into local static data
// Public API returns: { id, name, demo, repo, position }
function mergeServices(local, apiData) {
const byId = {};
apiData.forEach(s => { byId[s.id] = s; });
return local.map(s => {
const api = byId[s.id];
if (!api) return s;
return {
...s,
demo: api.demo || s.demo || null,
gitRepo: api.repo || null,
};
});
}
const PROJECTS_NUM_WORDS_BN = ['শূন্য','এক','দুই','তিন','চার','পাঁচ','ছয়','সাত','আট','নয়'];
const Projects = ({ lang = "en" }) => {
const D = PORTFOLIO_DATA;
const [services, setServices] = React.useState(D.services);
const bn = lang === "bn";
React.useEffect(() => {
const CACHE_KEY = 'aura_svc_v3';
const CACHE_TTL = 5 * 60 * 1000;
const cached = sessionStorage.getItem(CACHE_KEY);
if (cached) {
try {
const { data, ts } = JSON.parse(cached);
if (Date.now() - ts < CACHE_TTL && data.length > 0) {
setServices(mergeServices(D.services, data));
return;
}
} catch {}
}
fetch('https://aura.auraajenticai.cloud/api/public/services', { signal: AbortSignal.timeout(3000) })
.then(r => r.ok ? r.json() : null)
.then(data => {
if (Array.isArray(data) && data.length > 0) {
sessionStorage.setItem(CACHE_KEY, JSON.stringify({ data, ts: Date.now() }));
setServices(mergeServices(D.services, data));
}
})
.catch(() => {});
}, []);
return (
{PROJECTS_NUM_WORDS_BN[services.length] || services.length}টা সার্ভিস। একটাই টিম। সব প্রোডাকশন-গ্রেড ।>
: <>{['Zero','One','Two','Three','Four','Five','Six','Seven','Eight','Nine'][services.length] || services.length} service{services.length !== 1 ? 's' : ''}. One team. All production-grade .>}
sub={bn
? "ল্যান্ডিং পেজ থেকে এআই এজেন্ট রানটাইম পর্যন্ত — আমরা আপনার আইডিয়া spec থেকে লাইভ ডিপ্লয়মেন্টে নিয়ে যাই।"
: "From landing pages to AI agent runtimes — we take your idea from spec to live deployment."}
/>
);
};
window.Projects = Projects;