Update with real Diagram
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
import type { Metadata } from 'next';
|
import type { Metadata } from 'next';
|
||||||
import CodeBlock from '@/components/ui/CodeBlock';
|
import CodeBlock from '@/components/ui/CodeBlock';
|
||||||
|
import P2NSFlowDiagram from '@/components/diagrams/P2NSFlowDiagram';
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: 'How It Works - P2NS Documentation',
|
title: 'How It Works - P2NS Documentation',
|
||||||
@@ -43,22 +44,8 @@ export default function HowItWorksPage() {
|
|||||||
<p className="text-gray-600 dark:text-gray-300 mb-4">
|
<p className="text-gray-600 dark:text-gray-300 mb-4">
|
||||||
Here's a high-level view of what happens when you access a P2NS domain:
|
Here's a high-level view of what happens when you access a P2NS domain:
|
||||||
</p>
|
</p>
|
||||||
<div className="bg-gray-50 dark:bg-gray-800 p-6 rounded-lg mb-6">
|
<div className="mb-6">
|
||||||
<pre className="text-sm text-gray-700 dark:text-gray-300 whitespace-pre-wrap font-mono">
|
<P2NSFlowDiagram />
|
||||||
{`1. User Request
|
|
||||||
↓
|
|
||||||
2. DNS Query → P2NS DNS Server
|
|
||||||
↓
|
|
||||||
3. P2P Network Lookup → Find Domain Hash
|
|
||||||
↓
|
|
||||||
4. Virtual Interface → Assign Local IP
|
|
||||||
↓
|
|
||||||
5. Holesail Client → Establish Tunnel
|
|
||||||
↓
|
|
||||||
6. HTTPS Proxy → Route Request
|
|
||||||
↓
|
|
||||||
7. Service Response → Back to User`}
|
|
||||||
</pre>
|
|
||||||
</div>
|
</div>
|
||||||
<p className="text-gray-600 dark:text-gray-300 mb-6">
|
<p className="text-gray-600 dark:text-gray-300 mb-6">
|
||||||
The key components involved are: <strong className="text-gray-900 dark:text-white">peers</strong> (other P2NS nodes),
|
The key components involved are: <strong className="text-gray-900 dark:text-white">peers</strong> (other P2NS nodes),
|
||||||
|
|||||||
@@ -0,0 +1,147 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { motion } from 'framer-motion';
|
||||||
|
import { User, Globe, Network, Server, Shield, ArrowDown, ArrowRight, CheckCircle } from 'lucide-react';
|
||||||
|
|
||||||
|
const steps = [
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
title: 'User Request',
|
||||||
|
description: 'User types domain',
|
||||||
|
icon: User,
|
||||||
|
color: 'blue',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
title: 'DNS Query',
|
||||||
|
description: 'P2NS DNS Server',
|
||||||
|
icon: Globe,
|
||||||
|
color: 'purple',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
title: 'P2P Network',
|
||||||
|
description: 'Find Domain Hash',
|
||||||
|
icon: Network,
|
||||||
|
color: 'green',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 4,
|
||||||
|
title: 'Virtual Interface',
|
||||||
|
description: 'Assign Local IP',
|
||||||
|
icon: Server,
|
||||||
|
color: 'orange',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 5,
|
||||||
|
title: 'Holesail Client',
|
||||||
|
description: 'Establish Tunnel',
|
||||||
|
icon: Shield,
|
||||||
|
color: 'red',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 6,
|
||||||
|
title: 'HTTPS Proxy',
|
||||||
|
description: 'Route Request',
|
||||||
|
icon: Server,
|
||||||
|
color: 'indigo',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 7,
|
||||||
|
title: 'Service Response',
|
||||||
|
description: 'Back to User',
|
||||||
|
icon: CheckCircle,
|
||||||
|
color: 'blue',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
const colorClasses = {
|
||||||
|
blue: 'bg-blue-100 dark:bg-blue-900 text-blue-600 dark:text-blue-400 border-blue-200 dark:border-blue-700',
|
||||||
|
purple: 'bg-purple-100 dark:bg-purple-900 text-purple-600 dark:text-purple-400 border-purple-200 dark:border-purple-700',
|
||||||
|
green: 'bg-green-100 dark:bg-green-900 text-green-600 dark:text-green-400 border-green-200 dark:border-green-700',
|
||||||
|
orange: 'bg-orange-100 dark:bg-orange-900 text-orange-600 dark:text-orange-400 border-orange-200 dark:border-orange-700',
|
||||||
|
red: 'bg-red-100 dark:bg-red-900 text-red-600 dark:text-red-400 border-red-200 dark:border-red-700',
|
||||||
|
indigo: 'bg-indigo-100 dark:bg-indigo-900 text-indigo-600 dark:text-indigo-400 border-indigo-200 dark:border-indigo-700',
|
||||||
|
};
|
||||||
|
|
||||||
|
export default function P2NSFlowDiagram() {
|
||||||
|
// Group steps into rows of 2
|
||||||
|
const rows: (typeof steps)[] = [];
|
||||||
|
for (let i = 0; i < steps.length; i += 2) {
|
||||||
|
rows.push(steps.slice(i, i + 2));
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="bg-gradient-to-br from-gray-50 to-gray-100 dark:from-gray-800 dark:to-gray-900 rounded-xl p-6 md:p-8 border border-gray-200 dark:border-gray-700 shadow-lg">
|
||||||
|
<div className="max-w-4xl mx-auto">
|
||||||
|
{rows.map((row, rowIndex) => {
|
||||||
|
const isLastRow = rowIndex === rows.length - 1;
|
||||||
|
const isOddLastRow = isLastRow && row.length === 1;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div key={rowIndex} className="flex flex-col items-center">
|
||||||
|
<div className="grid grid-cols-2 gap-6 md:gap-8 w-full">
|
||||||
|
{row.map((step, stepIndex) => {
|
||||||
|
const Icon = step.icon;
|
||||||
|
const globalIndex = rowIndex * 2 + stepIndex;
|
||||||
|
const isLastInRow = stepIndex === row.length - 1;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div key={step.id} className="flex items-center">
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, y: -10 }}
|
||||||
|
whileInView={{ opacity: 1, y: 0 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
transition={{ duration: 0.4, delay: globalIndex * 0.08 }}
|
||||||
|
className="flex items-center gap-4 flex-1 bg-white dark:bg-gray-800 rounded-xl p-4 shadow-md hover:shadow-lg border border-gray-200 dark:border-gray-700 transition-all duration-300 hover:scale-[1.02]"
|
||||||
|
>
|
||||||
|
<div className={`p-3 rounded-xl border-2 ${colorClasses[step.color as keyof typeof colorClasses]} shadow-sm flex-shrink-0 transition-all duration-300 hover:scale-110`}>
|
||||||
|
<Icon className="h-6 w-6" />
|
||||||
|
</div>
|
||||||
|
<div className="flex-1 min-w-0">
|
||||||
|
<h3 className="text-base font-bold text-gray-900 dark:text-white mb-1 leading-tight">
|
||||||
|
{step.title}
|
||||||
|
</h3>
|
||||||
|
<p className="text-sm text-gray-600 dark:text-gray-400 leading-snug">
|
||||||
|
{step.description}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</motion.div>
|
||||||
|
|
||||||
|
{!isLastInRow && (
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, scale: 0.8 }}
|
||||||
|
whileInView={{ opacity: 1, scale: 1 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
transition={{ duration: 0.4, delay: globalIndex * 0.08 + 0.2 }}
|
||||||
|
className="flex-shrink-0 mx-2 md:mx-4"
|
||||||
|
>
|
||||||
|
<ArrowRight className="h-5 w-5 text-gray-500 dark:text-gray-400" strokeWidth={2.5} />
|
||||||
|
</motion.div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
{/* Empty cell for odd last row to center the single item */}
|
||||||
|
{isOddLastRow && <div></div>}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{!isLastRow && (
|
||||||
|
<motion.div
|
||||||
|
initial={{ opacity: 0, scale: 0.8 }}
|
||||||
|
whileInView={{ opacity: 1, scale: 1 }}
|
||||||
|
viewport={{ once: true }}
|
||||||
|
transition={{ duration: 0.4, delay: (rowIndex * 2 + 1) * 0.08 + 0.2 }}
|
||||||
|
className="my-4 md:my-6"
|
||||||
|
>
|
||||||
|
<ArrowDown className="h-6 w-6 text-gray-500 dark:text-gray-400" strokeWidth={2.5} />
|
||||||
|
</motion.div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user