add people n heor

This commit is contained in:
sasha-astiadi 2025-08-06 13:00:32 +02:00
parent 49a385d366
commit 06b0e11a8f
19 changed files with 558 additions and 182 deletions

View File

@ -27,7 +27,7 @@ const biography = `
John is a passionate software engineer with expertise in modern web technologies.
He specializes in building scalable applications and has a keen interest in user experience design.
</p>
<p class="mt-5">
<p class="mt-5 text-lg/7">
With over 5 years of experience in the tech industry, John has worked on various projects
ranging from startups to enterprise applications. He believes in writing clean, maintainable code
and is always eager to learn new technologies.

134
docs/gmail-setup-guide.md Normal file
View File

@ -0,0 +1,134 @@
# Gmail Contact Form Setup Guide
This guide will help you configure your contact form to send emails to your company Gmail inbox.
## Prerequisites
- A Gmail account for your company
- Access to Google Account settings
- Basic understanding of environment variables
## Step 1: Enable 2-Factor Authentication
1. Go to [Google Account Settings](https://myaccount.google.com/)
2. Navigate to **Security** → **2-Step Verification**
3. Follow the prompts to enable 2FA if not already enabled
4. **Note**: App passwords require 2FA to be enabled
## Step 2: Generate Gmail App Password
1. Go to [Google Account Settings](https://myaccount.google.com/)
2. Navigate to **Security****2-Step Verification** → **App passwords**
3. Select **Mail** as the app and **Other** as the device
4. Enter "OurWorld Contact Form" as the device name
5. Click **Generate**
6. **Important**: Copy the 16-character app password immediately (you won't see it again)
## Step 3: Configure Environment Variables
1. Open the `.env.local` file in your project root
2. Replace the placeholder values with your actual credentials:
```env
# Your Gmail address (the one that will send emails)
GMAIL_USER=your-company-email@gmail.com
# The 16-character app password you generated (no spaces)
GMAIL_APP_PASSWORD=abcdabcdabcdabcd
# Email address where contact form submissions will be sent
COMPANY_EMAIL=info@ourworld.tf
```
## Step 4: Security Considerations
### Environment Variables
- **Never commit `.env.local` to version control**
- The `.env.local` file is already in `.gitignore`
- Use different environment variables for production deployment
### Production Deployment
For production (Vercel, Netlify, etc.), add these environment variables in your hosting platform's dashboard:
- `GMAIL_USER`
- `GMAIL_APP_PASSWORD`
- `COMPANY_EMAIL`
## Step 5: Testing the Setup
1. Start your development server:
```bash
npm run dev
```
2. Navigate to `/contact` page
3. Fill out and submit the contact form
4. Check your Gmail inbox for the contact form submission
## Troubleshooting
### Common Issues
**"Authentication failed" error:**
- Verify 2FA is enabled on your Google account
- Double-check the app password (no spaces, 16 characters)
- Ensure you're using the app password, not your regular Gmail password
**"Invalid credentials" error:**
- Verify the `GMAIL_USER` email address is correct
- Check that the app password is correctly copied
**Emails not being received:**
- Check your spam/junk folder
- Verify the `COMPANY_EMAIL` address is correct
- Test with a different recipient email
**"Module not found" error:**
- Ensure nodemailer is installed: `npm install nodemailer @types/nodemailer`
### Email Format
The contact form sends emails with:
- **Subject**: "New Contact Form Submission from [First Name] [Last Name]"
- **From**: Your Gmail address (GMAIL_USER)
- **To**: Company email address (COMPANY_EMAIL)
- **Content**: Formatted HTML and plain text versions
## Security Best Practices
1. **Use App Passwords**: Never use your main Gmail password
2. **Limit Access**: Only share credentials with necessary team members
3. **Regular Rotation**: Consider rotating app passwords periodically
4. **Monitor Usage**: Check Gmail's security activity regularly
5. **Environment Separation**: Use different credentials for development/production
## Alternative Solutions
If you prefer not to use Gmail directly, consider these alternatives:
1. **EmailJS**: Client-side email service
2. **Formspree**: Form handling service
3. **SendGrid**: Professional email API
4. **Mailgun**: Email delivery service
5. **Resend**: Modern email API
## Support
If you encounter issues:
1. Check the browser console for error messages
2. Review the server logs for API errors
3. Verify all environment variables are set correctly
4. Test with a simple email first
## File Structure
```
project/
├── .env.local # Environment variables (not in git)
├── src/app/api/contact/ # API route for form submission
├── src/components/ContactHero.tsx # Contact form component
└── docs/gmail-setup-guide.md # This guide
```
---
**Important**: Keep your app password secure and never share it publicly. If compromised, revoke it immediately in your Google Account settings and generate a new one.

View File

@ -1,4 +1,13 @@
/** @type {import('next').NextConfig} */
const nextConfig = {}
const nextConfig = {
output: 'export',
trailingSlash: true,
images: {
unoptimized: true,
},
// Note: API routes in src/app/api/ will not work with static export
// The contact form API route will need to be handled separately
// Consider using a serverless function or external service for form handling
};
module.exports = nextConfig
module.exports = nextConfig;

20
package-lock.json generated
View File

@ -13,10 +13,12 @@
"@tailwindcss/forms": "^0.5.3",
"@tailwindcss/postcss": "^4.1.7",
"@types/node": "^20.10.8",
"@types/nodemailer": "^6.4.17",
"@types/react": "^18.2.47",
"@types/react-dom": "^18.2.18",
"clsx": "^2.1.0",
"next": "^14.0.4",
"nodemailer": "^7.0.5",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"tailwindcss": "^4.1.7",
@ -1350,6 +1352,15 @@
"undici-types": "~5.26.4"
}
},
"node_modules/@types/nodemailer": {
"version": "6.4.17",
"resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-6.4.17.tgz",
"integrity": "sha512-I9CCaIp6DTldEg7vyUTZi8+9Vo0hi1/T8gv3C89yk1rSAAzoKQ8H8ki/jBYJSFoH/BisgLP8tkZMlQ91CIquww==",
"license": "MIT",
"dependencies": {
"@types/node": "*"
}
},
"node_modules/@types/prop-types": {
"version": "15.7.11",
"resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.11.tgz",
@ -3994,6 +4005,15 @@
"node": "^10 || ^12 || >=14"
}
},
"node_modules/nodemailer": {
"version": "7.0.5",
"resolved": "https://registry.npmjs.org/nodemailer/-/nodemailer-7.0.5.tgz",
"integrity": "sha512-nsrh2lO3j4GkLLXoeEksAMgAOqxOv6QumNRVQTJwKH4nuiww6iC2y7GyANs9kRAxCexg3+lTWM3PZ91iLlVjfg==",
"license": "MIT-0",
"engines": {
"node": ">=6.0.0"
}
},
"node_modules/object-assign": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",

View File

@ -17,10 +17,12 @@
"@tailwindcss/forms": "^0.5.3",
"@tailwindcss/postcss": "^4.1.7",
"@types/node": "^20.10.8",
"@types/nodemailer": "^6.4.17",
"@types/react": "^18.2.47",
"@types/react-dom": "^18.2.18",
"clsx": "^2.1.0",
"next": "^14.0.4",
"nodemailer": "^7.0.5",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"tailwindcss": "^4.1.7",

View File

@ -0,0 +1,80 @@
import { NextRequest, NextResponse } from 'next/server'
import nodemailer from 'nodemailer'
export async function POST(request: NextRequest) {
try {
const body = await request.json()
const { firstName, lastName, email, phoneNumber, message } = body
// Validate required fields
if (!firstName || !lastName || !email || !message) {
return NextResponse.json(
{ error: 'Missing required fields' },
{ status: 400 }
)
}
// Create transporter using Gmail SMTP
const transporter = nodemailer.createTransport({
service: 'gmail',
auth: {
user: process.env.GMAIL_USER,
pass: process.env.GMAIL_APP_PASSWORD,
},
})
// Email content
const mailOptions = {
from: process.env.GMAIL_USER,
to: process.env.COMPANY_EMAIL || process.env.GMAIL_USER,
subject: `New Contact Form Submission from ${firstName} ${lastName}`,
html: `
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;">
<h2 style="color: #4f46e5;">New Contact Form Submission</h2>
<div style="background-color: #f8fafc; padding: 20px; border-radius: 8px; margin: 20px 0;">
<h3 style="margin-top: 0; color: #374151;">Contact Information</h3>
<p><strong>Name:</strong> ${firstName} ${lastName}</p>
<p><strong>Email:</strong> <a href="mailto:${email}">${email}</a></p>
${phoneNumber ? `<p><strong>Phone:</strong> ${phoneNumber}</p>` : ''}
</div>
<div style="background-color: #f8fafc; padding: 20px; border-radius: 8px; margin: 20px 0;">
<h3 style="margin-top: 0; color: #374151;">Message</h3>
<p style="white-space: pre-wrap;">${message}</p>
</div>
<div style="margin-top: 30px; padding-top: 20px; border-top: 1px solid #e5e7eb; color: #6b7280; font-size: 14px;">
<p>This email was sent from the OurWorld contact form on ${new Date().toLocaleString()}.</p>
</div>
</div>
`,
text: `
New Contact Form Submission
Name: ${firstName} ${lastName}
Email: ${email}
${phoneNumber ? `Phone: ${phoneNumber}` : ''}
Message:
${message}
Sent on: ${new Date().toLocaleString()}
`,
}
// Send email
await transporter.sendMail(mailOptions)
return NextResponse.json(
{ message: 'Email sent successfully' },
{ status: 200 }
)
} catch (error) {
console.error('Error sending email:', error)
return NextResponse.json(
{ error: 'Failed to send email' },
{ status: 500 }
)
}
}

View File

@ -1,6 +1,60 @@
'use client'
import { BuildingOffice2Icon, EnvelopeIcon, PhoneIcon } from '@heroicons/react/24/outline'
import { useState } from 'react'
export function ContactHero() {
const [formData, setFormData] = useState({
firstName: '',
lastName: '',
email: '',
phoneNumber: '',
message: ''
})
const [isSubmitting, setIsSubmitting] = useState(false)
const [submitStatus, setSubmitStatus] = useState<'idle' | 'success' | 'error'>('idle')
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
const { name, value } = e.target
setFormData(prev => ({
...prev,
[name]: value
}))
}
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault()
setIsSubmitting(true)
setSubmitStatus('idle')
try {
const response = await fetch('/api/contact', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(formData),
})
if (response.ok) {
setSubmitStatus('success')
setFormData({
firstName: '',
lastName: '',
email: '',
phoneNumber: '',
message: ''
})
} else {
setSubmitStatus('error')
}
} catch (error) {
console.error('Error submitting form:', error)
setSubmitStatus('error')
} finally {
setIsSubmitting(false)
}
}
return (
<div className="relative isolate bg-white">
<div className="mx-auto grid max-w-7xl grid-cols-1 lg:grid-cols-2">
@ -74,76 +128,105 @@ export function ContactHero() {
</dl>
</div>
</div>
<form action="#" method="POST" className="px-6 pt-20 pb-24 sm:pb-32 lg:px-8 lg:py-48">
<form onSubmit={handleSubmit} className="px-6 pt-20 pb-24 sm:pb-32 lg:px-8 lg:py-48">
<div className="mx-auto max-w-xl lg:mr-0 lg:max-w-lg">
{/* Status Messages */}
{submitStatus === 'success' && (
<div className="mb-6 rounded-md bg-green-50 p-4">
<div className="text-sm text-green-800">
Thank you! Your message has been sent successfully. We'll get back to you soon.
</div>
</div>
)}
{submitStatus === 'error' && (
<div className="mb-6 rounded-md bg-red-50 p-4">
<div className="text-sm text-red-800">
Sorry, there was an error sending your message. Please try again or contact us directly.
</div>
</div>
)}
<div className="grid grid-cols-1 gap-x-8 gap-y-6 sm:grid-cols-2">
<div>
<label htmlFor="first-name" className="block text-sm/6 font-semibold text-gray-900">
First name
<label htmlFor="firstName" className="block text-sm/6 font-semibold text-gray-900">
First name *
</label>
<div className="mt-2.5">
<input
id="first-name"
name="first-name"
id="firstName"
name="firstName"
type="text"
required
autoComplete="given-name"
value={formData.firstName}
onChange={handleInputChange}
className="block w-full rounded-md bg-white px-3.5 py-2 text-base text-gray-900 outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline-2 focus:-outline-offset-2 focus:outline-indigo-600"
/>
</div>
</div>
<div>
<label htmlFor="last-name" className="block text-sm/6 font-semibold text-gray-900">
Last name
<label htmlFor="lastName" className="block text-sm/6 font-semibold text-gray-900">
Last name *
</label>
<div className="mt-2.5">
<input
id="last-name"
name="last-name"
id="lastName"
name="lastName"
type="text"
required
autoComplete="family-name"
value={formData.lastName}
onChange={handleInputChange}
className="block w-full rounded-md bg-white px-3.5 py-2 text-base text-gray-900 outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline-2 focus:-outline-offset-2 focus:outline-indigo-600"
/>
</div>
</div>
<div className="sm:col-span-2">
<label htmlFor="email" className="block text-sm/6 font-semibold text-gray-900">
Email
Email *
</label>
<div className="mt-2.5">
<input
id="email"
name="email"
type="email"
required
autoComplete="email"
value={formData.email}
onChange={handleInputChange}
className="block w-full rounded-md bg-white px-3.5 py-2 text-base text-gray-900 outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline-2 focus:-outline-offset-2 focus:outline-indigo-600"
/>
</div>
</div>
<div className="sm:col-span-2">
<label htmlFor="phone-number" className="block text-sm/6 font-semibold text-gray-900">
<label htmlFor="phoneNumber" className="block text-sm/6 font-semibold text-gray-900">
Phone number
</label>
<div className="mt-2.5">
<input
id="phone-number"
name="phone-number"
id="phoneNumber"
name="phoneNumber"
type="tel"
autoComplete="tel"
value={formData.phoneNumber}
onChange={handleInputChange}
className="block w-full rounded-md bg-white px-3.5 py-2 text-base text-gray-900 outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline-2 focus:-outline-offset-2 focus:outline-indigo-600"
/>
</div>
</div>
<div className="sm:col-span-2">
<label htmlFor="message" className="block text-sm/6 font-semibold text-gray-900">
Message
Message *
</label>
<div className="mt-2.5">
<textarea
id="message"
name="message"
rows={4}
required
value={formData.message}
onChange={handleInputChange}
className="block w-full rounded-md bg-white px-3.5 py-2 text-base text-gray-900 outline-1 -outline-offset-1 outline-gray-300 placeholder:text-gray-400 focus:outline-2 focus:-outline-offset-2 focus:outline-indigo-600"
defaultValue={''}
/>
</div>
</div>
@ -151,9 +234,14 @@ export function ContactHero() {
<div className="mt-8 flex justify-end">
<button
type="submit"
className="rounded-md bg-indigo-600 px-3.5 py-2.5 text-center text-sm font-semibold text-white shadow-xs hover:bg-indigo-500 focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600"
disabled={isSubmitting}
className={`rounded-md px-3.5 py-2.5 text-center text-sm font-semibold text-white shadow-xs focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-600 ${
isSubmitting
? 'bg-gray-400 cursor-not-allowed'
: 'bg-indigo-600 hover:bg-gray-500'
}`}
>
Send message
{isSubmitting ? 'Sending...' : 'Send message'}
</button>
</div>
</div>

View File

@ -86,6 +86,7 @@ export function Header() {
<header className="py-5">
<Container>
<nav className="relative z-50 flex justify-between">
<div className="flex items-center md:gap-x-12">
<Link href="/" aria-label="Home">
<Logo className="h-6 w-auto lg:h-6 md:h-8" />

View File

@ -33,8 +33,40 @@ const features = [
export function HomeAbout() {
return (
<div className="bg-black py-24 sm:py-32">
<div className="relative bg-black py-24 sm:py-32 overflow-hidden">
<div className="mx-auto max-w-7xl px-6 lg:px-8">
<div
aria-hidden="true"
className="absolute inset-0 -z-10 overflow-hidden"
>
<div
style={{
background: 'linear-gradient(135deg, #ff80b5 0%, #9089fc 100%)',
width: '800px',
height: '600px',
borderRadius: '50%',
filter: 'blur(100px)',
opacity: 0.3,
position: 'absolute',
top: '20%',
right: '10%'
}}
/>
<div
style={{
background: 'linear-gradient(225deg, #9089fc 0%, #ff80b5 100%)',
width: '600px',
height: '400px',
borderRadius: '50%',
filter: 'blur(80px)',
opacity: 0.2,
position: 'absolute',
bottom: '20%',
left: '10%'
}}
/>
</div>
<div className="mx-auto max-w-4xl lg:mx-0">
<p className="subtitle text-white">ABOUT</p>
<h2 className="mt-2 h2-default text-white">

View File

@ -67,7 +67,7 @@ export function PersonTemplate({ personData, biography }: PersonTemplateProps) {
href={personData.linkedinUrl}
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500"
className="inline-flex items-center px-4 py-2 border border-transparent text-sm font-medium rounded-md text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-gray-500"
>
Connect on LinkedIn
</a>

View File

@ -38,26 +38,30 @@ export function VenturesCybercity() {
</p>
</blockquote>
<figcaption className="mt-4 flex gap-x-4">
<img
alt=""
src="/images/people/chris_camponovo/chris_camponovo.jpeg"
className="mt-1 size-14 flex-none rounded-full bg-gray-50"
/>
<div>
<p className="font-semibold text-base text-gray-900">Chris Camponovo</p>
<p className="text-gray-600 text-sm/8">Co-founder</p>
</div>
<a href="/people/chris_camponovo" className="flex gap-x-4 hover:opacity-80 transition-opacity">
<img
alt=""
src="/images/people/chris_camponovo/chris_camponovo.jpeg"
className="mt-1 size-14 flex-none rounded-full bg-gray-50"
/>
<div>
<p className="font-semibold text-base text-gray-900 hover:text-indigo-600">Chris Camponovo</p>
<p className="text-gray-600 text-sm/8">Co-founder</p>
</div>
</a>
</figcaption>
<figcaption className="mt-4 flex gap-x-4">
<img
alt=""
src="/images/people/florian_fournier/florian_fournier.jpeg"
className="mt-1 size-14 flex-none rounded-full bg-gray-50"
/>
<div>
<p className="font-semibold text-base text-gray-900">Florian Fournier</p>
<p className="text-gray-600 text-sm/8">Co-founder</p>
</div>
<a href="/people/florian_fournier" className="flex gap-x-4 hover:opacity-80 transition-opacity">
<img
alt=""
src="/images/people/florian_fournier/florian_fournier.jpeg"
className="mt-1 size-14 flex-none rounded-full bg-gray-50"
/>
<div>
<p className="font-semibold text-base text-gray-900 hover:text-indigo-600">Florian Fournier</p>
<p className="text-gray-600 text-sm/8">Co-founder</p>
</div>
</a>
</figcaption>
<blockquote className="mt-6 text-lg/8 font-semibold tracking-tight text-gray-900">
<p>
@ -70,13 +74,13 @@ export function VenturesCybercity() {
Website
</p>
<p className='text-lg/7 font-light text-gray-600'>
<a href="http://cybercity.ourworld.tf/" className="text-indigo-600 hover:text-indigo-500">cybercity.ourworld.tf</a>
<a href="http://cybercity.ourworld.tf/" className="text-indigo-600 hover:text-gray-500">cybercity.ourworld.tf</a>
</p>
<p className='mt-6'>
Contact
</p>
<p className='text-lg/7 font-light text-gray-600'>
<a href="mailto:info@threefold.io " className="text-indigo-600 hover:text-indigo-500">info@ourworld.tf</a>
<a href="mailto:info@threefold.io " className="text-indigo-600 hover:text-gray-50">info@ourworld.tf</a>
</p>
</blockquote>
</figure>

View File

@ -38,26 +38,30 @@ export function VenturesFreezone() {
</p>
</blockquote>
<figcaption className="mt-4 flex gap-x-4">
<img
alt=""
src="/images/people/chris_camponovo/chris_camponovo.jpeg"
className="mt-1 size-14 flex-none rounded-full bg-gray-50"
/>
<div>
<p className="font-semibold text-base text-gray-900">Chris Camponovo</p>
<p className="text-gray-600 text-sm/8">Co-founder</p>
</div>
<a href="/people/chris_camponovo" className="flex gap-x-4 hover:opacity-80 transition-opacity">
<img
alt=""
src="/images/people/chris_camponovo/chris_camponovo.jpeg"
className="mt-1 size-14 flex-none rounded-full bg-gray-50"
/>
<div>
<p className="font-semibold text-base text-gray-900 hover:text-indigo-600">Chris Camponovo</p>
<p className="text-gray-600 text-sm/8">Co-founder</p>
</div>
</a>
</figcaption>
<figcaption className="mt-4 flex gap-x-4">
<img
alt=""
src="/images/people/florian_fournier/florian_fournier.jpeg"
className="mt-1 size-14 flex-none rounded-full bg-gray-50"
/>
<div>
<p className="font-semibold text-base text-gray-900">Florian Fournier</p>
<p className="text-gray-600 text-sm/8">Co-founder</p>
</div>
<a href="/people/florian_fournier" className="flex gap-x-4 hover:opacity-80 transition-opacity">
<img
alt=""
src="/images/people/florian_fournier/florian_fournier.jpeg"
className="mt-1 size-14 flex-none rounded-full bg-gray-50"
/>
<div>
<p className="font-semibold text-base text-gray-900 hover:text-indigo-600">Florian Fournier</p>
<p className="text-gray-600 text-sm/8">Co-founder</p>
</div>
</a>
</figcaption>
<blockquote className="mt-6 text-lg/8 font-semibold tracking-tight text-gray-900">
<p>
@ -70,13 +74,13 @@ export function VenturesFreezone() {
Website
</p>
<p className='text-lg/7 font-light text-gray-600'>
<a href="http://cybercity.ourworld.tf/" className="text-indigo-600 hover:text-indigo-500">cybercity.ourworld.tf</a>
<a href="http://cybercity.ourworld.tf/" className="text-indigo-600 hover:text-gray-500">cybercity.ourworld.tf</a>
</p>
<p className='mt-6'>
Contact
</p>
<p className='text-lg/7 font-light text-gray-600'>
<a href="mailto:info@threefold.io " className="text-indigo-600 hover:text-indigo-500">info@ourworld.tf</a>
<a href="mailto:info@threefold.io " className="text-indigo-600 hover:text-gray-500">info@ourworld.tf</a>
</p>
</blockquote>
</figure>

View File

@ -38,26 +38,30 @@ export function VenturesGeomind() {
</p>
</blockquote>
<figcaption className="mt-4 flex gap-x-4">
<img
alt=""
src="/images/people/kristof_de_spiegeleer/kristof_de_spiegeleer.jpeg"
className="mt-1 size-14 flex-none rounded-full bg-gray-50"
/>
<div>
<p className="font-semibold text-base text-gray-900">Kristof de Spiegeleer</p>
<p className="text-gray-600 text-sm/8">Co-founder & CEO</p>
</div>
<a href="/people/kristof_de_spiegeleer" className="flex gap-x-4 hover:opacity-80 transition-opacity">
<img
alt=""
src="/images/people/kristof_de_spiegeleer/kristof_de_spiegeleer.jpeg"
className="mt-1 size-14 flex-none rounded-full bg-gray-50"
/>
<div>
<p className="font-semibold text-base text-gray-900 hover:text-indigo-600">Kristof de Spiegeleer</p>
<p className="text-gray-600 text-sm/8">Co-founder & CEO</p>
</div>
</a>
</figcaption>
<figcaption className="mt-4 flex gap-x-4">
<img
alt=""
src="/images/people/malte_geierhos/malte_geierhos.jpeg"
className="mt-1 size-14 flex-none rounded-full bg-gray-50"
/>
<div>
<p className="font-semibold text-base text-gray-900">Malte Geierhos</p>
<p className="text-gray-600 text-sm/8">CTO</p>
</div>
<a href="/people/malte_geierhos" className="flex gap-x-4 hover:opacity-80 transition-opacity">
<img
alt=""
src="/images/people/malte_geierhos/malte_geierhos.jpeg"
className="mt-1 size-14 flex-none rounded-full bg-gray-50"
/>
<div>
<p className="font-semibold text-base text-gray-900 hover:text-indigo-600">Malte Geierhos</p>
<p className="text-gray-600 text-sm/8">CTO</p>
</div>
</a>
</figcaption>
<blockquote className="mt-6 text-lg/8 font-semibold tracking-tight text-gray-900">
<p>
@ -70,13 +74,13 @@ export function VenturesGeomind() {
Website
</p>
<p className='text-lg/7 font-light text-gray-600'>
<a href="https://geomind.io/" className="text-indigo-600 hover:text-indigo-500">www.geomind.io</a>
<a href="https://geomind.io/" className="text-indigo-600 hover:text-gray-500">www.geomind.io</a>
</p>
<p className='mt-6'>
Contact
</p>
<p className='text-lg/7 font-light text-gray-600'>
<a href="mailto:info@threefold.io " className="text-indigo-600 hover:text-indigo-500">info@ourworld.tf</a>
<a href="mailto:info@threefold.io " className="text-indigo-600 hover:text-gray-500">info@ourworld.tf</a>
</p>
</blockquote>
</figure>

View File

@ -4,42 +4,42 @@ const ventures = [
logo: '/images/ventures/tf.png',
description: 'ThreeFold is a scalable bare metal infrastructure layer for AI, Internet, and Cloud presenting a cloud solution that offers unmatched security, reliability, performance, and autonomy. Leveraging open source technology as developed by TF9.',
url: 'https://threefold.io',
learnMoreUrl: 'ventures/threefold'
learnMoreUrl: './threefold'
},
{
name: 'GeoMind',
logo: '/images/ventures/geo_ico.png',
description: 'GeoMind is a software company which has developed a cloud computing system designed for global scalability, offering secure, immutable data storage that ensures integrity and permanence.',
url: 'https://geomind.io',
learnMoreUrl: 'ventures/geomind'
learnMoreUrl: './geomind'
},
{
name: 'Zanzibar Digital Free Zone',
logo: '/images/ventures/freezone.png',
description: 'A collaboration with the Government of Zanzibar through ZICTA. 100% digital and automated, offering seamless legal, financial, and operational support for businesses. The FreeZone provides regulatory incentives and benefits to businesses through a fully online platform.',
url: 'http://cybercity.ourworld.tf/',
learnMoreUrl: 'ventures/freezone'
learnMoreUrl: './freezone'
},
{
name: 'Zanzibar Cyber City',
logo: '/images/ventures/cybercity.png',
description: 'A visionary startup city featuring 3,000 units in its initial stages. The cyber city aims to be a collaborative hub for innovation, bringing together startups, investors, and technologists in a state-of-the-art urban environment.',
url: 'http://cybercity.ourworld.tf/',
learnMoreUrl: 'ventures/cybercity'
learnMoreUrl: './cybercity'
},
{
name: 'Indaba',
logo: '/images/ventures/ow_icon.png',
description: 'Indaba is a social business empowering young people to be resilient, reach their full potential, and contribute to the common good. A global ecosystem for holistic learning - accessible online and offline, affordable to the many, and grounded in culture, care, and collaboration.',
url: 'https://sikana.tv',
learnMoreUrl: 'ventures/indaba'
learnMoreUrl: './indaba'
},
{
name: 'Hero',
logo: '/images/ventures/hero.png',
description: 'Hero is a digital assistant designed to give individuals full control over their digital identity and assets. Focused on privacy and autonomy, Hero helps manage personal information, tasks, and interactions across decentralized platforms.',
url: '#',
learnMoreUrl: '/ventures/hero'
learnMoreUrl: './hero'
}
]

View File

@ -1,9 +1,9 @@
import {
CpuChipIcon,
UsersIcon,
CheckBadgeIcon,
LightBulbIcon,
UserIcon,
ShieldCheckIcon,
SparklesIcon,
BookOpenIcon,
HandRaisedIcon
} from '@heroicons/react/20/solid'
@ -23,9 +23,9 @@ export function VenturesHeroApp() {
<div className="lg:pr-8">
<h2 className="text-2xl font-semibold tracking-tight text-pretty text-gray-900">About</h2>
<p className="mt-6 text-lg/7 text-gray-600">
Indaba is a social business on a mission to empower young people to be resilient, reach their full potential, and contribute to the common good. Were building a global ecosystem for holistic learning ; accessible online and offline, affordable to the many, and grounded in culture, care, and collaboration.</p>
HERO is a next-generation Personal Agent (PA), a sovereign digital assistant designed to act entirely on behalf of its user. Developed on the ThreeFold infrastructure and operating within a sovereign digital freezone, HERO prioritizes privacy, autonomy, and user control in every interaction.</p>
<p className="mt-8 text-lg/7 text-gray-600">
Indaba is the platform that adds an "Engage" button to the Internet. While most platforms offer "Like," or "Comment," Indaba invites people to take responsibility, contribute meaningfully, and become part of the solution.
Unlike traditional AI systems owned by corporations and driven by centralized data harvesting, HERO is built around the principles of Augmented Collective Intelligence (ACI), enabling personalized intelligence that evolves through real human context. It integrates seamlessly into everyday life, supporting communication, identity, knowledge, memory, and transactions while preserving cultural nuance and digital sovereignty.
</p>
</div>
<div className="lg:row-span-2 lg:-mr-24 xl:mr-auto">
@ -37,33 +37,37 @@ export function VenturesHeroApp() {
Sector
</p>
<p className='text-lg/7 font-light text-gray-600'>
Education, Philantrophy, and Internet
Innovation, Internet
</p>
<p className='mt-4'>
Key Contact
</p>
</blockquote>
<figcaption className="mt-4 flex gap-x-4">
<img
alt=""
src="/images/people/gregory_flipo/gregory_flipo.jpg"
className="mt-1 size-14 flex-none rounded-full bg-gray-50"
/>
<div>
<p className="font-semibold text-base text-gray-900">Gregory Flipo </p>
<p className="text-gray-600 text-sm/8">Co-founder</p>
</div>
<a href="/people/kristof_de_spiegeleer" className="flex gap-x-4 hover:opacity-80 transition-opacity">
<img
alt=""
src="/images/people/kristof_de_spiegeleer/kristof_de_spiegeleer.jpeg"
className="mt-1 size-14 flex-none rounded-full bg-gray-50"
/>
<div>
<p className="font-semibold text-base text-gray-900 hover:text-indigo-600">Kristof De Spiegeleer</p>
<p className="text-gray-600 text-sm/8">Co-Founder, CEO</p>
</div>
</a>
</figcaption>
<figcaption className="mt-4 flex gap-x-4">
<img
alt=""
src="/images/people/sacha_obeegadoo/sacha_obeegadoo.jpg"
className="mt-1 size-14 flex-none rounded-full bg-gray-50"
/>
<div>
<p className="font-semibold text-base text-gray-900">Sacha Obeegadoo</p>
<p className="text-gray-600 text-sm/8">Co-founder</p>
</div>
<a href="/people/florian_fournier" className="flex gap-x-4 hover:opacity-80 transition-opacity">
<img
alt=""
src="/images/people/florian_fournier/florian_fournier.jpeg"
className="mt-1 size-14 flex-none rounded-full bg-gray-50"
/>
<div>
<p className="font-semibold text-base text-gray-900 hover:text-indigo-600">Florian Fournier</p>
<p className="text-gray-600 text-sm/8">Co-Founder</p>
</div>
</a>
</figcaption>
<blockquote className="mt-6 text-lg/8 font-semibold tracking-tight text-gray-900">
<p>
@ -76,13 +80,13 @@ export function VenturesHeroApp() {
Website
</p>
<p className='text-lg/7 font-light text-gray-600'>
<a href="http://ourworld.tf/" className="text-indigo-600 hover:text-indigo-500">indaba.ourworld.tf</a>
<a href="http://ourworld.tf/" className="text-indigo-600 hover:text-gray-500">www.ourworld.tf</a>
</p>
<p className='mt-6'>
Contact
</p>
<p className='text-lg/7 font-light text-gray-600'>
<a href="mailto:info@threefold.io " className="text-indigo-600 hover:text-indigo-500">info@ourworld.tf</a>
<a href="mailto:info@threefold.io " className="text-indigo-600 hover:text-gray-500">info@ourworld.tf</a>
</p>
</blockquote>
</figure>
@ -90,49 +94,35 @@ export function VenturesHeroApp() {
</div>
</div>
<div className="max-lg:mt-8 lg:col-span-1">
<p className="text-2xl font-semibold tracking-tight text-pretty text-gray-900">Indaba Ecosystem</p>
<p className="text-2xl font-semibold tracking-tight text-pretty text-gray-900">Key Features</p>
<hr className="mt-6 border-t border-gray-200" />
<ul role="list" className="mt-8 space-y-8 text-gray-600">
<li className="flex gap-x-3">
<UsersIcon aria-hidden="true" className="mt-1 size-5 flex-none text-black" />
<UserIcon aria-hidden="true" className="mt-1 size-5 flex-none text-black" />
<span>
<strong className="font-semibold text-lg text-gray-900">Indaba Studios. </strong>
A global engagement platform empowering people everywhere to contribute to the integral development of young people ; so they can grow in dignity, flourish fully, and serve the common good.
<strong className="font-semibold text-lg text-gray-900">Personal Agent Layer. </strong>
HERO acts as a digital assistant. It andles daily operations including messaging, calendars, identity, credentials, documentation, AI tasks, and transactions, all securely encrypted and user-governed.
</span>
</li>
<li className="flex gap-x-3">
<CpuChipIcon aria-hidden="true" className="mt-1 size-5 flex-none text-black" />
<span>
<strong className="font-semibold text-lg text-gray-900">IndabaOS. </strong>
The tech infrastructure that invites the world to accelerate the transition toward high quality youth development.
<strong className="font-semibold text-lg text-gray-900">Secure, Unbreakable Memory. </strong>
Personal memory is distributed across a decentralized network using quantum-resistant cryptography, ensuring security, redundancy, and unbreachable privacy.
</span>
</li>
<li className="flex gap-x-3">
<CheckBadgeIcon aria-hidden="true" className="mt-1 size-5 flex-none text-black" />
<ShieldCheckIcon aria-hidden="true" className="mt-1 size-5 flex-none text-black" />
<span>
<strong className="font-semibold text-lg text-gray-900">Indaba Certifications. </strong>
Recognition frameworks that validate skills, experiences, and contributions across the Indaba ecosystem.
<strong className="font-semibold text-lg text-gray-900">Private Blockchain Ledger. </strong>
Every HERO maintains a private blockchain ledger that verifies identity, manages access control, tracks interactions, and can communicate securely with other ledgers.
</span>
</li>
<li className="flex gap-x-3">
<LightBulbIcon aria-hidden="true" className="mt-1 size-5 flex-none text-black" />
<SparklesIcon aria-hidden="true" className="mt-1 size-5 flex-none text-black" />
<span>
<strong className="font-semibold text-lg text-gray-900">Indaba Foundation. </strong>
A lighthouse to empower nannies, teachers, caregivers, and school operators to reshape the landscape and trajectory of education in Africa ; and beyond.
</span>
</li>
<li className="flex gap-x-3">
<BookOpenIcon aria-hidden="true" className="mt-1 size-5 flex-none text-black" />
<span>
<strong className="font-semibold text-lg text-gray-900">Indaba Institute. </strong>
A global collaborative effort to build a purpose-driven WikipediaSpotify of youth development.
</span>
</li>
<li className="flex gap-x-3">
<HandRaisedIcon aria-hidden="true" className="mt-1 size-5 flex-none text-black" />
<span>
<strong className="font-semibold text-lg text-gray-900">ECD Teachers. </strong>
A giving model that invites aligned individuals and organizations to invest in systemic, community-led transformation.
<strong className="font-semibold text-lg text-gray-900">AI Agent. </strong>
HERO connects with a wide range of AI agents for research, content creation, and task automation. All computation is done locally or via trusted partners.
</span>
</li>
</ul>

View File

@ -44,26 +44,30 @@ export function VenturesIndaba() {
</p>
</blockquote>
<figcaption className="mt-4 flex gap-x-4">
<img
alt=""
src="/images/people/gregory_flipo/gregory_flipo.jpg"
className="mt-1 size-14 flex-none rounded-full bg-gray-50"
/>
<div>
<p className="font-semibold text-base text-gray-900">Gregory Flipo </p>
<p className="text-gray-600 text-sm/8">Co-founder</p>
</div>
<a href="/people/gregory_flipo" className="flex gap-x-4 hover:opacity-80 transition-opacity">
<img
alt=""
src="/images/people/gregory_flipo/gregory_flipo.jpg"
className="mt-1 size-14 flex-none rounded-full bg-gray-50"
/>
<div>
<p className="font-semibold text-base text-gray-900 hover:text-indigo-600">Gregory Flipo </p>
<p className="text-gray-600 text-sm/8">Co-founder</p>
</div>
</a>
</figcaption>
<figcaption className="mt-4 flex gap-x-4">
<img
alt=""
src="/images/people/sacha_obeegadoo/sacha_obeegadoo.jpg"
className="mt-1 size-14 flex-none rounded-full bg-gray-50"
/>
<div>
<p className="font-semibold text-base text-gray-900">Sacha Obeegadoo</p>
<p className="text-gray-600 text-sm/8">Co-founder</p>
</div>
<a href="/people/sacha_obeegadoo" className="flex gap-x-4 hover:opacity-80 transition-opacity">
<img
alt=""
src="/images/people/sacha_obeegadoo/sacha_obeegadoo.jpg"
className="mt-1 size-14 flex-none rounded-full bg-gray-50"
/>
<div>
<p className="font-semibold text-base text-gray-900 hover:text-indigo-600">Sacha Obeegadoo</p>
<p className="text-gray-600 text-sm/8">Co-founder</p>
</div>
</a>
</figcaption>
<blockquote className="mt-6 text-lg/8 font-semibold tracking-tight text-gray-900">
<p>
@ -76,13 +80,13 @@ export function VenturesIndaba() {
Website
</p>
<p className='text-lg/7 font-light text-gray-600'>
<a href="http://ourworld.tf/" className="text-indigo-600 hover:text-indigo-500">indaba.ourworld.tf</a>
<a href="http://ourworld.tf/" className="text-indigo-600 hover:text-gray-500">indaba.ourworld.tf</a>
</p>
<p className='mt-6'>
Contact
</p>
<p className='text-lg/7 font-light text-gray-600'>
<a href="mailto:info@threefold.io " className="text-indigo-600 hover:text-indigo-500">info@ourworld.tf</a>
<a href="mailto:info@threefold.io " className="text-indigo-600 hover:text-gray-500">info@ourworld.tf</a>
</p>
</blockquote>
</figure>

View File

@ -37,26 +37,30 @@ export function VenturesThreeFold() {
</p>
</blockquote>
<figcaption className="mt-4 flex gap-x-4">
<img
alt=""
src="/images/people/kristof_de_spiegeleer/kristof_de_spiegeleer.jpeg"
className="mt-1 size-14 flex-none rounded-full bg-gray-50"
/>
<div>
<p className="font-semibold text-base text-gray-900">Kristof de Spiegeleer</p>
<p className="text-gray-600 text-sm/8">Co-founder & CEO</p>
</div>
<a href="/people/kristof_de_spiegeleer" className="flex gap-x-4 hover:opacity-80 transition-opacity">
<img
alt=""
src="/images/people/kristof_de_spiegeleer/kristof_de_spiegeleer.jpeg"
className="mt-1 size-14 flex-none rounded-full bg-gray-50"
/>
<div>
<p className="font-semibold text-base text-gray-900 hover:text-indigo-600">Kristof de Spiegeleer</p>
<p className="text-gray-600 text-sm/8">Co-founder & CEO</p>
</div>
</a>
</figcaption>
<figcaption className="mt-4 flex gap-x-4">
<img
alt=""
src="/images/people/florian_fournier/florian_fournier.jpeg"
className="mt-1 size-14 flex-none rounded-full bg-gray-50"
/>
<div>
<p className="font-semibold text-base text-gray-900">Florian Fournier</p>
<p className="text-gray-600 text-sm/8">Co-founder</p>
</div>
<a href="/people/florian_fournier" className="flex gap-x-4 hover:opacity-80 transition-opacity">
<img
alt=""
src="/images/people/florian_fournier/florian_fournier.jpeg"
className="mt-1 size-14 flex-none rounded-full bg-gray-50"
/>
<div>
<p className="font-semibold text-base text-gray-900 hover:text-indigo-600">Florian Fournier</p>
<p className="text-gray-600 text-sm/8">Co-founder</p>
</div>
</a>
</figcaption>
<blockquote className="mt-6 text-lg/8 font-semibold tracking-tight text-gray-900">
<p>
@ -69,13 +73,13 @@ export function VenturesThreeFold() {
Website
</p>
<p className='text-lg/7 font-light text-gray-600'>
<a href="https://threefold.io" className="text-indigo-600 hover:text-indigo-500">www.threefold.io</a>
<a href="https://threefold.io" className="text-indigo-600 hover:text-gray-500">www.threefold.io</a>
</p>
<p className='mt-6'>
Contact
</p>
<p className='text-lg/7 font-light text-gray-600'>
<a href="mailto:info@threefold.io " className="text-indigo-600 hover:text-indigo-500">info@threefold.io</a>
<a href="mailto:info@threefold.io " className="text-indigo-600 hover:text-gray-500">info@threefold.io</a>
</p>
</blockquote>
</figure>

View File

@ -14,7 +14,7 @@ const biography = `
<p class="text-lg/7">
Kristof is a technologist, philosopher, and builder with a long-standing dedication to creating systems that serve the common good. With a background in distributed infrastructure and digital ecosystems, his work is driven by a deep belief in open collaboration, self-sovereignty, and planetary resilience.
</p>
<p class="mt-5">
<p class="mt-5 text-lg/7">
At OurWorld, Kristof brings together decades of experience in architecture, code, and community-building to lay the groundwork for ventures that are not only scalable and secure; but deeply ethical by design. His vision anchors the platform's commitment to aligning technology with life itself.
</p>
`

View File

@ -4,7 +4,7 @@ export const data = [
{
name: 'Malte Geierhos',
role: 'Team Member',
imageUrl: '/images/people/Malte_Geierhos/Malte_Geierhos.jpeg',
imageUrl: '/images/people/malte_geierhos/malte_geierhos.jpeg',
xUrl: '#',
linkedinUrl: 'https://www.linkedin.com/in/malte-geierhos/',
},