Skip to content

Commit cf6858e

Browse files
committed
refactor: style
1 parent 72e0a7a commit cf6858e

File tree

5 files changed

+200
-103
lines changed

5 files changed

+200
-103
lines changed

public/apps/apps.json

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -346,6 +346,14 @@
346346
"icon": "MagicWandIcon",
347347
"order": 3,
348348
"apps": [
349+
{
350+
"slug": "og-image-generator",
351+
"to": "/apps/og-image-generator",
352+
"title": "OG Image Generator",
353+
"description": "Generate open graph images for your posts with generative art.",
354+
"icon": "ImageSquareIcon",
355+
"created_at": "2025-12-22T12:00:00+03:00"
356+
},
349357
{
350358
"slug": "fractal-flora",
351359
"to": "/apps/fractal-flora",
@@ -454,14 +462,6 @@
454462
"description": "Generate CRON expressions visually and convert human-readable text to CRON.",
455463
"icon": "ClockIcon",
456464
"created_at": "2025-11-18T03:40:32+03:00"
457-
},
458-
{
459-
"slug": "og-image-generator",
460-
"to": "/apps/og-image-generator",
461-
"title": "OG Image Generator",
462-
"description": "Generate open graph images for your posts with generative art.",
463-
"icon": "ImageSquareIcon",
464-
"created_at": "2025-12-22T12:00:00+03:00"
465465
}
466466
]
467467
},

