Skip to content

Commit 45ff0b6

Browse files
Copilot0xrinegade
andcommitted
Implement individual tutorial pages with copy functionality and comprehensive step-by-step guides
Co-authored-by: 0xrinegade <[email protected]>
1 parent 59c7dda commit 45ff0b6

File tree

6 files changed

+1562
-10
lines changed

6 files changed

+1562
-10
lines changed
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import React, { useState } from 'react'
2+
import { Copy, Check } from 'lucide-react'
3+
4+
interface CopyButtonProps {
5+
text: string
6+
className?: string
7+
}
8+
9+
export function CopyButton({ text, className = '' }: CopyButtonProps) {
10+
const [copied, setCopied] = useState(false)
11+
12+
const handleCopy = async () => {
13+
try {
14+
await navigator.clipboard.writeText(text)
15+
setCopied(true)
16+
setTimeout(() => setCopied(false), 2000)
17+
} catch (err) {
18+
console.error('Failed to copy text: ', err)
19+
}
20+
}
21+
22+
return (
23+
<button
24+
onClick={handleCopy}
25+
className={`inline-flex items-center gap-2 px-3 py-1.5 text-sm font-medium rounded-md transition-colors ${
26+
copied
27+
? 'bg-green-100 text-green-700 hover:bg-green-200'
28+
: 'bg-slate-100 text-slate-600 hover:bg-slate-200'
29+
} ${className}`}
30+
>
31+
{copied ? (
32+
<>
33+
<Check className="w-4 h-4" />
34+
Copied!
35+
</>
36+
) : (
37+
<>
38+
<Copy className="w-4 h-4" />
39+
Copy
40+
</>
41+
)}
42+
</button>
43+
)
44+
}
Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
import React, { ReactNode } from 'react'
2+
import { motion } from 'framer-motion'
3+
import { ArrowLeft, Clock, BarChart3, CheckCircle } from 'lucide-react'
4+
import { Link } from 'react-router-dom'
5+
import { CopyButton } from './CopyButton'
6+
7+
interface TutorialStep {
8+
title: string
9+
description: string
10+
code?: string
11+
language?: string
12+
notes?: string[]
13+
}
14+
15+
interface TutorialLayoutProps {
16+
title: string
17+
description: string
18+
level: 'Beginner' | 'Intermediate' | 'Advanced' | 'Expert'
19+
time: string
20+
category: string
21+
categoryPath: string
22+
overview: string
23+
prerequisites?: string[]
24+
steps: TutorialStep[]
25+
conclusion?: string
26+
nextSteps?: string[]
27+
relatedTutorials?: Array<{
28+
title: string
29+
path: string
30+
}>
31+
}
32+
33+
export function TutorialLayout({
34+
title,
35+
description,
36+
level,
37+
time,
38+
category,
39+
categoryPath,
40+
overview,
41+
prerequisites = [],
42+
steps,
43+
conclusion,
44+
nextSteps = [],
45+
relatedTutorials = []
46+
}: TutorialLayoutProps) {
47+
const getLevelColor = (level: string) => {
48+
switch (level) {
49+
case 'Beginner': return 'bg-green-100 text-green-800'
50+
case 'Intermediate': return 'bg-yellow-100 text-yellow-800'
51+
case 'Advanced': return 'bg-orange-100 text-orange-800'
52+
case 'Expert': return 'bg-red-100 text-red-800'
53+
default: return 'bg-slate-100 text-slate-800'
54+
}
55+
}
56+
57+
return (
58+
<div className="pt-20 min-h-screen bg-slate-50">
59+
<div className="max-w-4xl mx-auto px-8 py-12">
60+
<motion.div
61+
initial={{ opacity: 0, y: 20 }}
62+
animate={{ opacity: 1, y: 0 }}
63+
transition={{ duration: 0.5 }}
64+
>
65+
{/* Breadcrumb */}
66+
<nav className="flex items-center gap-2 text-sm text-slate-600 mb-6">
67+
<Link to="/docs" className="hover:text-slate-900">Documentation</Link>
68+
<span>/</span>
69+
<Link to={categoryPath} className="hover:text-slate-900">{category}</Link>
70+
<span>/</span>
71+
<span className="text-slate-900">{title}</span>
72+
</nav>
73+
74+
{/* Back Button */}
75+
<Link
76+
to={categoryPath}
77+
className="inline-flex items-center gap-2 text-sm text-slate-600 hover:text-slate-900 mb-8"
78+
>
79+
<ArrowLeft className="w-4 h-4" />
80+
Back to {category}
81+
</Link>
82+
83+
{/* Header */}
84+
<div className="bg-white rounded-xl border border-slate-200 p-8 mb-8">
85+
<h1 className="text-3xl font-bold text-slate-900 mb-4">{title}</h1>
86+
<p className="text-lg text-slate-600 mb-6">{description}</p>
87+
88+
<div className="flex flex-wrap gap-4 mb-6">
89+
<div className="flex items-center gap-2">
90+
<BarChart3 className="w-4 h-4 text-slate-500" />
91+
<span className={`px-2 py-1 rounded-full text-xs font-medium ${getLevelColor(level)}`}>
92+
{level}
93+
</span>
94+
</div>
95+
<div className="flex items-center gap-2 text-slate-600">
96+
<Clock className="w-4 h-4" />
97+
<span className="text-sm">{time}</span>
98+
</div>
99+
</div>
100+
101+
<div className="prose prose-slate max-w-none">
102+
<h3 className="text-lg font-semibold text-slate-900 mb-3">Overview</h3>
103+
<p className="text-slate-600">{overview}</p>
104+
</div>
105+
</div>
106+
107+
{/* Prerequisites */}
108+
{prerequisites.length > 0 && (
109+
<div className="bg-blue-50 border border-blue-200 rounded-xl p-6 mb-8">
110+
<h3 className="text-lg font-semibold text-blue-900 mb-4 flex items-center gap-2">
111+
<CheckCircle className="w-5 h-5" />
112+
Prerequisites
113+
</h3>
114+
<ul className="space-y-2">
115+
{prerequisites.map((prereq, index) => (
116+
<li key={index} className="text-blue-800 flex items-start gap-2">
117+
<span className="w-1.5 h-1.5 bg-blue-500 rounded-full mt-2 flex-shrink-0" />
118+
{prereq}
119+
</li>
120+
))}
121+
</ul>
122+
</div>
123+
)}
124+
125+
{/* Steps */}
126+
<div className="space-y-8">
127+
{steps.map((step, index) => (
128+
<motion.div
129+
key={index}
130+
initial={{ opacity: 0, y: 20 }}
131+
animate={{ opacity: 1, y: 0 }}
132+
transition={{ duration: 0.5, delay: index * 0.1 }}
133+
className="bg-white rounded-xl border border-slate-200 p-8"
134+
>
135+
<div className="flex items-start gap-4 mb-6">
136+
<div className="flex-shrink-0 w-8 h-8 bg-purple-100 text-purple-600 rounded-full flex items-center justify-center font-semibold">
137+
{index + 1}
138+
</div>
139+
<div className="flex-1">
140+
<h3 className="text-xl font-semibold text-slate-900 mb-2">{step.title}</h3>
141+
<p className="text-slate-600">{step.description}</p>
142+
</div>
143+
</div>
144+
145+
{step.code && (
146+
<div className="mb-6">
147+
<div className="flex items-center justify-between mb-3">
148+
<h4 className="text-sm font-medium text-slate-900">
149+
{step.language || 'Code'}
150+
</h4>
151+
<CopyButton text={step.code} />
152+
</div>
153+
<div className="bg-slate-900 rounded-lg p-4 overflow-x-auto">
154+
<pre className="text-sm text-slate-100">
155+
<code>{step.code}</code>
156+
</pre>
157+
</div>
158+
</div>
159+
)}
160+
161+
{step.notes && step.notes.length > 0 && (
162+
<div className="bg-amber-50 border border-amber-200 rounded-lg p-4">
163+
<h4 className="text-sm font-medium text-amber-900 mb-2">Important Notes:</h4>
164+
<ul className="space-y-1">
165+
{step.notes.map((note, noteIndex) => (
166+
<li key={noteIndex} className="text-amber-800 text-sm flex items-start gap-2">
167+
<span className="w-1 h-1 bg-amber-500 rounded-full mt-2 flex-shrink-0" />
168+
{note}
169+
</li>
170+
))}
171+
</ul>
172+
</div>
173+
)}
174+
</motion.div>
175+
))}
176+
</div>
177+
178+
{/* Conclusion */}
179+
{conclusion && (
180+
<div className="bg-green-50 border border-green-200 rounded-xl p-6 mt-8">
181+
<h3 className="text-lg font-semibold text-green-900 mb-3">Conclusion</h3>
182+
<p className="text-green-800">{conclusion}</p>
183+
</div>
184+
)}
185+
186+
{/* Next Steps */}
187+
{nextSteps.length > 0 && (
188+
<div className="bg-purple-50 border border-purple-200 rounded-xl p-6 mt-8">
189+
<h3 className="text-lg font-semibold text-purple-900 mb-4">Next Steps</h3>
190+
<ul className="space-y-2">
191+
{nextSteps.map((step, index) => (
192+
<li key={index} className="text-purple-800 flex items-start gap-2">
193+
<span className="w-1.5 h-1.5 bg-purple-500 rounded-full mt-2 flex-shrink-0" />
194+
{step}
195+
</li>
196+
))}
197+
</ul>
198+
</div>
199+
)}
200+
201+
{/* Related Tutorials */}
202+
{relatedTutorials.length > 0 && (
203+
<div className="bg-white rounded-xl border border-slate-200 p-6 mt-8">
204+
<h3 className="text-lg font-semibold text-slate-900 mb-4">Related Tutorials</h3>
205+
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
206+
{relatedTutorials.map((tutorial, index) => (
207+
<Link
208+
key={index}
209+
to={tutorial.path}
210+
className="block p-4 bg-slate-50 rounded-lg hover:bg-slate-100 transition-colors"
211+
>
212+
<span className="text-slate-900 font-medium">{tutorial.title}</span>
213+
</Link>
214+
))}
215+
</div>
216+
</div>
217+
)}
218+
</motion.div>
219+
</div>
220+
</div>
221+
)
222+
}

