11import React , { useState } from 'react' ;
22import { Link } from 'react-router-dom' ;
3- import { ArrowLeftIcon , ArticleIcon } from '@phosphor-icons/react' ;
4- import colors from '../../config/colors' ;
3+ import { AnimatePresence , motion } from 'framer-motion' ;
4+ import {
5+ ArrowLeftIcon ,
6+ ArticleIcon ,
7+ ArrowsClockwiseIcon ,
8+ CopySimpleIcon ,
9+ TextTIcon ,
10+ ToggleLeftIcon ,
11+ ToggleRightIcon ,
12+ } from '@phosphor-icons/react' ;
513import useSeo from '../../hooks/useSeo' ;
614import { useToast } from '../../hooks/useToast' ;
715import BreadcrumbTitle from '../../components/BreadcrumbTitle' ;
16+ import GenerativeArt from '../../components/GenerativeArt' ;
817
918const LOREM_WORDS = [
1019 'lorem' ,
@@ -79,8 +88,10 @@ const LOREM_WORDS = [
7988] ;
8089
8190const LoremIpsumGeneratorPage = ( ) => {
91+ const appName = 'Lorem Ipsum Generator' ;
92+
8293 useSeo ( {
83- title : 'Lorem Ipsum Generator | Fezcodex' ,
94+ title : ` ${ appName } | Fezcodex` ,
8495 description : 'Generate random placeholder text for your projects.' ,
8596 keywords : [
8697 'Fezcodex' ,
@@ -89,12 +100,6 @@ const LoremIpsumGeneratorPage = () => {
89100 'placeholder text' ,
90101 'dummy text' ,
91102 ] ,
92- ogTitle : 'Lorem Ipsum Generator | Fezcodex' ,
93- ogDescription : 'Generate placeholder text for your projects and designs.' ,
94- twitterCard : 'summary_large_image' ,
95- twitterTitle : 'Lorem Ipsum Generator | Fezcodex' ,
96- twitterDescription :
97- 'Generate placeholder text for your projects and designs.' ,
98103 } ) ;
99104
100105 const { addToast } = useToast ( ) ;
@@ -147,104 +152,179 @@ const LoremIpsumGeneratorPage = () => {
147152 const copyToClipboard = ( ) => {
148153 navigator . clipboard . writeText ( generatedText ) . then ( ( ) => {
149154 addToast ( {
150- title : 'Copied!' ,
151- message : 'Text copied to clipboard.' ,
152- duration : 2000 ,
155+ title : 'Copied' ,
156+ message : 'Placeholder text stored in clipboard.' ,
153157 } ) ;
154158 } ) ;
155159 } ;
156160
157- const cardStyle = {
158- backgroundColor : colors [ 'app-alpha-10' ] ,
159- borderColor : colors [ 'app-alpha-50' ] ,
160- color : colors . app ,
161- } ;
162-
163161 return (
164- < div className = "py-16 sm:py-24" >
165- < div className = "mx-auto max-w-7xl px-6 lg:px-8 text-gray-300" >
166- < Link
167- to = "/apps"
168- className = "group text-primary-400 hover:underline flex items-center justify-center gap-2 text-lg mb-4"
169- >
170- < ArrowLeftIcon className = "text-xl transition-transform group-hover:-translate-x-1" /> { ' ' }
171- Back to Apps
172- </ Link >
173- < BreadcrumbTitle title = "Lorem Ipsum Generator" slug = "lorem" />
174- < hr className = "border-gray-700" />
175- < div className = "flex justify-center items-center mt-16" >
176- < div
177- className = "group bg-transparent border rounded-lg shadow-2xl p-6 flex flex-col justify-between relative transform overflow-hidden h-full w-full max-w-4xl"
178- style = { cardStyle }
162+ < div className = "min-h-screen bg-[#050505] text-white selection:bg-emerald-500/30 font-sans" >
163+ < div className = "mx-auto max-w-7xl px-6 py-24 md:px-12" >
164+ < header className = "mb-24" >
165+ < Link
166+ to = "/apps"
167+ className = "group mb-12 inline-flex items-center gap-2 text-xs font-mono text-gray-500 hover:text-white transition-colors uppercase tracking-[0.3em]"
179168 >
180- < div
181- className = "absolute top-0 left-0 w-full h-full opacity-10"
182- style = { {
183- backgroundImage :
184- 'radial-gradient(circle, white 1px, transparent 1px)' ,
185- backgroundSize : '10px 10px' ,
186- } }
187- > </ div >
188- < div className = "relative z-10 p-1" >
189- < h1 className = "text-3xl font-arvo font-normal mb-4 text-app flex items-center gap-2" >
190- < ArticleIcon size = { 32 } /> Lorem Ipsum Generator
191- </ h1 >
192- < hr className = "border-gray-700 mb-6" />
193-
194- < div className = "grid grid-cols-1 md:grid-cols-2 gap-6 mb-6" >
195- < div >
196- < label className = "block text-sm font-medium mb-2 opacity-80" >
197- Paragraphs
198- </ label >
199- < input
200- type = "number"
201- min = "1"
202- max = "50"
203- value = { paragraphs }
204- onChange = { ( e ) =>
205- setParagraphs ( parseInt ( e . target . value ) || 1 )
206- }
207- className = "w-full bg-black/20 border border-gray-600 rounded px-3 py-2 focus:outline-none focus:border-blue-500 transition-colors"
208- />
209- </ div >
210- < div className = "flex items-center" >
211- < label className = "flex items-center space-x-3 cursor-pointer mt-6" >
169+ < ArrowLeftIcon
170+ weight = "bold"
171+ className = "transition-transform group-hover:-translate-x-1"
172+ />
173+ < span > Applications</ span >
174+ </ Link >
175+
176+ < div className = "flex flex-col md:flex-row md:items-end justify-between gap-12" >
177+ < div className = "space-y-4" >
178+ < BreadcrumbTitle
179+ title = { appName }
180+ slug = "lorem"
181+ variant = "brutalist"
182+ />
183+ < p className = "text-xl text-gray-400 max-w-2xl font-light leading-relaxed" >
184+ Standardized filler protocol. Generate pseudo-Latin data blocks
185+ for structural layout verification.
186+ </ p >
187+ </ div >
188+ </ div >
189+ </ header >
190+
191+ < div className = "grid grid-cols-1 lg:grid-cols-12 gap-12" >
192+ { /* Main Interaction Area */ }
193+ < div className = "lg:col-span-8 space-y-12" >
194+ < div className = "relative border border-white/10 bg-white/[0.02] p-8 md:p-12 rounded-sm overflow-hidden group" >
195+ < div className = "absolute inset-0 opacity-[0.03] pointer-events-none grayscale" >
196+ < GenerativeArt
197+ seed = { appName + paragraphs }
198+ className = "w-full h-full"
199+ />
200+ </ div >
201+
202+ < div className = "relative z-10 space-y-8" >
203+ < div className = "grid grid-cols-1 md:grid-cols-2 gap-8" >
204+ < div className = "space-y-4" >
205+ < label className = "font-mono text-[10px] text-gray-500 uppercase tracking-widest flex items-center gap-2" >
206+ < TextTIcon weight = "fill" /> Paragraph_Count
207+ </ label >
212208 < input
213- type = "checkbox"
214- checked = { startWithLorem }
215- onChange = { ( e ) => setStartWithLorem ( e . target . checked ) }
216- className = "form-checkbox h-5 w-5 text-blue-600 rounded bg-black/20 border-gray-600"
209+ type = "number"
210+ min = "1"
211+ max = "50"
212+ value = { paragraphs }
213+ onChange = { ( e ) =>
214+ setParagraphs ( parseInt ( e . target . value ) || 1 )
215+ }
216+ className = "w-full bg-black/40 border border-white/10 rounded-sm p-4 font-mono text-xl text-white focus:border-emerald-500/50 outline-none transition-colors"
217217 />
218- < span > Start with "Lorem ipsum..."</ span >
219- </ label >
218+ </ div >
219+
220+ < div className = "space-y-4" >
221+ < label className = "font-mono text-[10px] text-gray-500 uppercase tracking-widest flex items-center gap-2" >
222+ Standard_Prefix
223+ </ label >
224+ < button
225+ onClick = { ( ) => setStartWithLorem ( ! startWithLorem ) }
226+ className = { `w-full p-4 border rounded-sm flex items-center justify-between transition-all ${
227+ startWithLorem
228+ ? 'bg-emerald-500/10 border-emerald-500 text-emerald-500'
229+ : 'bg-black/40 border-white/10 text-gray-400 hover:border-white/30'
230+ } `}
231+ >
232+ < span className = "font-mono text-xs uppercase tracking-wider" >
233+ Start with "Lorem ipsum..."
234+ </ span >
235+ { startWithLorem ? (
236+ < ToggleRightIcon size = { 24 } weight = "fill" />
237+ ) : (
238+ < ToggleLeftIcon size = { 24 } />
239+ ) }
240+ </ button >
241+ </ div >
220242 </ div >
221- </ div >
222243
223- < div className = "flex justify-end gap-4 mb-6" >
224244 < button
225245 onClick = { generateText }
226- className = "px-6 py-2 rounded-md font-arvo font-normal border transition-colors duration-300 hover:bg-white/10"
227- style = { {
228- borderColor : cardStyle . color ,
229- color : cardStyle . color ,
230- } }
246+ className = "w-full group relative inline-flex items-center justify-center gap-4 px-10 py-6 bg-white text-black hover:bg-emerald-400 transition-all duration-300 font-mono uppercase tracking-widest text-sm font-black rounded-sm"
231247 >
232- Generate
233- </ button >
234- < button
235- onClick = { copyToClipboard }
236- className = "px-6 py-2 rounded-md font-arvo font-normal border transition-colors duration-300 text-blue-500 hover:bg-blue-500 hover:text-white border-blue-500"
237- >
238- Copy
248+ < ArrowsClockwiseIcon
249+ weight = "bold"
250+ size = { 20 }
251+ className = "group-hover:rotate-180 transition-transform duration-500"
252+ />
253+ < span > Generate Sequence</ span >
239254 </ button >
240255 </ div >
256+ </ div >
257+
258+ < AnimatePresence >
259+ { generatedText && (
260+ < motion . div
261+ initial = { { opacity : 0 , y : 20 } }
262+ animate = { { opacity : 1 , y : 0 } }
263+ exit = { { opacity : 0 , y : 20 } }
264+ className = "relative group border border-emerald-500/20 bg-emerald-500/[0.02] p-8 md:p-12 rounded-sm overflow-hidden"
265+ >
266+ < div className = "flex justify-between items-center mb-6 border-b border-emerald-500/10 pb-6" >
267+ < label className = "font-mono text-[10px] text-emerald-500 uppercase tracking-widest font-black flex items-center gap-2" >
268+ < span className = "h-px w-4 bg-emerald-500/20" /> { ' ' }
269+ Output_Stream
270+ </ label >
271+ < button
272+ onClick = { copyToClipboard }
273+ className = "text-emerald-500 hover:text-white transition-colors"
274+ >
275+ < CopySimpleIcon size = { 24 } weight = "bold" />
276+ </ button >
277+ </ div >
278+ < div className = "font-serif text-lg leading-relaxed text-gray-300 whitespace-pre-wrap" >
279+ { generatedText }
280+ </ div >
281+ </ motion . div >
282+ ) }
283+ </ AnimatePresence >
284+ </ div >
241285
242- < div className = "bg-black/30 rounded-lg p-4 min-h-[200px] max-h-[500px] overflow-y-auto font-serif leading-relaxed whitespace-pre-wrap border border-gray-700" >
243- { generatedText }
286+ { /* Sidebar Info */ }
287+ < div className = "lg:col-span-4 space-y-8" >
288+ < div className = "border border-white/10 bg-white/[0.02] p-8 rounded-sm" >
289+ < h3 className = "font-mono text-[10px] font-bold text-emerald-500 uppercase tracking-widest mb-10 flex items-center gap-2" >
290+ < ArticleIcon weight = "fill" />
291+ Generator_Specs
292+ </ h3 >
293+
294+ < div className = "space-y-6" >
295+ < div className = "p-6 border border-white/5 bg-white/[0.01] rounded-sm" >
296+ < span className = "font-mono text-[10px] text-gray-600 uppercase block mb-2" >
297+ Source_Dialect
298+ </ span >
299+ < p className = "text-white font-black uppercase tracking-tight" >
300+ Pseudo-Latin_V1
301+ </ p >
302+ </ div >
303+ < div className = "p-6 border border-white/5 bg-white/[0.01] rounded-sm" >
304+ < span className = "font-mono text-[10px] text-gray-600 uppercase block mb-2" >
305+ Word_Bank_Size
306+ </ span >
307+ < p className = "text-white font-black uppercase tracking-tight" >
308+ { LOREM_WORDS . length } Units
309+ </ p >
310+ </ div >
244311 </ div >
245312 </ div >
313+
314+ < div className = "p-8 border border-white/10 bg-white/[0.01] rounded-sm flex items-start gap-4" >
315+ < TextTIcon size = { 24 } className = "text-gray-700 shrink-0 mt-1" />
316+ < p className = "text-[10px] font-mono uppercase tracking-[0.2em] leading-relaxed text-gray-500" >
317+ Lorem Ipsum is industry-standard dummy text used to demonstrate
318+ the visual form of a document without the distraction of meaningful content.
319+ </ p >
320+ </ div >
246321 </ div >
247322 </ div >
323+
324+ < footer className = "mt-32 pt-12 border-t border-white/10 flex flex-col md:flex-row justify-between items-center gap-6 text-gray-600 font-mono text-[10px] uppercase tracking-[0.3em]" >
325+ < span > Fezcodex_Text_Synthesizer_v2.0</ span >
326+ < span className = "text-gray-800" > STREAM_STATUS // NOMINAL</ span >
327+ </ footer >
248328 </ div >
249329 </ div >
250330 ) ;
0 commit comments