This commit is contained in:
despiegk 2025-08-03 08:06:30 +02:00
parent 51900b05bf
commit 86867b2d5a
14 changed files with 1458 additions and 208 deletions

View File

@ -38,12 +38,14 @@
"@radix-ui/react-toggle-group": "^1.1.9",
"@radix-ui/react-tooltip": "^1.2.6",
"@tailwindcss/vite": "^4.1.7",
"buffer": "^6.0.3",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"cmdk": "^1.1.1",
"date-fns": "^4.1.0",
"embla-carousel-react": "^8.6.0",
"framer-motion": "^12.15.0",
"gray-matter": "^4.0.3",
"input-otp": "^1.4.2",
"lucide-react": "^0.510.0",
"next-themes": "^0.4.6",
@ -51,9 +53,11 @@
"react-day-picker": "8.10.1",
"react-dom": "^19.1.0",
"react-hook-form": "^7.56.3",
"react-markdown": "^10.1.0",
"react-resizable-panels": "^3.0.2",
"react-router-dom": "^7.6.1",
"recharts": "^2.15.3",
"remark-gfm": "^4.0.1",
"sonner": "^2.0.3",
"tailwind-merge": "^3.3.0",
"tailwindcss": "^4.1.7",

File diff suppressed because it is too large Load Diff

View File

