Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
674 changes: 674 additions & 0 deletions website/src/components/AIChatbot.tsx

Large diffs are not rendered by default.

85 changes: 85 additions & 0 deletions website/src/components/AccessControlVisualizer.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import React, { useState } from 'react';
import { Shield, AlertTriangle, Lock, UserCheck } from 'lucide-react';

const roles = [
{
name: 'Owner',
icon: Shield,
color: 'bg-amber-500/10 text-amber-500',
permissions: ['Upgrade contract', 'Transfer ownership', 'Emergency pause'],
},
{
name: 'Admin',
icon: UserCheck,
color: 'bg-blue-500/10 text-blue-500',
permissions: ['Manage validators', 'Update parameters', 'Grant roles'],
},
{
name: 'Pauser',
icon: AlertTriangle,
color: 'bg-red-500/10 text-red-500',
permissions: ['Pause operations', 'Resume operations'],
},
{
name: 'Minter',
icon: Lock,
color: 'bg-emerald-500/10 text-emerald-500',
permissions: ['Mint tokens', 'Burn tokens'],
},
];

export function AccessControlVisualizer() {
const [activeRole, setActiveRole] = useState(roles[0]);

return (
<div className="my-6 overflow-hidden rounded-xl border border-border bg-card shadow-[0_0_0_1px_rgba(0,0,0,0.08)] dark:shadow-[0_0_0_1px_rgba(255,255,255,0.08)]">
<div className="border-b border-border px-5 py-3">
<div className="flex items-center gap-2">
<Shield className="h-4 w-4 text-primary" />
<h3 className="text-sm font-semibold">Access Control Roles</h3>
</div>
</div>
<div className="grid gap-4 p-5 sm:grid-cols-2">
<div className="space-y-2">
{roles.map((role) => {
const Icon = role.icon;
return (
<button
key={role.name}
onClick={() => setActiveRole(role)}
className={`flex w-full items-center gap-3 rounded-lg border p-3 text-left transition-all ${
activeRole.name === role.name
? 'border-primary bg-primary/5'
: 'border-border bg-background hover:bg-muted'
}`}
>
<div className={`flex h-9 w-9 items-center justify-center rounded-lg ${role.color}`}>
<Icon className="h-4 w-4" />
</div>
<span className="font-medium">{role.name}</span>
</button>
);
})}
</div>
<div className="rounded-lg bg-muted p-4">
<div className="mb-3 flex items-center gap-2">
{React.createElement(activeRole.icon, {
className: `h-5 w-5 ${activeRole.color.split(' ')[1]}`,
})}
<h4 className="font-semibold">{activeRole.name} Permissions</h4>
</div>
<ul className="space-y-2">
{activeRole.permissions.map((perm) => (
<li key={perm} className="flex items-center gap-2 text-sm text-muted-foreground">
<span className="h-1.5 w-1.5 rounded-full bg-primary" />
{perm}
</li>
))}
</ul>
</div>
</div>
</div>
);
}

export default AccessControlVisualizer;
52 changes: 52 additions & 0 deletions website/src/components/AddressValidator.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import React, { useState } from 'react';
import { CheckCircle2, XCircle, Search } from 'lucide-react';

export function AddressValidator() {
const [address, setAddress] = useState('xdc8ba9bc4ce7a37d8a84ac7f8');
const [isValid, setIsValid] = useState(false);

const validate = (value: string) => {
const regex = /^xdc[0-9a-fA-F]{40}$/;
setIsValid(regex.test(value));
setAddress(value);
};

return (
<div className="my-6 overflow-hidden rounded-xl border border-border bg-card shadow-[0_0_0_1px_rgba(0,0,0,0.08)] dark:shadow-[0_0_0_1px_rgba(255,255,255,0.08)]">
<div className="border-b border-border px-5 py-3">
<div className="flex items-center gap-2">
<Search className="h-4 w-4 text-primary" />
<h3 className="text-sm font-semibold">Address Validator</h3>
</div>
</div>
<div className="space-y-4 p-5">
<div className="relative">
<input
type="text"
value={address}
onChange={(e) => validate(e.target.value)}
placeholder="Enter xdc... address"
className="w-full rounded-lg border border-input bg-background px-3 py-2.5 pr-10 text-sm font-mono outline-none focus:ring-2 focus:ring-ring"
/>
<div className="absolute right-3 top-1/2 -translate-y-1/2">
{isValid ? (
<CheckCircle2 className="h-5 w-5 text-emerald-500" />
) : (
<XCircle className="h-5 w-5 text-red-500" />
)}
</div>
</div>
<div
className={`rounded-lg p-3 text-sm font-medium ${
isValid ? 'bg-emerald-500/10 text-emerald-500' : 'bg-red-500/10 text-red-500'
}`}
>
{isValid ? 'Valid XDC address format' : 'Invalid XDC address format'}
</div>
<p className="text-xs text-muted-foreground">XDC addresses start with "xdc" followed by 40 hexadecimal characters.</p>
</div>
</div>
);
}

export default AddressValidator;
28 changes: 28 additions & 0 deletions website/src/components/AnimatedHero/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react';
import styles from './styles.module.css';

export default function AnimatedHero() {
return (
<div className={styles.hero}>
<div className={styles.content}>
<h1 className={styles.title}>
<span className={styles.gradient}>XDC Network</span>
<br />
Documentation
</h1>
<p className={styles.subtitle}>
Build the future of decentralized finance on the XDC Chain
</p>
<div className={styles.cta}>
<a href="/learn" className={styles.primaryButton}>
Get Started
</a>
<a href="/xdcchain/developers" className={styles.secondaryButton}>
Developer Docs
</a>
</div>
</div>
<div className={styles.grid} />
</div>
);
}
112 changes: 112 additions & 0 deletions website/src/components/AnimatedHero/styles.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
.hero {
position: relative;
min-height: 80vh;
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
padding: 2rem;
}