src/components/AnimatedRoutes.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -904,6 +904,10 @@ const AnimatedRoutes = ({
904904
path="/apps::se"
905905
element={<Navigate to="/apps/sprite-editor" replace />}
906906
/>
907+
<Route
908+
path="/apps::og-gen"
909+
element={<Navigate to="/apps/og-image-generator" replace />}
910+
/>
907911
{/* End of hardcoded redirects */}
908912
<Route
909913
path="/apps/ip"

src/pages/apps/BananaConverterPage.js

Lines changed: 171 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,37 @@
11
import React, { useState } from 'react';
22
import { Link } from 'react-router-dom';
3-
import { ArrowLeftIcon, PlantIcon } from '@phosphor-icons/react';
4-
import colors from '../../config/colors';
3+
import { AnimatePresence, motion } from 'framer-motion';
4+
import {
5+
ArrowLeftIcon,
6+
PlantIcon,
7+
ArrowsClockwiseIcon,
8+
RulerIcon,
9+
ScalesIcon,
10+
CalculatorIcon,
11+
} from '@phosphor-icons/react';
512
import useSeo from '../../hooks/useSeo';
6-
import CustomDropdown from '../../components/CustomDropdown'; // Import CustomDropdown
713
import BreadcrumbTitle from '../../components/BreadcrumbTitle';
14+
import GenerativeArt from '../../components/GenerativeArt';
815

916
const BANANA_LENGTH_CM = 18; // Average banana length
1017
const BANANA_WEIGHT_G = 120; // Average banana weight
1118

1219
const unitOptions = [
13-
{ label: 'cm', value: 'cm' },
14-
{ label: 'm', value: 'm' },
15-
{ label: 'km', value: 'km' },
16-
{ label: 'in', value: 'in' },
17-
{ label: 'ft', value: 'ft' },
18-
{ label: 'g', value: 'g' },
19-
{ label: 'kg', value: 'kg' },
20-
{ label: 'lb', value: 'lb' },
21-
{ label: 'oz', value: 'oz' },
20+
{ label: 'CM', value: 'cm' },
21+
{ label: 'M', value: 'm' },
22+
{ label: 'KM', value: 'km' },
23+
{ label: 'IN', value: 'in' },
24+
{ label: 'FT', value: 'ft' },
25+
{ label: 'G', value: 'g' },
26+
{ label: 'KG', value: 'kg' },
27+
{ label: 'LB', value: 'lb' },
28+
{ label: 'OZ', value: 'oz' },
2229
];
2330

2431
const BananaConverterPage = () => {
32+
const appName = 'Banana Converter';
2533
useSeo({
26-
title: 'Banana for Scale Converter | Fezcodex',
34+
title: `${appName} | Fezcodex`,
2735
description: 'Convert measuring units into the internet standard: Bananas.',
2836
keywords: [
2937
'Fezcodex',
@@ -32,11 +40,6 @@ const BananaConverterPage = () => {
3240
'fun',
3341
'measurement',
3442
],
35-
ogTitle: 'Banana Converter | Fezcodex',
36-
ogDescription: 'Convert any unit of measurement into bananas.',
37-
twitterCard: 'summary_large_image',
38-
twitterTitle: 'Banana Converter | Fezcodex',
39-
twitterDescription: 'Convert any unit of measurement into bananas.',
4043
});
4144

4245
const [inputValue, setInputValue] = useState('');
@@ -93,81 +96,174 @@ const BananaConverterPage = () => {
9396
}
9497

9598
if (isLength) {
96-
setResult(`${(valInCm / BANANA_LENGTH_CM).toFixed(2)} Bananas long`);
99+
setResult(`${(valInCm / BANANA_LENGTH_CM).toFixed(2)} BANANAS_LONG`);
97100
} else {
98-
setResult(`${(valInG / BANANA_WEIGHT_G).toFixed(2)} Bananas heavy`);
101+
setResult(`${(valInG / BANANA_WEIGHT_G).toFixed(2)} BANANAS_HEAVY`);
99102
}
100103
};
101104

102-
const cardStyle = {
103-
backgroundColor: colors['app-alpha-10'],
104-
borderColor: colors['app-alpha-50'],
105-
color: colors.app,
106-
};
107-
108105
return (
109-
<div className="py-16 sm:py-24">
110-
<div className="mx-auto max-w-7xl px-6 lg:px-8 text-gray-300">
111-
<Link
112-
to="/apps"
113-
className="group text-primary-400 hover:underline flex items-center justify-center gap-2 text-lg mb-4"
114-
>
115-
<ArrowLeftIcon className="text-xl transition-transform group-hover:-translate-x-1" />{' '}
116-
Back to Apps
117-
</Link>
118-
<BreadcrumbTitle title="Banana Converter" slug="banana" />
119-
<hr className="border-gray-700" />
120-
<div className="flex justify-center items-center mt-16">
121-
<div
122-
className="group bg-transparent border rounded-lg shadow-2xl p-6 flex flex-col justify-between relative transform h-full w-full max-w-2xl"
123-
style={cardStyle}
106+
<div className="min-h-screen bg-[#050505] text-white selection:bg-emerald-500/30 font-sans">
107+
<div className="mx-auto max-w-7xl px-6 py-24 md:px-12">
108+
<header className="mb-24">
109+
<Link
110+
to="/apps"
111+
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]"
124112
>
125-
<div
126-
className="absolute top-0 left-0 w-full h-full opacity-10 rounded-lg overflow-hidden"
127-
style={{
128-
backgroundImage:
129-
'radial-gradient(circle, white 1px, transparent 1px)',
130-
backgroundSize: '10px 10px',
131-
}}
132-
></div>
133-
<div className="relative z-10 p-1 text-center">
134-
<h1 className="text-3xl font-arvo font-normal mb-4 text-app flex items-center justify-center gap-2">
135-
<PlantIcon size={32} /> Banana Converter
136-
</h1>
137-
<hr className="border-gray-700 mb-6" />
138-
139-
<div className="flex flex-col gap-4 mb-6">
140-
<div className="flex gap-2">
141-
<input
142-
type="number"
143-
value={inputValue}
144-
onChange={(e) => setInputValue(e.target.value)}
145-
placeholder="Value"
146-
className="w-full bg-black/20 border border-gray-600 rounded px-3 py-2 focus:outline-none focus:border-yellow-500 transition-colors"
147-
/>
148-
<CustomDropdown
149-
options={unitOptions}
150-
value={inputUnit}
151-
onChange={setInputUnit}
152-
label="Unit"
153-
/>
113+
<ArrowLeftIcon
114+
weight="bold"
115+
className="transition-transform group-hover:-translate-x-1"
116+
/>
117+
<span>Applications</span>
118+
</Link>
119+
120+
<div className="flex flex-col md:flex-row md:items-end justify-between gap-12">
121+
<div className="space-y-4">
122+
<BreadcrumbTitle
123+
title={appName}
124+
slug="banana"
125+
variant="brutalist"
126+
/>
127+
<p className="text-xl text-gray-400 max-w-2xl font-light leading-relaxed">
128+
Standardization protocol. Convert arbitrary metric and imperial
129+
units into the universal banana constant.
130+
</p>
131+
</div>
132+
</div>
133+
</header>
134+
135+
<div className="grid grid-cols-1 lg:grid-cols-12 gap-12">
136+
{/* Main Interaction Area */}
137+
<div className="lg:col-span-8 space-y-12">
138+
<div className="relative border border-white/10 bg-white/[0.02] p-8 md:p-12 rounded-sm overflow-hidden group">
139+
<div className="absolute inset-0 opacity-[0.03] pointer-events-none grayscale">
140+
<GenerativeArt
141+
seed={appName + inputValue}
142+
className="w-full h-full"
143+
/>
144+
</div>
145+
146+
<div className="relative z-10 space-y-12">
147+
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
148+
<div className="space-y-4">
149+
<label className="font-mono text-[10px] text-gray-500 uppercase tracking-widest flex items-center gap-2">
150+
<RulerIcon weight="fill" /> Input_Value
151+
</label>
152+
<input
153+
type="number"
154+
value={inputValue}
155+
onChange={(e) => setInputValue(e.target.value)}
156+
placeholder="0.00"
157+
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"
158+
/>
159+
</div>
160+
161+
<div className="space-y-4">
162+
<label className="font-mono text-[10px] text-gray-500 uppercase tracking-widest flex items-center gap-2">
163+
<ScalesIcon weight="fill" /> Unit_Type
164+
</label>
165+
<div className="grid grid-cols-3 gap-2">
166+
{unitOptions.map((opt) => (
167+
<button
168+
key={opt.value}
169+
onClick={() => setInputUnit(opt.value)}
170+
className={`py-2 text-[10px] font-mono uppercase tracking-wider border transition-all ${
171+
inputUnit === opt.value
172+
? 'bg-emerald-500/10 border-emerald-500 text-emerald-500'
173+
: 'bg-black/40 border-white/10 text-gray-400 hover:border-white/30'
174+
}`}
175+
>
176+
{opt.label}
177+
</button>
178+
))}
179+
</div>
180+
</div>
154181
</div>
182+
155183
<button
156184
onClick={handleConvert}
157-
className="px-6 py-2 rounded-md font-arvo font-normal border transition-colors duration-300 hover:bg-yellow-500/20 text-yellow-500 border-yellow-500"
185+
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"
158186
>
159-
Scale It!
187+
<ArrowsClockwiseIcon
188+
weight="bold"
189+
size={20}
190+
className="group-hover:rotate-180 transition-transform duration-500"
191+
/>
192+
<span>Compute Scale</span>
160193
</button>
161194
</div>
195+
</div>
162196

197+
<AnimatePresence>
163198
{result && (
164-
<div className="text-3xl font-bold text-yellow-400 animate-pulse">
165-
{result} 🍌
166-
</div>
199+
<motion.div
200+
initial={{ opacity: 0, y: 20 }}
201+
animate={{ opacity: 1, y: 0 }}
202+
exit={{ opacity: 0, y: 20 }}
203+
className="relative group border border-emerald-500/20 bg-emerald-500/[0.02] p-8 md:p-12 rounded-sm overflow-hidden"
204+
>
205+
<div className="flex justify-between items-center mb-6 border-b border-emerald-500/10 pb-6">
206+
<label className="font-mono text-[10px] text-emerald-500 uppercase tracking-widest font-black flex items-center gap-2">
207+
<span className="h-px w-4 bg-emerald-500/20" />{' '}
208+
Calculated_Output
209+
</label>
210+
<PlantIcon
211+
size={24}
212+
weight="fill"
213+
className="text-yellow-500"
214+
/>
215+
</div>
216+
<div className="font-mono text-4xl md:text-5xl font-black text-white leading-none tracking-tighter">
217+
{result} 🍌
218+
</div>
219+
</motion.div>
167220
)}
221+
</AnimatePresence>
222+
</div>
223+
224+
{/* Sidebar Info */}
225+
<div className="lg:col-span-4 space-y-8">
226+
<div className="border border-white/10 bg-white/[0.02] p-8 rounded-sm">
227+
<h3 className="font-mono text-[10px] font-bold text-emerald-500 uppercase tracking-widest mb-10 flex items-center gap-2">
228+
<CalculatorIcon weight="fill" />
229+
Conversion_Constants
230+
</h3>
231+
232+
<div className="space-y-6">
233+
<div className="p-6 border border-white/5 bg-white/[0.01] rounded-sm flex justify-between items-center">
234+
<span className="font-mono text-[10px] text-gray-600 uppercase">
235+
Length_Ref
236+
</span>
237+
<p className="text-white font-mono text-xs font-bold uppercase tracking-tight">
238+
{BANANA_LENGTH_CM} CM
239+
</p>
240+
</div>
241+
<div className="p-6 border border-white/5 bg-white/[0.01] rounded-sm flex justify-between items-center">
242+
<span className="font-mono text-[10px] text-gray-600 uppercase">
243+
Mass_Ref
244+
</span>
245+
<p className="text-white font-mono text-xs font-bold uppercase tracking-tight">
246+
{BANANA_WEIGHT_G} G
247+
</p>
248+
</div>
249+
</div>
250+
</div>
251+
252+
<div className="p-8 border border-white/10 bg-white/[0.01] rounded-sm flex items-start gap-4">
253+
<PlantIcon size={24} className="text-gray-700 shrink-0 mt-1" />
254+
<p className="text-[10px] font-mono uppercase tracking-[0.2em] leading-relaxed text-gray-500">
255+
The Banana Standard is the only universally accepted measurement
256+
system for internet-scale visual verification. All calculations
257+
assume a standard cavendish curve topology.
258+
</p>
168259
</div>
169260
</div>
170261
</div>
262+
263+
<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]">
264+
<span>Fezcodex_Scale_Engine_v0.9.4</span>
265+
<span className="text-gray-800">SYSTEM_STATUS // CALIBRATED</span>
266+
</footer>
171267
</div>
172268
</div>
173269
);

src/pages/apps/OgImageGeneratorPage.js

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import html2canvas from 'html2canvas';
1212
import useSeo from '../../hooks/useSeo';
1313
import { useToast } from '../../hooks/useToast';
1414
import GenerativeArt from '../../components/GenerativeArt';
15+
import BreadcrumbTitle from '../../components/BreadcrumbTitle';
1516

1617
const OgImageGeneratorPage = () => {
1718
const appName = 'OG Image Generator';
@@ -82,24 +83,21 @@ const OgImageGeneratorPage = () => {
8283
<div className="min-h-screen bg-[#050505] text-white selection:bg-emerald-500/30 font-sans">
8384
<div className="mx-auto max-w-7xl px-6 py-24 md:px-12">
8485

85-
<header className="mb-24">
86-
<Link to="/apps" 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]">
87-
<ArrowLeftIcon weight="bold" className="transition-transform group-hover:-translate-x-1" />
88-
<span>Applications</span>
89-
</Link>
90-
91-
<div className="flex flex-col md:flex-row md:items-end justify-between gap-12">
92-
<div className="space-y-4">
93-
<h1 className="text-6xl md:text-8xl font-black tracking-tighter text-white leading-none uppercase">
94-
OG Image Gen
95-
</h1>
96-
<p className="text-xl text-gray-400 max-w-2xl font-light leading-relaxed">
97-
Create stunning Open Graph images with generative backgrounds.
98-
</p>
99-
</div>
100-
</div>
101-
</header>
86+
<header className="mb-24">
87+
<Link to="/apps" 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]">
88+
<ArrowLeftIcon weight="bold" className="transition-transform group-hover:-translate-x-1" />
89+
<span>Applications</span>
90+
</Link>
10291

92+
<div className="flex flex-col md:flex-row md:items-end justify-between gap-12">
93+
<div className="space-y-4">
94+
<BreadcrumbTitle title="OG Image Gen" slug="og-gen" variant="brutalist" />
95+
<p className="text-xl text-gray-400 max-w-2xl font-light leading-relaxed">
96+
Create stunning Open Graph images with generative backgrounds.
97+
</p>
98+
</div>
99+
</div>
100+
</header>
103101
<div className="grid grid-cols-1 lg:grid-cols-12 gap-12">
104102

105103
{/* Controls Sidebar */}

0 commit comments

Comments
 (0)