@ -6,6 +6,7 @@ import How from './pages/How';
import GetStarted from './pages/GetStarted';
import Technology from './pages/Technology';
import Blog from './pages/Blog';
import BlogPost from './pages/BlogPost';
import './App.css';
function App() {
@ -20,6 +21,7 @@ function App() {
<Route path="/get-started" element={<GetStarted />} />
<Route path="/technology" element={<Technology />} />
<Route path="/blog" element={<Blog />} />
<Route path="/blog/:slug" element={<BlogPost />} />
</Routes>
</main>
</div>

View File

@ -0,0 +1,14 @@
---
title: "AI That Serves You: The Personal Agent Revolution"
author: "HERO Team"
date: "December 8, 2024"
readTime: "7 min read"
tags: ["AI", "Personal Agents", "Technology"]
image: "/src/assets/heart.jpg"
featured: false
draft: false
---
Unlike corporate AI that serves shareholders, Personal Agents work exclusively for you. Learn how this changes everything about AI interaction.
This is placeholder content for the full article.

View File

@ -0,0 +1,14 @@
---
title: "Building Trust in a Zero-Knowledge World"
author: "Dr. Sarah Chen"
date: "December 12, 2024"
readTime: "6 min read"
tags: ["Cryptography", "Zero-Knowledge", "Security"]
image: "/src/assets/balls.jpg"
featured: false
draft: false
---
How HERO's zero-knowledge architecture enables trust without compromising privacy. A deep dive into the cryptographic foundations of digital sovereignty.
This is placeholder content for the full article.

View File

@ -0,0 +1,14 @@
---
title: "From Centralized to Sovereign: The Evolution of Digital Identity"
author: "Alex Rodriguez"
date: "December 10, 2024"
readTime: "5 min read"
tags: ["Identity", "Blockchain", "Sovereignty"]
image: "/src/assets/white_keyb.jpg"
featured: false
draft: false
---
Tracing the journey from corporate-controlled identities to blockchain-verified, user-owned digital personas. The future is sovereign.
This is placeholder content for the full article.

View File

@ -0,0 +1,14 @@
---
title: "Peer-to-Peer Communication: Cutting Out the Middleman"
author: "HERO Team"
date: "December 1, 2024"
readTime: "6 min read"
tags: ["Communication", "P2P", "Privacy"]
image: "/src/assets/heart.jpg"
featured: false
draft: false
---
How HERO enables direct communication between Personal Agents without corporate intermediaries. The future of private messaging is here.
This is placeholder content for the full article.

View File

@ -0,0 +1,14 @@
---
title: "Quantum-Safe Storage: Protecting Your Digital Legacy"
author: "Dr. Michael Park"
date: "December 5, 2024"
readTime: "9 min read"
tags: ["Quantum Computing", "Storage", "Security"]
image: "/src/assets/balls.jpg"
featured: false
draft: false
---
As quantum computing threatens traditional encryption, HERO's quantum-safe storage ensures your data remains secure for generations.
This is placeholder content for the full article.

View File

@ -0,0 +1,14 @@
---
title: "The Economics of Digital Sovereignty"
author: "Emma Thompson"
date: "December 3, 2024"
readTime: "4 min read"
tags: ["Economics", "Privacy", "Value"]
image: "/src/assets/white_keyb.jpg"
featured: false
draft: false
---
Why paying $20/month for digital freedom is the best investment you'll ever make. Breaking down the true cost of corporate data harvesting.
This is placeholder content for the full article.

View File

@ -0,0 +1,14 @@
---
title: "The Future of Digital Sovereignty: Why Personal Agents Matter"
author: "HERO Team"
date: "December 15, 2024"
readTime: "8 min read"
tags: ["Digital Sovereignty", "Privacy", "AI"]
image: "/src/assets/heart.jpg"
featured: true
draft: false
---
In an era where tech giants control our digital lives, Personal Agents represent a fundamental shift toward individual sovereignty and privacy. Discover how HERO is leading this revolution.
This is placeholder content for the full article.

View File

@ -2,6 +2,8 @@ import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import './index.css'
import App from './App'
import { Buffer } from 'buffer';
window.Buffer = Buffer;
createRoot(document.getElementById('root')).render(
<StrictMode>

View File

@ -1,83 +1,111 @@
import React from 'react';
import React, { useEffect, useState } from 'react';
import { motion } from 'framer-motion';
import { Link } from 'react-router-dom';
import { Calendar, User, ArrowRight, Tag } from 'lucide-react';
import HeroSection from '../components/HeroSection';
import Section from '../components/Section';
import { Button } from '@/components/ui/button';
import matter from 'gray-matter'; // Import gray-matter
import { Buffer } from 'buffer'; // Explicitly import Buffer
// Import images
import blogBackground from '../assets/myhero.jpg'; // HERO background with panning effect
import post1Image from '../assets/heart.jpg'; // Emotional tech
import post2Image from '../assets/balls.jpg'; // AI Agent creation
import post3Image from '../assets/white_keyb.jpg'; // Digital privacy
import blogBackground from '../assets/myhero.jpg';
// Use Vite's import.meta.glob to import all markdown files
const modules = import.meta.glob('../blogs/*.md', { as: 'raw', eager: true });
const Blog = () => {
const featuredPost = {
title: "The Future of Digital Sovereignty: Why Personal Agents Matter",
excerpt: "In an era where tech giants control our digital lives, Personal Agents represent a fundamental shift toward individual sovereignty and privacy. Discover how HERO is leading this revolution.",
author: "HERO Team",
date: "December 15, 2024",
readTime: "8 min read",
image: post1Image,
tags: ["Digital Sovereignty", "Privacy", "AI"]
};
const [posts, setPosts] = useState([]);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const blogPosts = [
{
title: "Building Trust in a Zero-Knowledge World",
excerpt: "How HERO's zero-knowledge architecture enables trust without compromising privacy. A deep dive into the cryptographic foundations of digital sovereignty.",
author: "Dr. Sarah Chen",
date: "December 12, 2024",
readTime: "6 min read",
image: post2Image,
tags: ["Cryptography", "Zero-Knowledge", "Security"]
},
{
title: "From Centralized to Sovereign: The Evolution of Digital Identity",
excerpt: "Tracing the journey from corporate-controlled identities to blockchain-verified, user-owned digital personas. The future is sovereign.",
author: "Alex Rodriguez",
date: "December 10, 2024",
readTime: "5 min read",
image: post3Image,
tags: ["Identity", "Blockchain", "Sovereignty"]
},
{
title: "AI That Serves You: The Personal Agent Revolution",
excerpt: "Unlike corporate AI that serves shareholders, Personal Agents work exclusively for you. Learn how this changes everything about AI interaction.",
author: "HERO Team",
date: "December 8, 2024",
readTime: "7 min read",
image: post1Image,
tags: ["AI", "Personal Agents", "Technology"]
},
{
title: "Quantum-Safe Storage: Protecting Your Digital Legacy",
excerpt: "As quantum computing threatens traditional encryption, HERO's quantum-safe storage ensures your data remains secure for generations.",
author: "Dr. Michael Park",
date: "December 5, 2024",
readTime: "9 min read",
image: post2Image,
tags: ["Quantum Computing", "Storage", "Security"]
},
{
title: "The Economics of Digital Sovereignty",
excerpt: "Why paying $20/month for digital freedom is the best investment you'll ever make. Breaking down the true cost of corporate data harvesting.",
author: "Emma Thompson",
date: "December 3, 2024",
readTime: "4 min read",
image: post3Image,
tags: ["Economics", "Privacy", "Value"]
},
{
title: "Peer-to-Peer Communication: Cutting Out the Middleman",
excerpt: "How HERO enables direct communication between Personal Agents without corporate intermediaries. The future of private messaging is here.",
author: "HERO Team",
date: "December 1, 2024",
readTime: "6 min read",
image: post1Image,
tags: ["Communication", "P2P", "Privacy"]
}
];
useEffect(() => {
const loadPosts = async () => {
try {
const loadedPosts = [];
for (const path in modules) {
const content = modules[path];
const { data: frontmatter } = matter(content);
// Extract slug from filename
const slug = path.split('/').pop().replace('.md', '');
// Only include posts that are not drafts
if (frontmatter.draft !== true) {
loadedPosts.push({
...frontmatter,
slug,
// Ensure image path is correct for Vite
image: frontmatter.image ? new URL(frontmatter.image, import.meta.url).href : '/src/assets/default.jpg'
});
}
}
setPosts(loadedPosts);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};
loadPosts();
}, []);
// Handle cases where posts might still be loading or empty
if (loading) {
return (
<div className="min-h-screen">
<HeroSection
subtitle="Insights & Updates"
title="HERO Blog"
description="Loading blog posts..."
backgroundImage={blogBackground}
ctaText="Subscribe to Updates"
ctaLink="#subscribe"
showVideo={false}
/>
</div>
);
}
if (error) {
return (
<div className="min-h-screen">
<HeroSection
subtitle="Insights & Updates"
title="HERO Blog"
description={`Error: ${error}`}
backgroundImage={blogBackground}
ctaText="Subscribe to Updates"
ctaLink="#subscribe"
showVideo={false}
/>
</div>
);
}
// Ensure posts array is not empty before accessing elements
const featuredPost = posts.find(post => post.featured === true);
const blogPosts = posts.filter(post => post.slug !== featuredPost?.slug);
// If no featured post is found, and there are other posts, pick the first one
const displayFeaturedPost = featuredPost || (posts.length > 0 ? posts[0] : null);
if (!displayFeaturedPost && posts.length === 0) {
return (
<div className="min-h-screen">
<HeroSection
subtitle="Insights & Updates"
title="HERO Blog"
description="No blog posts found."
backgroundImage={blogBackground}
ctaText="Subscribe to Updates"
ctaLink="#subscribe"
showVideo={false}
/>
</div>
);
}
const categories = [
"All Posts",
@ -112,75 +140,79 @@ const Blog = () => {
</div>
{/* Featured Post Section */}
<Section background="gradient" padding="xlarge">
<div className="text-center mb-16">
<motion.h2
className="text-4xl md:text-5xl font-bold text-white mb-6"
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6 }}
viewport={{ once: true }}
>
Featured <span className="text-blue-400">Article</span>
</motion.h2>
</div>
<motion.article
initial={{ opacity: 0, y: 30 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8 }}
viewport={{ once: true }}
className="max-w-4xl mx-auto glass-effect rounded-2xl overflow-hidden hover:border-blue-400/30 transition-all duration-300 hover-lift"
>
<div className="md:flex">
<div className="md:w-1/2">
<img
src={featuredPost.image}
alt={featuredPost.title}
className="w-full h-64 md:h-full object-cover"
/>
</div>
<div className="md:w-1/2 p-8">
<div className="flex flex-wrap gap-2 mb-4">
{featuredPost.tags.map((tag, index) => (
<span
key={index}
className="px-3 py-1 bg-blue-600/20 text-blue-400 text-sm rounded-full"
>
{tag}
</span>
))}
</div>
<h3 className="text-2xl md:text-3xl font-bold text-white mb-4 leading-tight">
{featuredPost.title}
</h3>
<p className="text-gray-300 mb-6 leading-relaxed">
{featuredPost.excerpt}
</p>
<div className="flex items-center justify-between text-sm text-gray-400 mb-6">
<div className="flex items-center space-x-4">
<div className="flex items-center space-x-2">
<User size={16} />
<span>{featuredPost.author}</span>
</div>
<div className="flex items-center space-x-2">
<Calendar size={16} />
<span>{featuredPost.date}</span>
</div>
</div>
<span>{featuredPost.readTime}</span>
</div>
<Button className="bg-blue-600 hover:bg-blue-700 text-white">
Read Full Article <ArrowRight size={16} className="ml-2" />
</Button>
</div>
{displayFeaturedPost && (
<Section background="gradient" padding="xlarge">
<div className="text-center mb-16">
<motion.h2
className="text-4xl md:text-5xl font-bold text-white mb-6"
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6 }}
viewport={{ once: true }}
>
Featured <span className="text-blue-400">Article</span>
</motion.h2>
</div>
</motion.article>
</Section>
<Link to={`/blog/${displayFeaturedPost.slug}`} className="block">
<motion.article
initial={{ opacity: 0, y: 30 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8 }}
viewport={{ once: true }}
className="max-w-4xl mx-auto glass-effect rounded-2xl overflow-hidden hover:border-blue-400/30 transition-all duration-300 hover-lift"
>
<div className="md:flex">
<div className="md:w-1/2">
<img
src={displayFeaturedPost.image}
alt={displayFeaturedPost.title}
className="w-full h-64 md:h-full object-cover"
/>
</div>
<div className="md:w-1/2 p-8">
<div className="flex flex-wrap gap-2 mb-4">
{displayFeaturedPost.tags?.map((tag, index) => (
<span
key={index}
className="px-3 py-1 bg-blue-600/20 text-blue-400 text-sm rounded-full"
>
{tag}
</span>
))}
</div>
<h3 className="text-2xl md:text-3xl font-bold text-white mb-4 leading-tight">
{displayFeaturedPost.title}
</h3>
<p className="text-gray-300 mb-6 leading-relaxed">
{displayFeaturedPost.excerpt}
</p>
<div className="flex items-center justify-between text-sm text-gray-400 mb-6">
<div className="flex items-center space-x-4">
<div className="flex items-center space-x-2">
<User size={16} />
<span>{displayFeaturedPost.author}</span>
</div>
<div className="flex items-center space-x-2">
<Calendar size={16} />
<span>{displayFeaturedPost.date}</span>
</div>
</div>
<span>{displayFeaturedPost.readTime}</span>
</div>
<span className="inline-flex items-center text-blue-400 hover:text-blue-300 transition-colors duration-300 font-semibold cursor-pointer">
Read Full Article <ArrowRight size={16} className="ml-2" />
</span>
</div>
</div>
</motion.article>
</Link>
</Section>
)}
{/* Blog Posts Grid */}
<Section background="dark" padding="xlarge">
@ -205,10 +237,10 @@ const Blog = () => {
>
{categories.map((category, index) => (
<button
key={index}
key={category}
className={`px-4 py-2 rounded-full text-sm font-medium transition-all duration-300 ${
index === 0
? 'bg-purple-600 text-white'
index === 0
? 'bg-purple-600 text-white'
: 'bg-gray-800 text-gray-300 hover:bg-gray-700 hover:text-white'
}`}
>
@ -220,58 +252,60 @@ const Blog = () => {
<div className="grid md:grid-cols-2 lg:grid-cols-3 gap-8">
{blogPosts.map((post, index) => (
<motion.article
key={index}
initial={{ opacity: 0, y: 30 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, delay: index * 0.1 }}
viewport={{ once: true }}
className="glass-effect rounded-xl overflow-hidden hover:border-purple-400/30 transition-all duration-300 hover-lift group"
>
<div className="relative overflow-hidden">
<img
src={post.image}
alt={post.title}
className="w-full h-48 object-cover group-hover:scale-105 transition-transform duration-300"
/>
<div className="absolute inset-0"></div>
</div>
<div className="p-6">
<div className="flex flex-wrap gap-2 mb-3">
{post.tags.slice(0, 2).map((tag, tagIndex) => (
<span
key={tagIndex}
className="px-2 py-1 bg-purple-600/20 text-purple-400 text-xs rounded-full"
>
{tag}
</span>
))}
<Link to={`/blog/${post.slug}`} className="block">
<motion.article
key={index}
initial={{ opacity: 0, y: 30 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6, delay: index * 0.1 }}
viewport={{ once: true }}
className="glass-effect rounded-xl overflow-hidden hover:border-purple-400/30 transition-all duration-300 hover-lift group"
>
<div className="relative overflow-hidden">
<img
src={post.image}
alt={post.title}
className="w-full h-48 object-cover group-hover:scale-105 transition-transform duration-300"
/>
<div className="absolute inset-0"></div>
</div>
<h3 className="text-xl font-semibold text-white mb-3 leading-tight group-hover:text-purple-100 transition-colors duration-300">
{post.title}
</h3>
<p className="text-gray-300 text-sm mb-4 leading-relaxed">
{post.excerpt}
</p>
<div className="flex items-center justify-between text-xs text-gray-400">
<div className="flex items-center space-x-3">
<div className="flex items-center space-x-1">
<User size={12} />
<span>{post.author}</span>
</div>
<div className="flex items-center space-x-1">
<Calendar size={12} />
<span>{post.date}</span>
</div>
<div className="p-6">
<div className="flex flex-wrap gap-2 mb-3">
{post.tags.slice(0, 2).map((tag) => (
<span
key={tag}
className="px-2 py-1 bg-purple-600/20 text-purple-400 text-xs rounded-full"
>
{tag}
</span>
))}
</div>
<h3 className="text-xl font-semibold text-white mb-3 leading-tight group-hover:text-purple-100 transition-colors duration-300">
{post.title}
</h3>
<p className="text-gray-300 text-sm mb-4 leading-relaxed">
{post.excerpt}
</p>
<div className="flex items-center justify-between text-xs text-gray-400">
<div className="flex items-center space-x-3">
<div className="flex items-center space-x-1">
<User size={12} />
<span>{post.author}</span>
</div>
<div className="flex items-center space-x-1">
<Calendar size={12} />
<span>{post.date}</span>
</div>
</div>
<span>{post.readTime}</span>
</div>
<span>{post.readTime}</span>
</div>
</div>
</motion.article>
</motion.article>
</Link>
))}
</div>
</Section>

151
src/pages/BlogPost.jsx Normal file
View File

@ -0,0 +1,151 @@
import React, { useEffect, useState } from 'react';
import { useParams, Link } from 'react-router-dom';
import ReactMarkdown from 'react-markdown';
import remarkGfm from 'remark-gfm';
import matter from 'gray-matter';
import { ArrowLeft, Calendar, User, Tag } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Buffer } from 'buffer'; // Explicitly import Buffer
const BlogPost = () => {
const { slug } = useParams();
const [post, setPost] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
const loadPost = async () => {
try {
const response = await fetch(`/src/blogs/${slug}.md`);
if (!response.ok) {
throw new Error('Post not found');
}
const content = await response.text();
const { data: frontmatter, content: markdownContent } = matter(content);
setPost({
frontmatter,
content: markdownContent
});
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};
loadPost();
}, [slug]);
if (loading) {
return (
<div className="min-h-screen bg-gray-900 flex items-center justify-center">
<div className="text-white text-xl">Loading...</div>
</div>
);
}
if (error) {
return (
<div className="min-h-screen bg-gray-900 flex items-center justify-center">
<div className="text-white text-xl">Error: {error}</div>
</div>
);
}
return (
<div className="min-h-screen bg-gray-900">
<div className="container mx-auto px-4 py-8 max-w-4xl">
<Link to="/blog">
<Button className="mb-8 bg-gray-800 hover:bg-gray-700 text-white">
<ArrowLeft className="mr-2 h-4 w-4" />
Back to Blog
</Button>
</Link>
{post.frontmatter.image && (
<div className="mb-8">
<img
src={post.frontmatter.image}
alt={post.frontmatter.title}
className="w-full h-64 md:h-96 object-cover rounded-lg"
/>
</div>
)}
<article className="bg-gray-800 rounded-lg p-8">
<div className="mb-6">
<h1 className="text-4xl font-bold text-white mb-4">
{post.frontmatter.title}
</h1>
<div className="flex items-center space-x-4 text-gray-400 mb-4">
<div className="flex items-center space-x-2">
<User size={16} />
<span>{post.frontmatter.author}</span>
</div>
<div className="flex items-center space-x-2">
<Calendar size={16} />
<span>{post.frontmatter.date}</span>
</div>
<span>{post.frontmatter.readTime}</span>
</div>
<div className="flex flex-wrap gap-2">
{post.frontmatter.tags?.map((tag, index) => (
<span
key={index}
className="px-3 py-1 bg-blue-600/20 text-blue-400 text-sm rounded-full"
>
<Tag className="inline-block mr-1 h-3 w-3" />
{tag}
</span>
))}
</div>
</div>
<div className="prose prose-invert prose-lg max-w-none">
<ReactMarkdown
remarkPlugins={[remarkGfm]}
components={{
h1: ({node, ...props}) => <h1 className="text-3xl font-bold text-white mb-4" {...props} />,
h2: ({node, ...props}) => <h2 className="text-2xl font-semibold text-white mb-3 mt-6" {...props} />,
h3: ({node, ...props}) => <h3 className="text-xl font-semibold text-white mb-2 mt-4" {...props} />,
p: ({node, ...props}) => <p className="text-gray-300 leading-relaxed mb-4" {...props} />,
ul: ({node, ...props}) => <ul className="text-gray-300 list-disc list-inside mb-4" {...props} />,
ol: ({node, ...props}) => <ol className="text-gray-300 list-decimal list-inside mb-4" {...props} />,
li: ({node, ...props}) => <li className="text-gray-300 mb-1" {...props} />,
blockquote: ({node, ...props}) => (
<blockquote
className="border-l-4 border-blue-500 pl-4 italic text-gray-400 mb-4"
{...props}
/>
),
code: ({node, inline, ...props}) => (
<code
className={`${
inline
? 'bg-gray-700 px-1 py-0.5 rounded text-sm'
: 'block bg-gray-700 p-4 rounded text-sm overflow-x-auto'
}`}
{...props}
/>
),
a: ({node, ...props}) => (
<a
className="text-blue-400 hover:text-blue-300 underline"
{...props}
/>
),
}}
>
{post.content}
</ReactMarkdown>
</div>
</article>
</div>
</div>
);
};
export default BlogPost;

View File

@ -6,9 +6,15 @@ import path from 'path'
// https://vite.dev/config/
export default defineConfig({
plugins: [react(),tailwindcss()],
define: {
global: 'window',
'process.env': {}, // Define process.env as an empty object
},
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"),
// Alias 'buffer' to 'buffer/index.js' for browser compatibility
'buffer': 'buffer/index.js',
},
},
})