.content {
position: relative;
z-index: 1;
text-align: center;
max-width: 800px;
}

.title {
font-size: 3.5rem;
font-weight: 800;
line-height: 1.1;
margin-bottom: 1rem;
}

.gradient {
background: linear-gradient(135deg, #2563eb, #06b6d4);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
animation: gradient-shift 3s ease infinite;
background-size: 200% 200%;
}

@keyframes gradient-shift {
0%, 100% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
}

.subtitle {
font-size: 1.25rem;
opacity: 0.8;
margin-bottom: 2rem;
}

.cta {
display: flex;
gap: 1rem;
justify-content: center;
}

.primaryButton {
padding: 0.875rem 2rem;
border-radius: 12px;
background: linear-gradient(135deg, #2563eb, #1d4ed8);
color: white;
font-weight: 600;
text-decoration: none;
transition: all 0.3s cubic-bezier(0.16, 1, 0.3, 1);
transform-style: preserve-3d;
}

.primaryButton:hover {
transform: translateY(-2px) translateZ(10px);
box-shadow: 0 10px 40px rgba(37, 99, 235, 0.3);
}

.secondaryButton {
padding: 0.875rem 2rem;
border-radius: 12px;
border: 1px solid var(--ifm-color-emphasis-300);
color: var(--ifm-font-color-base);
font-weight: 600;
text-decoration: none;
transition: all 0.3s ease;
background: transparent;
}

.secondaryButton:hover {
background: var(--ifm-color-emphasis-100);
transform: translateY(-2px);
}

.grid {
position: absolute;
inset: 0;
pointer-events: none;
z-index: 0;
background:
repeating-linear-gradient(
90deg,
var(--ifm-color-emphasis-200) 0px,
var(--ifm-color-emphasis-200) 1px,
transparent 1px,
transparent 100px
),
repeating-linear-gradient(
0deg,
var(--ifm-color-emphasis-200) 0px,
var(--ifm-color-emphasis-200) 1px,
transparent 1px,
transparent 100px
);
transform: perspective(500px) rotateX(60deg);
transform-origin: center top;
opacity: 0.2;
animation: grid-move 20s linear infinite;
}

@keyframes grid-move {
0% { background-position: 0 0; }
100% { background-position: 0 100px; }
}
114 changes: 114 additions & 0 deletions website/src/components/AnimatedSection.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import React from 'react';
import { motion, useReducedMotion } from 'framer-motion';
import { cn } from '@site/src/lib/utils';

interface AnimatedSectionProps {
children: React.ReactNode;
className?: string;
delay?: number;
}

export function AnimatedSection({ children, className, delay = 0 }: AnimatedSectionProps) {
const shouldReduceMotion = useReducedMotion();

return (
<motion.div
initial={shouldReduceMotion ? { opacity: 1 } : { opacity: 0, y: 28, filter: 'blur(4px)' }}
whileInView={{ opacity: 1, y: 0, filter: 'blur(0px)' }}
viewport={{ once: true, margin: '-80px' }}
transition={{
duration: 0.65,
delay,
ease: [0.16, 1, 0.3, 1],
}}
className={className}
>
{children}
</motion.div>
);
}

interface StaggerContainerProps {
children: React.ReactNode;
className?: string;
staggerDelay?: number;
}

export function StaggerContainer({ children, className, staggerDelay = 0.08 }: StaggerContainerProps) {
const shouldReduceMotion = useReducedMotion();

return (
<motion.div
initial="hidden"
whileInView="visible"
viewport={{ once: true, margin: '-60px' }}
variants={{
hidden: {},
visible: {
transition: {
staggerChildren: staggerDelay,
},
},
}}
className={className}
>
{React.Children.map(children, (child) =>
React.isValidElement(child) ? (
<motion.div
variants={
shouldReduceMotion
? { hidden: { opacity: 1 }, visible: { opacity: 1 } }
: {
hidden: { opacity: 0, y: 24, scale: 0.97, filter: 'blur(4px)' },
visible: {
opacity: 1,
y: 0,
scale: 1,
filter: 'blur(0px)',
transition: {
duration: 0.55,
ease: [0.16, 1, 0.3, 1],
},
},
}
}
>
{child}
</motion.div>
) : (
child
)
)}
</motion.div>
);
}

interface FadeInProps {
children: React.ReactNode;
className?: string;
delay?: number;
direction?: 'up' | 'down' | 'left' | 'right';
}

export function FadeIn({ children, className, delay = 0, direction = 'up' }: FadeInProps) {
const shouldReduceMotion = useReducedMotion();

const directionMap = {
up: { y: 24 },
down: { y: -24 },
left: { x: 24 },
right: { x: -24 },
};

return (
<motion.div
initial={shouldReduceMotion ? { opacity: 1 } : { opacity: 0, filter: 'blur(4px)', ...directionMap[direction] }}
whileInView={{ opacity: 1, x: 0, y: 0, filter: 'blur(0px)' }}
viewport={{ once: true, margin: '-40px' }}
transition={{ duration: 0.6, delay, ease: [0.16, 1, 0.3, 1] }}
className={cn(className)}
>
{children}
</motion.div>
);
}
Loading