Skip to content

Commit e21799e

Browse files
committed
feat: metabolic hub
1 parent 35eca7c commit e21799e

File tree

15 files changed

+2062
-49
lines changed

15 files changed

+2062
-49
lines changed

public/apps/apps.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -654,6 +654,14 @@
654654
"icon": "ToolboxIcon",
655655
"order": 5,
656656
"apps": [
657+
{
658+
"slug": "metabolic-hub",
659+
"to": "/apps/metabolic-hub",
660+
"title": "Metabolic Hub (Fasting Tracker)",
661+
"description": "Protocol for high-precision metabolic temporal management and nutritional tracking.",
662+
"icon": "ForkKnifeIcon",
663+
"created_at": "2026-01-04T12:00:00+03:00"
664+
},
657665
{
658666
"slug": "piml-lab",
659667
"to": "/apps/piml-lab",

public/rss.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@
99
<link>https://fezcode.com</link>
1010
</image>
1111
<generator>RSS for Node</generator>
12-
<lastBuildDate>Sat, 03 Jan 2026 20:21:16 GMT</lastBuildDate>
12+
<lastBuildDate>Sun, 04 Jan 2026 10:35:29 GMT</lastBuildDate>
1313
<atom:link href="https://fezcode.com/rss.xml" rel="self" type="application/rss+xml"/>
14-
<pubDate>Sat, 03 Jan 2026 20:21:16 GMT</pubDate>
14+
<pubDate>Sun, 04 Jan 2026 10:35:24 GMT</pubDate>
1515
<copyright><![CDATA[2026 Ahmed Samil Bulbul]]></copyright>
1616
<language><![CDATA[en]]></language>
1717
<managingEditor><![CDATA[samil.bulbul@gmail.com (Ahmed Samil Bulbul)]]></managingEditor>

public/sitemap.xml

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,55 +2,55 @@
22
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
33
<url>
44
<loc>https://fezcode.com/</loc>
5-
<lastmod>2026-01-03T20:21:16.855Z</lastmod>
5+
<lastmod>2026-01-04T10:35:30.034Z</lastmod>
66
<changefreq>monthly</changefreq>
77
<priority>1.0</priority>
88
</url>
99
<url>
1010
<loc>https://fezcode.com/about</loc>
11-
<lastmod>2026-01-03T20:21:16.856Z</lastmod>
11+
<lastmod>2026-01-04T10:35:30.035Z</lastmod>
1212
<changefreq>monthly</changefreq>
1313
<priority>0.8</priority>
1414
</url>
1515
<url>
1616
<loc>https://fezcode.com/blog</loc>
17-
<lastmod>2026-01-03T20:21:16.856Z</lastmod>
17+
<lastmod>2026-01-04T10:35:30.035Z</lastmod>
1818
<changefreq>monthly</changefreq>
1919
<priority>0.8</priority>
2020
</url>
2121
<url>
2222
<loc>https://fezcode.com/projects</loc>
23-
<lastmod>2026-01-03T20:21:16.856Z</lastmod>
23+
<lastmod>2026-01-04T10:35:30.035Z</lastmod>
2424
<changefreq>monthly</changefreq>
2525
<priority>0.8</priority>
2626
</url>
2727
<url>
2828
<loc>https://fezcode.com/logs</loc>
29-
<lastmod>2026-01-03T20:21:16.856Z</lastmod>
29+
<lastmod>2026-01-04T10:35:30.035Z</lastmod>
3030
<changefreq>monthly</changefreq>
3131
<priority>0.8</priority>
3232
</url>
3333
<url>
3434
<loc>https://fezcode.com/stories</loc>
35-
<lastmod>2026-01-03T20:21:16.856Z</lastmod>
35+
<lastmod>2026-01-04T10:35:30.035Z</lastmod>
3636
<changefreq>monthly</changefreq>
3737
<priority>0.8</priority>
3838
</url>
3939
<url>
4040
<loc>https://fezcode.com/settings</loc>
41-
<lastmod>2026-01-03T20:21:16.856Z</lastmod>
41+
<lastmod>2026-01-04T10:35:30.035Z</lastmod>
4242
<changefreq>monthly</changefreq>
4343
<priority>0.8</priority>
4444
</url>
4545
<url>
4646
<loc>https://fezcode.com/apps</loc>
47-
<lastmod>2026-01-03T20:21:16.856Z</lastmod>
47+
<lastmod>2026-01-04T10:35:30.035Z</lastmod>
4848
<changefreq>monthly</changefreq>
4949
<priority>0.8</priority>
5050
</url>
5151
<url>
5252
<loc>https://fezcode.com/stories/lore</loc>
53-
<lastmod>2026-01-03T20:21:16.856Z</lastmod>
53+
<lastmod>2026-01-04T10:35:30.035Z</lastmod>
5454
<changefreq>monthly</changefreq>
5555
<priority>0.8</priority>
5656
</url>
@@ -1106,79 +1106,79 @@
11061106
</url>
11071107
<url>
11081108
<loc>https://fezcode.com/stories/books/1</loc>
1109-
<lastmod>2026-01-03T20:21:16.864Z</lastmod>
1109+
<lastmod>2026-01-04T10:35:31.140Z</lastmod>
11101110
<changefreq>monthly</changefreq>
11111111
<priority>0.6</priority>
11121112
</url>
11131113
<url>
11141114
<loc>https://fezcode.com/stories/books/1/pages/1</loc>
1115-
<lastmod>2026-01-03T20:21:16.864Z</lastmod>
1115+
<lastmod>2026-01-04T10:35:31.140Z</lastmod>
11161116
<changefreq>weekly</changefreq>
11171117
<priority>0.5</priority>
11181118
</url>
11191119
<url>
11201120
<loc>https://fezcode.com/stories/books/2</loc>
1121-
<lastmod>2026-01-03T20:21:16.864Z</lastmod>
1121+
<lastmod>2026-01-04T10:35:31.140Z</lastmod>
11221122
<changefreq>monthly</changefreq>
11231123
<priority>0.6</priority>
11241124
</url>
11251125
<url>
11261126
<loc>https://fezcode.com/stories/books/2/pages/1</loc>
1127-
<lastmod>2026-01-03T20:21:16.864Z</lastmod>
1127+
<lastmod>2026-01-04T10:35:31.140Z</lastmod>
11281128
<changefreq>weekly</changefreq>
11291129
<priority>0.5</priority>
11301130
</url>
11311131
<url>
11321132
<loc>https://fezcode.com/stories/books/3</loc>
1133-
<lastmod>2026-01-03T20:21:16.864Z</lastmod>
1133+
<lastmod>2026-01-04T10:35:31.140Z</lastmod>
11341134
<changefreq>monthly</changefreq>
11351135
<priority>0.6</priority>
11361136
</url>
11371137
<url>
11381138
<loc>https://fezcode.com/stories/books/3/pages/1</loc>
1139-
<lastmod>2026-01-03T20:21:16.864Z</lastmod>
1139+
<lastmod>2026-01-04T10:35:31.140Z</lastmod>
11401140
<changefreq>weekly</changefreq>
11411141
<priority>0.5</priority>
11421142
</url>
11431143
<url>
11441144
<loc>https://fezcode.com/stories/books/3/pages/2</loc>
1145-
<lastmod>2026-01-03T20:21:16.864Z</lastmod>
1145+
<lastmod>2026-01-04T10:35:31.140Z</lastmod>
11461146
<changefreq>weekly</changefreq>
11471147
<priority>0.5</priority>
11481148
</url>
11491149
<url>
11501150
<loc>https://fezcode.com/stories/books/4</loc>
1151-
<lastmod>2026-01-03T20:21:16.864Z</lastmod>
1151+
<lastmod>2026-01-04T10:35:31.140Z</lastmod>
11521152
<changefreq>monthly</changefreq>
11531153
<priority>0.6</priority>
11541154
</url>
11551155
<url>
11561156
<loc>https://fezcode.com/stories/books/4/pages/1</loc>
1157-
<lastmod>2026-01-03T20:21:16.864Z</lastmod>
1157+
<lastmod>2026-01-04T10:35:31.140Z</lastmod>
11581158
<changefreq>weekly</changefreq>
11591159
<priority>0.5</priority>
11601160
</url>
11611161
<url>
11621162
<loc>https://fezcode.com/stories/books/4/pages/2</loc>
1163-
<lastmod>2026-01-03T20:21:16.864Z</lastmod>
1163+
<lastmod>2026-01-04T10:35:31.140Z</lastmod>
11641164
<changefreq>weekly</changefreq>
11651165
<priority>0.5</priority>
11661166
</url>
11671167
<url>
11681168
<loc>https://fezcode.com/stories/books/5</loc>
1169-
<lastmod>2026-01-03T20:21:16.864Z</lastmod>
1169+
<lastmod>2026-01-04T10:35:31.140Z</lastmod>
11701170
<changefreq>monthly</changefreq>
11711171
<priority>0.6</priority>
11721172
</url>
11731173
<url>
11741174
<loc>https://fezcode.com/stories/books/5/pages/1</loc>
1175-
<lastmod>2026-01-03T20:21:16.864Z</lastmod>
1175+
<lastmod>2026-01-04T10:35:31.140Z</lastmod>
11761176
<changefreq>weekly</changefreq>
11771177
<priority>0.5</priority>
11781178
</url>
11791179
<url>
11801180
<loc>https://fezcode.com/stories/books/5/pages/2</loc>
1181-
<lastmod>2026-01-03T20:21:16.864Z</lastmod>
1181+
<lastmod>2026-01-04T10:35:31.140Z</lastmod>
11821182
<changefreq>weekly</changefreq>
11831183
<priority>0.5</priority>
11841184
</url>
Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
import React, { useState, useEffect } from 'react';
2+
import BrutalistDialog from '../../../../components/BrutalistDialog';
3+
4+
const AdjustFastModal = ({ isOpen, onClose, fast, onUpdate }) => {
5+
const [startTime, setStartTime] = useState('');
6+
const [endTime, setEndTime] = useState('');
7+
const [targetLength, setTargetLength] = useState(16);
8+
9+
useEffect(() => {
10+
if (fast && isOpen) {
11+
// Format dates for datetime-local input (YYYY-MM-DDTHH:mm)
12+
const start = new Date(fast.start);
13+
start.setMinutes(start.getMinutes() - start.getTimezoneOffset());
14+
setStartTime(start.toISOString().slice(0, 16));
15+
16+
if (fast.end) {
17+
const end = new Date(fast.end);
18+
end.setMinutes(end.getMinutes() - end.getTimezoneOffset());
19+
setEndTime(end.toISOString().slice(0, 16));
20+
} else {
21+
setEndTime('');
22+
}
23+
setTargetLength(fast.targetLength || 16);
24+
}
25+
}, [fast, isOpen]);
26+
27+
const handleSave = () => {
28+
const updatedData = {
29+
start: new Date(startTime).getTime(),
30+
targetLength: parseInt(targetLength),
31+
};
32+
if (endTime) {
33+
updatedData.end = new Date(endTime).getTime();
34+
}
35+
onUpdate(fast.id, updatedData);
36+
onClose();
37+
};
38+
39+
if (!fast) return null;
40+
41+
return (
42+
43+
<BrutalistDialog
44+
45+
isOpen={isOpen}
46+
47+
onClose={onClose}
48+
49+
title="Edit Fasting Time"
50+
51+
variant="paper"
52+
53+
>
54+
55+
<div className="space-y-8 py-6 font-arvo text-[#1a1a1a]">
56+
57+
<p className="text-[10px] font-mono font-black uppercase tracking-widest border-b border-[#1a1a1a]/10 pb-2">Change your fasting hours</p>
58+
59+
<div className="space-y-6">
60+
61+
<div>
62+
63+
<label className="block text-[10px] font-mono text-gray-400 uppercase tracking-widest mb-3 font-bold">Started At</label>
64+
65+
<input
66+
67+
type="datetime-local"
68+
69+
value={startTime}
70+
71+
onChange={(e) => setStartTime(e.target.value)}
72+
73+
className="w-full bg-[#1a1a1a]/5 border-b-2 border-[#1a1a1a] p-4 text-lg text-[#1a1a1a] focus:outline-none font-mono font-black"
74+
75+
/>
76+
77+
</div>
78+
79+
{fast.end && (
80+
81+
<div>
82+
83+
<label className="block text-[10px] font-mono text-gray-400 uppercase tracking-widest mb-3 font-bold">Ended At</label>
84+
85+
<input
86+
87+
type="datetime-local"
88+
89+
value={endTime}
90+
91+
onChange={(e) => setEndTime(e.target.value)}
92+
93+
className="w-full bg-[#1a1a1a]/5 border-b-2 border-[#1a1a1a] p-4 text-lg text-[#1a1a1a] focus:outline-none font-mono font-black"
94+
95+
/>
96+
97+
</div>
98+
99+
)}
100+
101+
<div>
102+
103+
<label className="block text-[10px] font-mono text-gray-400 uppercase tracking-widest mb-3 font-bold">Goal (Hours)</label>
104+
105+
<input
106+
107+
type="number"
108+
109+
value={targetLength}
110+
111+
onChange={(e) => setTargetLength(e.target.value)}
112+
113+
className="w-full bg-[#1a1a1a]/5 border-b-2 border-[#1a1a1a] p-4 text-2xl text-[#1a1a1a] focus:outline-none font-mono font-black"
114+
115+
/>
116+
117+
</div>
118+
119+
</div>
120+
121+
<button
122+
123+
onClick={handleSave}
124+
125+
className="w-full py-5 bg-[#1a1a1a] text-[#e9e4d0] font-black uppercase tracking-[0.4em] hover:opacity-90 transition-all text-xs mt-8 shadow-xl"
126+
127+
>
128+
129+
Confirm Changes
130+
131+
</button>
132+
133+
</div>
134+
135+
</BrutalistDialog>
136+
137+
);
138+
};
139+
140+
export default AdjustFastModal;

0 commit comments

Comments
 (0)