Skip to content

Commit d18416e

Browse files
committed
feat: apps.
1 parent 33cf6be commit d18416e

File tree

9 files changed

+330
-30
lines changed

9 files changed

+330
-30
lines changed

craco.config.js

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
11
module.exports = {
2-
devServer: (devServerConfig, { env, paths, proxy, allowedHost }) => {
3-
// Ensure devServerConfig.setupMiddlewares is a function
4-
devServerConfig.setupMiddlewares = (middlewares, devServer) => {
5-
// No custom middlewares are added here, but the function must exist
6-
return middlewares;
7-
};
8-
9-
// Remove deprecated properties if they exist to avoid warnings
10-
delete devServerConfig.onBeforeSetupMiddleware;
11-
delete devServerConfig.onAfterSetupMiddleware;
12-
13-
return devServerConfig;
2+
devServer: {
3+
proxy: {
4+
'/api': {
5+
target: 'https://api.ipify.org',
6+
changeOrigin: true,
7+
pathRewrite: { '^/api': '' },
8+
},
9+
},
1410
},
1511
};

public/rss.xml

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,24 @@
99
<link>https://fezcode.com</link>
1010
</image>
1111
<generator>RSS for Node</generator>
12-
<lastBuildDate>Tue, 04 Nov 2025 18:55:10 GMT</lastBuildDate>
12+
<lastBuildDate>Tue, 04 Nov 2025 22:07:04 GMT</lastBuildDate>
1313
<atom:link href="https://fezcode.com/rss.xml" rel="self" type="application/rss+xml"/>
14-
<pubDate>Tue, 04 Nov 2025 18:55:10 GMT</pubDate>
14+
<pubDate>Tue, 04 Nov 2025 22:07:04 GMT</pubDate>
1515
<copyright><![CDATA[2025 Ahmed Samil Bulbul]]></copyright>
1616
<language><![CDATA[en]]></language>
1717
<managingEditor><![CDATA[samil.bulbul@gmail.com (Ahmed Samil Bulbul)]]></managingEditor>
1818
<webMaster><![CDATA[samil.bulbul@gmail.com (Ahmed Samil Bulbul)]]></webMaster>
1919
<ttl>60</ttl>
20+
<item>
21+
<title><![CDATA[Monotonic Stack with Daily Temperatures]]></title>
22+
<description><![CDATA[[object Object]]]></description>
23+
<link>https://fezcode.com/#/blog/monotonic-stack</link>
24+
<guid isPermaLink="false">https://fezcode.com/#/blog/monotonic-stack</guid>
25+
<dc:creator><![CDATA[Ahmed Samil Bulbul]]></dc:creator>
26+
<pubDate>Wed, 05 Nov 2025 00:00:00 GMT</pubDate>
27+
<content:encoded><![CDATA[<h1>Monotonic Stack &amp; LeetCode&#39;s &quot;Daily Temperatures&quot;</h1>
28+
<p><a href="https://fezcode.com/#/blog/monotonic-stack">Read more...</a></p>]]></content:encoded>
29+
</item>
2030
<item>
2131
<title><![CDATA[Weighted Quick-Union with Path Compression]]></title>
2232
<description><![CDATA[[object Object]]]></description>

src/components/AnimatedRoutes.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ import DndNotFoundPage from '../pages/DndNotFoundPage'; // New import
1616
import DndEpisodePage from '../pages/DndEpisodePage'; // New import
1717
import DndLorePage from '../pages/DndLorePage'; // New import
1818
import DndBookPage from '../pages/DndBookPage'; // New import
19+
import AppPage from '../pages/AppPage';
20+
import IpPage from '../pages/apps/IpPage';
1921

2022
import UsefulLinksPage from '../pages/UsefulLinksPage';
2123

@@ -270,6 +272,34 @@ function AnimatedRoutes() {
270272
</motion.div>
271273
}
272274
/>
275+
<Route
276+
path="/apps"
277+
element={
278+
<motion.div
279+
initial="initial"
280+
animate="in"
281+
exit="out"
282+
variants={pageVariants}
283+
transition={pageTransition}
284+
>
285+
<AppPage />
286+
</motion.div>
287+
}
288+
/>
289+
<Route
290+
path="/apps/ip"
291+
element={
292+
<motion.div
293+
initial="initial"
294+
animate="in"
295+
exit="out"
296+
variants={pageVariants}
297+
transition={pageTransition}
298+
>
299+
<IpPage />
300+
</motion.div>
301+
}
302+
/>
273303
{/* D&D specific 404 page */}
274304
<Route
275305
path="/dnd/*"

src/components/AppCard.js

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import React from 'react';
2+
import { Link } from 'react-router-dom';
3+
import { ArrowRight } from '@phosphor-icons/react';
4+
import colors from '../config/colors';
5+
6+
const AppCard = ({ app }) => {
7+
const { to, title, description } = app;
8+
9+
const cardStyle = {
10+
backgroundColor: colors['article-alpha-10'],
11+
borderColor: colors['article-alpha-50'],
12+
color: colors.article,
13+
};
14+
15+
const detailTextColor = colors['article-light'];
16+
17+
return (
18+
<Link to={to} className="block h-full">
19+
<div
20+
className="group bg-transparent border rounded-lg shadow-2xl p-6 flex flex-col justify-between relative transform transition-all duration-300 ease-in-out scale-105 overflow-hidden h-full"
21+
style={cardStyle}
22+
>
23+
<div
24+
className="absolute top-0 left-0 w-full h-full opacity-10 group-hover:opacity-0 transition-opacity duration-500 ease-in-out"
25+
style={{
26+
backgroundImage:
27+
'radial-gradient(circle, white 1px, transparent 1px)',
28+
backgroundSize: '10px 10px',
29+
}}
30+
></div>
31+
<div
32+
className="absolute top-0 left-0 w-full h-full opacity-0 group-hover:opacity-10 transition-opacity duration-500 ease-in-out"
33+
style={{
34+
backgroundImage:
35+
'linear-gradient(white 1px, transparent 1px), linear-gradient(to right, white 1px, transparent 1px)',
36+
backgroundSize: '15px 15px',
37+
}}
38+
></div>
39+
<div>
40+
<h2 className="text-xl font-normal transition-colors" style={{ color: cardStyle.color }}>{title}</h2>
41+
<p className="mt-2" style={{ color: detailTextColor }}>{description}</p>
42+
</div>
43+
<div className="flex justify-end items-center mt-4">
44+
<ArrowRight size={24} className="transition-colors" style={{ color: detailTextColor }} />
45+
</div>
46+
</div>
47+
</Link>
48+
);
49+
};
50+
51+
export default AppCard;

src/components/Navbar.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React, { useState, useEffect } from 'react';
22
import { Link } from 'react-router-dom';
33
import Fez from './Fez';
4-
import { Sidebar, User, BookOpen } from '@phosphor-icons/react';
4+
import { Sidebar, User, BookOpen, RocketLaunch } from '@phosphor-icons/react';
55

66
const Navbar = ({ toggleSidebar, isSidebarOpen }) => {
77
const [isScrolled, setIsScrolled] = useState(false);
@@ -76,6 +76,13 @@ const Navbar = ({ toggleSidebar, isSidebarOpen }) => {
7676
<BookOpen size={24} />
7777
<span>Blog</span>
7878
</Link>
79+
<Link
80+
to="/apps"
81+
className="flex items-center space-x-3 text-gray-300 hover:text-white hover:bg-gray-800 px-3 py-2 rounded-md transition-colors"
82+
>
83+
<RocketLaunch size={24} />
84+
<span>Apps</span>
85+
</Link>
7986
</div>
8087
</div>
8188
</header>

src/components/Sidebar.js

Lines changed: 47 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,19 @@ import { NavLink, Link, useLocation } from 'react-router-dom';
55
import { motion } from 'framer-motion';
66

77
import {
8-
HouseIcon,
9-
UserIcon,
10-
BookOpenIcon,
11-
WrenchIcon,
12-
ArticleIcon,
13-
CaretDownIcon,
14-
GameControllerIcon,
15-
ListIcon,
16-
GithubLogoIcon,
17-
GlobeSimpleIcon,
18-
SwordIcon,
19-
AlienIcon,
20-
AnchorIcon, JoystickIcon, BooksIcon, AsteriskSimpleIcon, LinkIcon, ArrowSquareOutIcon, ShuffleIcon, EnvelopeSimpleIcon, RssIcon
8+
House as HouseIcon,
9+
User as UserIcon,
10+
BookOpen as BookOpenIcon,
11+
Wrench as WrenchIcon,
12+
Article as ArticleIcon,
13+
CaretDown as CaretDownIcon,
14+
GameController as GameControllerIcon,
15+
List as ListIcon,
16+
GithubLogo as GithubLogoIcon,
17+
GlobeSimple as GlobeSimpleIcon,
18+
Sword as SwordIcon,
19+
Alien as AlienIcon,
20+
Anchor as AnchorIcon, Joystick as JoystickIcon, Books as BooksIcon, AsteriskSimple as AsteriskSimpleIcon, Link as LinkIcon, ArrowSquareOut as ArrowSquareOutIcon, Shuffle as ShuffleIcon, EnvelopeSimple as EnvelopeSimpleIcon, Rss as RssIcon, SquaresFour as SquaresFourIcon, ComputerTower as ComputerTowerIcon
2121
} from '@phosphor-icons/react';
2222

2323
import Fez from './Fez';
@@ -27,6 +27,7 @@ import { version } from '../version';
2727
const Sidebar = ({ isOpen, toggleSidebar, toggleModal }) => {
2828
const [isMainOpen, setIsMainOpen] = useState(true);
2929
const [isContentOpen, setIsContentOpen] = useState(true);
30+
const [isAppsOpen, setIsAppsOpen] = useState(true);
3031
const [isExtrasOpen, setIsExtrasOpen] = useState(false);
3132
const [isGamesOpen, setIsGamesOpen] = useState(false);
3233
const [isExternalLinksOpen, setIsExternalLinksOpen] = useState(false);
@@ -37,15 +38,16 @@ const Sidebar = ({ isOpen, toggleSidebar, toggleModal }) => {
3738
// Effect to update allSectionsOpen when individual sections change
3839
useEffect(() => {
3940
setAllSectionsOpen(
40-
isMainOpen && isContentOpen && isExtrasOpen && isGamesOpen && isExternalLinksOpen,
41+
isMainOpen && isContentOpen && isAppsOpen && isExtrasOpen && isGamesOpen && isExternalLinksOpen,
4142
);
42-
}, [isMainOpen, isContentOpen, isGamesOpen, isExtrasOpen, isExternalLinksOpen]);
43+
}, [isMainOpen, isContentOpen, isAppsOpen, isGamesOpen, isExtrasOpen, isExternalLinksOpen]);
4344

4445
const toggleAllSections = () => {
4546
const newState = !allSectionsOpen;
4647
setAllSectionsOpen(newState);
4748
setIsMainOpen(newState);
4849
setIsContentOpen(newState);
50+
setIsAppsOpen(newState);
4951
setIsExtrasOpen(newState);
5052
setIsGamesOpen(newState);
5153
setIsExternalLinksOpen(newState);
@@ -66,6 +68,8 @@ const Sidebar = ({ isOpen, toggleSidebar, toggleModal }) => {
6668
location.pathname.startsWith('/projects') ||
6769
location.pathname.startsWith('/logs');
6870

71+
const isAppsActive = location.pathname.startsWith('/apps');
72+
6973
const variants = {
7074
open: { x: 0 },
7175

@@ -179,6 +183,34 @@ const Sidebar = ({ isOpen, toggleSidebar, toggleModal }) => {
179183
)}
180184
</div>
181185

186+
<div className="mt-8">
187+
<button
188+
onClick={() => setIsAppsOpen(!isAppsOpen)}
189+
className={`flex items-center justify-between w-full text-sm font-normal uppercase tracking-wider mb-4 focus:outline-none ${
190+
isAppsActive ? 'text-red-400' : 'text-gray-100'
191+
}`}
192+
>
193+
<span className={`flex items-center gap-2 font-sans ${isAppsActive ? 'text-rose-400' : 'text-white'}`}>
194+
<SquaresFourIcon size={16} />
195+
<span>Apps</span>
196+
</span>
197+
198+
<CaretDownIcon
199+
size={20}
200+
className={`transition-transform ${isAppsOpen ? 'transform rotate-180' : ''}`}
201+
/>
202+
</button>
203+
204+
{isAppsOpen && (
205+
<nav className="space-y-2 border-l-2 border-gray-700 ml-3 pl-3">
206+
<NavLink to="/apps" className={getLinkClass}>
207+
<SquaresFourIcon size={24} />
208+
<span>All Apps</span>
209+
</NavLink>
210+
</nav>
211+
)}
212+
</div>
213+
182214
<div className="mt-8">
183215
<button
184216
onClick={() => setIsExtrasOpen(!isExtrasOpen)}

src/index.css

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,14 @@ code {
9393
color: #bc4749 !important; /* Placeholder color for 'logs' */
9494
}
9595

96+
.apps-color {
97+
color: #f5dd90 !important; /* Placeholder color for 'apps' */
98+
}
99+
100+
.single-app-color {
101+
color: #A07B90 !important; /* Placeholder color for 'single-app' */
102+
}
103+
96104
@media (max-width: 768px) {
97105
body {
98106
font-family: serif !important;

src/pages/AppPage.js

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import React from 'react';
2+
import { Link } from 'react-router-dom';
3+
import { ArrowLeftIcon } from '@phosphor-icons/react';
4+
import AppCard from '../components/AppCard';
5+
import usePageTitle from '../utils/usePageTitle';
6+
7+
const apps = [
8+
{
9+
to: '/apps/ip',
10+
title: 'Show my IP',
11+
description: 'Display your public IP address.',
12+
},
13+
];
14+
15+
function AppPage() {
16+
usePageTitle('Apps');
17+
18+
return (
19+
<div className="py-16 sm:py-24">
20+
<div className="mx-auto max-w-7xl px-6 lg:px-8 text-gray-300">
21+
<Link
22+
to="/"
23+
className="text-primary-400 hover:underline flex items-center justify-center gap-2 text-lg mb-4"
24+
>
25+
<ArrowLeftIcon size={24} /> Back to Home
26+
</Link>
27+
<h1 className="text-4xl font-bold tracking-tight sm:text-6xl mb-4 flex items-center">
28+
<span className="codex-color">codex</span>
29+
<span className="separator-color">::</span>
30+
<span className="apps-color">apps</span>
31+
</h1>
32+
<hr className="border-gray-700" />
33+
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8 mt-8">
34+
{apps.map((app, index) => (
35+
<AppCard key={index} app={app} />
36+
))}
37+
</div>
38+
</div>
39+
</div>
40+
);
41+
}
42+
43+
export default AppPage;

0 commit comments

Comments
 (0)