Skip to content

Commit 6e7a853

Browse files
committed
feat: Add Crontab Generator and refactor navigation to use React Router for URL-based routing.
1 parent a8293cd commit 6e7a853

12 files changed

Lines changed: 356 additions & 36 deletions

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ A sleek collection of developer tools built with React + Vite. Runs entirely in-
1414
| **Password Gen** | Generate secure random passwords with configurable options |
1515
| **Hash Generator** | Generate MD5 and bcrypt hashes |
1616
| **Basic Auth** | Generate HTTP headers and Nginx/Apache htpasswd entries |
17+
| **Crontab Gen** | Generate, explain, and validate cron expressions with UTC time |
1718

1819
## Quick Start
1920

package-lock.json

Lines changed: 69 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@
1010
},
1111
"dependencies": {
1212
"bcryptjs": "^3.0.3",
13+
"cronstrue": "^3.11.0",
1314
"lucide-react": "^0.460.0",
1415
"react": "^18.3.1",
15-
"react-dom": "^18.3.1"
16+
"react-dom": "^18.3.1",
17+
"react-router-dom": "^7.13.0"
1618
},
1719
"devDependencies": {
1820
"@types/react": "^18.3.12",

src/App.jsx

Lines changed: 30 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useState } from 'react';
1+
import { Routes, Route, Navigate, useLocation } from 'react-router-dom';
22
import {
33
ArrowRightLeft,
44
ShieldCheck,
@@ -7,7 +7,8 @@ import {
77
AlignLeft,
88
KeyRound,
99
Hash,
10-
Lock
10+
Lock,
11+
CalendarClock
1112
} from 'lucide-react';
1213

1314
// Layout components
@@ -22,12 +23,10 @@ import {
2223
CharacterCount,
2324
PasswordGenerator,
2425
HashGenerator,
25-
BasicAuthGenerator
26+
BasicAuthGenerator,
27+
CrontabGenerator
2628
} from './features';
2729

28-
// UI components
29-
import { Card } from './components/ui';
30-
3130
/**
3231
* Navigation configuration
3332
*/
@@ -40,6 +39,7 @@ const NAV_ITEMS = [
4039
{ id: 'password', label: 'Password Gen', icon: Lock },
4140
{ id: 'hash', label: 'Hash Generator', icon: Hash },
4241
{ id: 'basicauth', label: 'Basic Auth', icon: KeyRound },
42+
{ id: 'crontab', label: 'Crontab Gen', icon: CalendarClock },
4343
];
4444

4545
/**
@@ -54,31 +54,44 @@ const FEATURE_COMPONENTS = {
5454
password: PasswordGenerator,
5555
hash: HashGenerator,
5656
basicauth: BasicAuthGenerator,
57+
crontab: CrontabGenerator,
5758
};
5859

5960
/**
6061
* Main Application Component
6162
*/
6263
const App = () => {
63-
const [activeTab, setActiveTab] = useState('debezium');
64-
65-
const activeNavItem = NAV_ITEMS.find(i => i.id === activeTab);
66-
const ActiveFeature = FEATURE_COMPONENTS[activeTab];
64+
const location = useLocation();
65+
// Extract feature ID from path (e.g., "/crontab" -> "crontab")
66+
const currentId = location.pathname.substring(1) || 'debezium';
67+
const activeNavItem = NAV_ITEMS.find(i => i.id === currentId) || NAV_ITEMS[0];
6768

6869
return (
6970
<div className="flex h-screen w-full bg-slate-950 text-slate-200 font-sans selection:bg-blue-500/30">
70-
<Sidebar
71-
navItems={NAV_ITEMS}
72-
activeTab={activeTab}
73-
onTabChange={setActiveTab}
74-
/>
71+
<Sidebar navItems={NAV_ITEMS} />
7572

7673
<div className="flex-1 flex flex-col overflow-hidden w-full">
7774
<Header title={activeNavItem?.label} />
7875

79-
<main className="flex-1 overflow-hidden p-4 md:p-6 relative">
76+
<main className="flex-1 overflow-y-auto p-4 md:p-6 relative">
8077
<div className="h-full w-full max-w-6xl mx-auto">
81-
{ActiveFeature && <ActiveFeature />}
78+
<Routes>
79+
<Route path="/" element={<Navigate to="/debezium" replace />} />
80+
81+
{NAV_ITEMS.map(item => {
82+
const Component = FEATURE_COMPONENTS[item.id];
83+
return (
84+
<Route
85+
key={item.id}
86+
path={`/${item.id}`}
87+
element={<Component />}
88+
/>
89+
);
90+
})}
91+
92+
{/* Fallback for unknown routes */}
93+
<Route path="*" element={<Navigate to="/debezium" replace />} />
94+
</Routes>
8295
</div>
8396
</main>
8497
</div>

src/features/BasicAuthGenerator.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ const BasicAuthGenerator = () => {
5555
};
5656

5757
return (
58-
<div className="flex flex-col gap-6 max-w-2xl mx-auto mt-8">
58+
<div className="flex flex-col gap-6 max-w-2xl mx-auto">
5959
<Card title="Basic Auth Generator">
6060
<div className="flex flex-col gap-6">
6161
{/* Credentials Input */}

0 commit comments

Comments
 (0)