website/src/pages/DocsPage.tsx

Lines changed: 66 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,20 @@ import {
2323
MobileTutorials
2424
} from '../components/AdvancedTutorialSections'
2525

26+
// Import individual tutorial components
27+
import {
28+
OnlineStoreIntegrationTutorial,
29+
MarketplaceEscrowTutorial
30+
} from './tutorials/EcommerceTutorials'
31+
import {
32+
InGameCurrencyTutorial,
33+
NFTMarketplaceTutorial
34+
} from './tutorials/GamingTutorials'
35+
import {
36+
SaaSSubscriptionBillingTutorial,
37+
FreelancePaymentEscrowTutorial
38+
} from './tutorials/SaaSTutorials'
39+
2640
// Documentation sections
2741
const sections = [
2842
{
@@ -34,16 +48,43 @@ const sections = [
3448
]
3549
},
3650
{
37-
title: 'Tutorials',
51+
title: 'E-commerce Tutorials',
52+
items: [
53+
{ name: 'Online Store Integration', href: '/docs/tutorials/ecommerce/online-store', icon: Book },
54+
{ name: 'Marketplace with Escrow', href: '/docs/tutorials/ecommerce/marketplace-escrow', icon: Book },
55+
{ name: 'Subscription Box Service', href: '/docs/tutorials/ecommerce/subscription-box', icon: Book },
56+
{ name: 'Digital Product Store', href: '/docs/tutorials/ecommerce/digital-products', icon: Book },
57+
{ name: 'Flash Sale Management', href: '/docs/tutorials/ecommerce/flash-sales', icon: Book },
58+
]
59+
},
60+
{
61+
title: 'Gaming & NFT Tutorials',
62+
items: [
63+
{ name: 'In-Game Currency Exchange', href: '/docs/tutorials/gaming/currency-exchange', icon: Book },
64+
{ name: 'NFT Marketplace for Games', href: '/docs/tutorials/gaming/nft-marketplace', icon: Book },
65+
{ name: 'Tournament Prize Distribution', href: '/docs/tutorials/gaming/tournament-prizes', icon: Book },
66+
{ name: 'Play-to-Earn Rewards', href: '/docs/tutorials/gaming/play-to-earn', icon: Book },
67+
{ name: 'Game Asset Rental System', href: '/docs/tutorials/gaming/asset-rental', icon: Book },
68+
]
69+
},
70+
{
71+
title: 'SaaS & Service Tutorials',
3872
items: [
39-
{ name: 'E-commerce Tutorials', href: '/docs/tutorials/ecommerce', icon: Book },
40-
{ name: 'Gaming & NFT Tutorials', href: '/docs/tutorials/gaming', icon: Book },
41-
{ name: 'DeFi Integration Tutorials', href: '/docs/tutorials/defi', icon: Book },
42-
{ name: 'SaaS & Service Tutorials', href: '/docs/tutorials/saas', icon: Book },
43-
{ name: 'Creator & Social Tutorials', href: '/docs/tutorials/social', icon: Book },
44-
{ name: 'Enterprise Tutorials', href: '/docs/tutorials/enterprise', icon: Book },
45-
{ name: 'Cross-Chain Tutorials', href: '/docs/tutorials/cross-chain', icon: Book },
46-
{ name: 'Mobile & IoT Tutorials', href: '/docs/tutorials/mobile', icon: Book },
73+
{ name: 'SaaS Subscription Billing', href: '/docs/tutorials/saas/subscription-billing', icon: Book },
74+
{ name: 'Freelance Payment Escrow', href: '/docs/tutorials/saas/freelance-escrow', icon: Book },
75+
{ name: 'Consulting Time Tracking', href: '/docs/tutorials/saas/time-tracking', icon: Book },
76+
{ name: 'API Usage Billing', href: '/docs/tutorials/saas/api-billing', icon: Book },
77+
{ name: 'Software License Management', href: '/docs/tutorials/saas/license-management', icon: Book },
78+
]
79+
},
80+
{
81+
title: 'DeFi & Finance Tutorials',
82+
items: [
83+
{ name: 'Yield Farming Rewards', href: '/docs/tutorials/defi/yield-farming', icon: Book },
84+
{ name: 'Cross-Chain Arbitrage Bot', href: '/docs/tutorials/defi/arbitrage-bot', icon: Book },
85+
{ name: 'Lending Protocol Integration', href: '/docs/tutorials/defi/lending-protocol', icon: Book },
86+
{ name: 'DEX Trading Fee Distribution', href: '/docs/tutorials/defi/dex-fees', icon: Book },
87+
{ name: 'Automated Market Maker', href: '/docs/tutorials/defi/amm', icon: Book },
4788
]
4889
},
4990
{
@@ -178,14 +219,29 @@ export function DocsPage() {
178219
<Route path="/developer-guide" element={<DeveloperGuideDoc />} />
179220
<Route path="/api" element={<ApiDoc />} />
180221
<Route path="/cli" element={<CliDoc />} />
222+
223+
{/* E-commerce Tutorials */}
181224
<Route path="/tutorials/ecommerce" element={<EcommerceTutorials />} />
225+
<Route path="/tutorials/ecommerce/online-store" element={<OnlineStoreIntegrationTutorial />} />
226+
<Route path="/tutorials/ecommerce/marketplace-escrow" element={<MarketplaceEscrowTutorial />} />
227+
228+
{/* Gaming Tutorials */}
182229
<Route path="/tutorials/gaming" element={<GamingTutorials />} />
183-
<Route path="/tutorials/defi" element={<DeFiTutorials />} />
230+
<Route path="/tutorials/gaming/currency-exchange" element={<InGameCurrencyTutorial />} />
231+
<Route path="/tutorials/gaming/nft-marketplace" element={<NFTMarketplaceTutorial />} />
232+
233+
{/* SaaS Tutorials */}
184234
<Route path="/tutorials/saas" element={<SaaSTutorials />} />
235+
<Route path="/tutorials/saas/subscription-billing" element={<SaaSSubscriptionBillingTutorial />} />
236+
<Route path="/tutorials/saas/freelance-escrow" element={<FreelancePaymentEscrowTutorial />} />
237+
238+
{/* Other category pages */}
239+
<Route path="/tutorials/defi" element={<DeFiTutorials />} />
185240
<Route path="/tutorials/social" element={<SocialTutorials />} />
186241
<Route path="/tutorials/enterprise" element={<EnterpriseTutorials />} />
187242
<Route path="/tutorials/cross-chain" element={<CrossChainTutorials />} />
188243
<Route path="/tutorials/mobile" element={<MobileTutorials />} />
244+
189245
<Route path="/cross-chain" element={<CrossChainDoc />} />
190246
<Route path="/architecture" element={<ArchitectureDoc />} />
191247
<Route path="/security" element={<SecurityDoc />} />

0 commit comments

Comments
 (0)