Skip to content

Commit 68285df

Browse files
committed
feat: restructure guidelines with dedicated pages
- Replace cluttered guidelines section with 3 clean cards - Create dedicated pages for each guideline subsection: - /product/UX-patterns: Full interaction patterns accordion with best practices - /product/visual-patterns: Visual design principles and patterns - /product/integration-workflow: Workflow processes and handoff guidelines - Guidelines cards features: - Hover effects with primary color transitions - Clickable navigation to dedicated pages - Feature tags showing what's inside each section - Clean, organized layout with proper spacing - Each dedicated page includes: - Back navigation to guidelines - Full content from original subsections - Consistent header and footer - Responsive design and animations - Coming soon sections for future content - Improved user experience: - Less cluttered main guidelines page - Better content organization - Easier navigation between related content - Cleaner visual hierarchy
1 parent 7d0d152 commit 68285df

File tree

4 files changed

+692
-374
lines changed

4 files changed

+692
-374
lines changed
Lines changed: 331 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,331 @@
1+
'use client';
2+
3+
import { useState } from 'react';
4+
import { motion, AnimatePresence } from 'framer-motion';
5+
import { useLanguage } from '@/contexts/LanguageContext';
6+
import { MousePointer, Palette, Zap, Smartphone, ChevronDown, CheckCircle, XCircle, ArrowLeft } from 'lucide-react';
7+
import { useRouter } from 'next/navigation';
8+
import Header from '@/components/layout/Header';
9+
import Footer from '@/components/layout/Footer';
10+
11+
const UXPatternsPage = () => {
12+
const { t } = useLanguage();
13+
const router = useRouter();
14+
const [openPattern, setOpenPattern] = useState<string | null>(null);
15+
16+
const handlePatternToggle = (patternId: string) => {
17+
setOpenPattern(openPattern === patternId ? null : patternId);
18+
};
19+
20+
const interactionPatterns = [
21+
{
22+
id: 'onLoad',
23+
title: 'While loading',
24+
description: t('product.guidelines.interactionPatterns.onLoad.description'),
25+
tags: ['Skeleton UI', 'Loading states']
26+
},
27+
{
28+
id: 'onScroll',
29+
title: 'Page Scroll',
30+
description: t('product.guidelines.interactionPatterns.onScroll.description'),
31+
tags: ['Vertical scroll', 'Primary interaction']
32+
},
33+
{
34+
id: 'notify',
35+
title: 'Notify',
36+
description: t('product.guidelines.interactionPatterns.notify.description'),
37+
tags: ['Toast', 'Banner']
38+
},
39+
{
40+
id: 'alert',
41+
title: 'Alert',
42+
description: t('product.guidelines.interactionPatterns.alert.description'),
43+
tags: ['Toast', 'Urgent notification']
44+
},
45+
{
46+
id: 'pauseAsk',
47+
title: 'Pause & Ask',
48+
description: t('product.guidelines.interactionPatterns.pauseAsk.description'),
49+
tags: ['Popup', 'Modal']
50+
},
51+
{
52+
id: 'magnify',
53+
title: 'Magnify',
54+
description: t('product.guidelines.interactionPatterns.magnify.description'),
55+
tags: ['Bottomsheet', 'Expandable content']
56+
},
57+
{
58+
id: 'screenToScreen',
59+
title: 'Screen to Screen',
60+
description: t('product.guidelines.interactionPatterns.screenToScreen.description'),
61+
tags: ['Navigation', 'Transitions']
62+
},
63+
{
64+
id: 'feedback',
65+
title: 'Feedback',
66+
description: t('product.guidelines.interactionPatterns.feedback.description'),
67+
tags: ['Touch', 'Swipe', 'Haptic']
68+
},
69+
{
70+
id: 'moreToCome',
71+
title: 'More to come',
72+
description: t('product.guidelines.interactionPatterns.moreToCome.description'),
73+
tags: ['Future patterns']
74+
}
75+
];
76+
77+
const subsections = [
78+
{
79+
id: 'interaction-patterns',
80+
icon: MousePointer,
81+
title: t('product.guidelines.interactionPatterns.title'),
82+
subtitle: t('product.guidelines.interactionPatterns.subtitle'),
83+
description: t('product.guidelines.interactionPatterns.description')
84+
},
85+
{
86+
id: 'ui-kit',
87+
icon: Palette,
88+
title: t('product.guidelines.uiKit.title'),
89+
subtitle: t('product.guidelines.uiKit.subtitle'),
90+
description: t('product.guidelines.uiKit.description'),
91+
structure: [
92+
t('product.guidelines.uiKit.atoms'),
93+
t('product.guidelines.uiKit.modules'),
94+
t('product.guidelines.uiKit.views')
95+
]
96+
},
97+
{
98+
id: 'micro-interaction-patterns',
99+
icon: Zap,
100+
title: t('product.guidelines.microInteractionPatterns.title'),
101+
subtitle: t('product.guidelines.microInteractionPatterns.subtitle'),
102+
description: t('product.guidelines.microInteractionPatterns.description'),
103+
patterns: [
104+
t('product.guidelines.microInteractionPatterns.livingIcons'),
105+
t('product.guidelines.microInteractionPatterns.emphasisOn'),
106+
t('product.guidelines.microInteractionPatterns.rewardDelights'),
107+
t('product.guidelines.microInteractionPatterns.moreToCome')
108+
]
109+
}
110+
];
111+
112+
return (
113+
<main className="min-h-screen relative">
114+
<Header />
115+
116+
{/* Back Button */}
117+
<div className="pt-20 px-4 sm:px-6 lg:px-8">
118+
<div className="max-w-7xl mx-auto">
119+
<motion.button
120+
onClick={() => router.back()}
121+
className="flex items-center space-x-2 text-muted-foreground hover:text-white transition-colors mb-8"
122+
whileHover={{ x: -4 }}
123+
>
124+
<ArrowLeft className="w-4 h-4" />
125+
<span>Back to Guidelines</span>
126+
</motion.button>
127+
</div>
128+
</div>
129+
130+
<section className="py-20 px-4 sm:px-6 lg:px-8">
131+
<div className="max-w-7xl mx-auto">
132+
{/* Section Header */}
133+
<motion.div
134+
initial={{ opacity: 0, y: 30 }}
135+
whileInView={{ opacity: 1, y: 0 }}
136+
transition={{ duration: 0.6 }}
137+
viewport={{ once: true }}
138+
className="text-center mb-16"
139+
>
140+
<h1 className="text-3xl sm:text-4xl lg:text-5xl font-bold mb-4 bg-gradient-to-r from-foreground to-muted-foreground bg-clip-text text-transparent">
141+
{t('product.guidelines.uxPatterns.title')}
142+
</h1>
143+
<p className="text-xl text-muted-foreground max-w-4xl mx-auto leading-relaxed">
144+
{t('product.guidelines.uxPatterns.description')}
145+
</p>
146+
</motion.div>
147+
148+
{/* Subsections */}
149+
<div className="space-y-20">
150+
{subsections.map((subsection, sectionIndex) => (
151+
<motion.div
152+
key={subsection.id}
153+
initial={{ opacity: 0, y: 30 }}
154+
whileInView={{ opacity: 1, y: 0 }}
155+
transition={{ duration: 0.6, delay: sectionIndex * 0.2 }}
156+
viewport={{ once: true }}
157+
className="bg-gradient-to-br from-background to-muted/20 rounded-2xl border border-border p-8 lg:p-12 shadow-2xl"
158+
>
159+
{/* Subsection Header */}
160+
<div className="flex items-start space-x-6 mb-8">
161+
<div className="w-16 h-16 rounded-xl bg-primary/10 flex items-center justify-center flex-shrink-0">
162+
<subsection.icon className="w-8 h-8 text-white" />
163+
</div>
164+
<div className="flex-1">
165+
<h2 className="text-2xl lg:text-3xl font-bold text-white mb-2">
166+
{subsection.title}
167+
</h2>
168+
<p className="text-lg text-muted-foreground font-medium mb-4">
169+
{subsection.subtitle}
170+
</p>
171+
<p className="text-muted-foreground leading-relaxed">
172+
{subsection.description}
173+
</p>
174+
</div>
175+
</div>
176+
177+
{/* Content */}
178+
{subsection.id === 'interaction-patterns' ? (
179+
// Special accordion UI for Interaction Patterns
180+
<div className="space-y-4">
181+
{/* Best Practices & Dark Patterns */}
182+
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-8">
183+
{/* Best Practices */}
184+
<div className="bg-gradient-to-br from-green-500/10 to-green-600/5 border border-green-500/20 rounded-xl p-6">
185+
<div className="flex items-center space-x-3 mb-4">
186+
<CheckCircle className="w-5 h-5 text-green-400" />
187+
<h3 className="text-lg font-semibold text-white">
188+
{t('product.guidelines.interactionPatterns.bestPractices')}
189+
</h3>
190+
</div>
191+
<div className="text-muted-foreground leading-relaxed whitespace-pre-line text-sm">
192+
{t('product.guidelines.interactionPatterns.bestPractices.content')}
193+
</div>
194+
</div>
195+
196+
{/* Dark Patterns */}
197+
<div className="bg-gradient-to-br from-red-500/10 to-red-600/5 border border-red-500/20 rounded-xl p-6">
198+
<div className="flex items-center space-x-3 mb-4">
199+
<XCircle className="w-5 h-5 text-red-400" />
200+
<h3 className="text-lg font-semibold text-white">
201+
{t('product.guidelines.interactionPatterns.darkPatterns')}
202+
</h3>
203+
</div>
204+
<div className="text-muted-foreground leading-relaxed whitespace-pre-line text-sm">
205+
{t('product.guidelines.interactionPatterns.darkPatterns.content')}
206+
</div>
207+
</div>
208+
</div>
209+
210+
{/* Patterns Accordion */}
211+
<div className="space-y-3">
212+
{interactionPatterns.map((pattern, patternIndex) => (
213+
<motion.div
214+
key={pattern.id}
215+
initial={{ opacity: 0, y: 20 }}
216+
whileInView={{ opacity: 1, y: 0 }}
217+
transition={{ duration: 0.4, delay: patternIndex * 0.05 }}
218+
viewport={{ once: true }}
219+
className="bg-gradient-to-br from-background to-muted/20 border border-border rounded-xl overflow-hidden"
220+
>
221+
{/* Pattern Header */}
222+
<button
223+
onClick={() => handlePatternToggle(pattern.id)}
224+
className="w-full p-4 text-left flex items-center justify-between hover:bg-muted/10 transition-colors"
225+
>
226+
<div className="flex-1">
227+
<h4 className="text-base font-semibold text-white">
228+
{pattern.title}
229+
</h4>
230+
</div>
231+
<motion.div
232+
animate={{ rotate: openPattern === pattern.id ? 180 : 0 }}
233+
transition={{ duration: 0.3 }}
234+
>
235+
<ChevronDown className="w-4 h-4 text-muted-foreground" />
236+
</motion.div>
237+
</button>
238+
239+
{/* Pattern Content */}
240+
<AnimatePresence>
241+
{openPattern === pattern.id && (
242+
<motion.div
243+
initial={{ height: 0, opacity: 0 }}
244+
animate={{ height: 'auto', opacity: 1 }}
245+
exit={{ height: 0, opacity: 0 }}
246+
transition={{ duration: 0.3, ease: 'easeInOut' }}
247+
className="overflow-hidden"
248+
>
249+
<div className="px-4 pb-4">
250+
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
251+
{/* Description */}
252+
<div className="space-y-3">
253+
<h5 className="text-sm font-medium text-white">
254+
Description
255+
</h5>
256+
<p className="text-muted-foreground leading-relaxed text-sm">
257+
{pattern.description}
258+
</p>
259+
260+
{/* Tags */}
261+
<div className="flex flex-wrap gap-2 mt-3">
262+
{pattern.tags.map((tag, tagIndex) => (
263+
<span
264+
key={tagIndex}
265+
className="px-2 py-1 bg-primary/20 text-primary text-xs rounded-full border border-primary/30"
266+
>
267+
{tag}
268+
</span>
269+
))}
270+
</div>
271+
</div>
272+
273+
{/* Live Preview */}
274+
<div className="space-y-3">
275+
<h5 className="text-sm font-medium text-white">
276+
Live Preview
277+
</h5>
278+
<div className="relative">
279+
{/* Mobile Frame with 16:9 ratio */}
280+
<div className="w-full max-w-[280px] mx-auto bg-black rounded-[1.5rem] p-1 shadow-2xl">
281+
<div className="bg-muted/20 rounded-[1.25rem] h-[157px] flex items-center justify-center" style={{ aspectRatio: '16/9' }}>
282+
<div className="text-center space-y-2 px-4">
283+
<Smartphone className="w-6 h-6 text-muted-foreground mx-auto" />
284+
<p className="text-xs sm:text-sm text-muted-foreground break-words">
285+
{pattern.title}
286+
</p>
287+
<p className="text-xs text-muted-foreground/70">
288+
Preview coming soon
289+
</p>
290+
</div>
291+
</div>
292+
</div>
293+
</div>
294+
</div>
295+
</div>
296+
</div>
297+
</motion.div>
298+
)}
299+
</AnimatePresence>
300+
</motion.div>
301+
))}
302+
</div>
303+
</div>
304+
) : (
305+
// Regular grid for other subsections
306+
<div className="grid grid-cols-1 md:grid-cols-2 gap-3">
307+
{(subsection.patterns || subsection.structure || []).map((item: string, itemIndex: number) => (
308+
<div
309+
key={itemIndex}
310+
className="flex items-start space-x-3 p-3 bg-muted/30 rounded-lg"
311+
>
312+
<div className="w-1.5 h-1.5 rounded-full bg-primary mt-2 flex-shrink-0" />
313+
<p className="text-muted-foreground text-sm leading-relaxed">
314+
{item}
315+
</p>
316+
</div>
317+
))}
318+
</div>
319+
)}
320+
</motion.div>
321+
))}
322+
</div>
323+
</div>
324+
</section>
325+
326+
<Footer />
327+
</main>
328+
);
329+
};
330+
331+
export default UXPatternsPage;

0 commit comments

Comments
 (0)