diff --git a/app/Http/Controllers/ToolController.php b/app/Http/Controllers/ToolController.php
index 8d6782c..ebb7a3a 100644
--- a/app/Http/Controllers/ToolController.php
+++ b/app/Http/Controllers/ToolController.php
@@ -69,6 +69,12 @@ public function index(): View
'route' => 'tools.code-editor',
'icon' => 'editor',
],
+ [
+ 'name' => 'Cron Parser',
+ 'description' => 'Parse and explain cron expressions',
+ 'route' => 'tools.cron',
+ 'icon' => 'clock',
+ ],
];
return view('home', compact('tools'));
@@ -123,4 +129,9 @@ public function codeEditor(): View
{
return view('tools.code-editor');
}
+
+ public function cron(): View
+ {
+ return view('tools.cron-parser');
+ }
}
diff --git a/resources/views/home.blade.php b/resources/views/home.blade.php
index 7de13c3..88070e4 100644
--- a/resources/views/home.blade.php
+++ b/resources/views/home.blade.php
@@ -84,6 +84,11 @@
@break
+ @case('clock')
+
+ @break
@endswitch
diff --git a/resources/views/tools/cron-parser.blade.php b/resources/views/tools/cron-parser.blade.php
new file mode 100644
index 0000000..475ef07
--- /dev/null
+++ b/resources/views/tools/cron-parser.blade.php
@@ -0,0 +1,547 @@
+@extends('layouts.app')
+
+@section('title', 'Cron Expression Parser - Explain & Validate Cron Jobs | Dev Tools')
+@section('meta_description', 'Free online cron expression parser. Understand cron syntax, validate expressions, see next run times, and get human-readable explanations of your cron schedules.')
+@section('meta_keywords', 'cron parser, cron expression, cron validator, cron schedule, crontab, cron syntax, cron job, cron generator, cron explainer, cron next run')
+
+@push('schema')
+
+@endpush
+
+@section('content')
+
+
+
+
Cron Expression Parser
+
Parse and explain cron expressions with next run times
+
+
← Back
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Syntax Reference
+
+
+
Field Values
+
+
+
+ | Minute |
+ 0-59 |
+
+
+ | Hour |
+ 0-23 |
+
+
+ | Day of Month |
+ 1-31 |
+
+
+ | Month |
+ 1-12 |
+
+
+ | Day of Week |
+ 0-6 (Sun-Sat) |
+
+
+
+
+
+
Special Characters
+
+
+
+ | * |
+ Any value |
+
+
+ | , |
+ Value list (1,3,5) |
+
+
+ | - |
+ Range (1-5) |
+
+
+ | / |
+ Step (*/15) |
+
+
+
+
+
+
+
+
+
+@endsection
+
+@push('scripts')
+
+@endpush
diff --git a/routes/web.php b/routes/web.php
index ebacbfc..ae392fe 100644
--- a/routes/web.php
+++ b/routes/web.php
@@ -16,6 +16,7 @@
Route::get('/hash', [ToolController::class, 'hash'])->name('hash');
Route::get('/url', [ToolController::class, 'url'])->name('url');
Route::get('/code-editor', [ToolController::class, 'codeEditor'])->name('code-editor');
+ Route::get('/cron', [ToolController::class, 'cron'])->name('cron');
});
// Static Pages
@@ -36,6 +37,7 @@
['loc' => route('tools.hash'), 'priority' => '0.8', 'changefreq' => 'monthly'],
['loc' => route('tools.url'), 'priority' => '0.8', 'changefreq' => 'monthly'],
['loc' => route('tools.code-editor'), 'priority' => '0.9', 'changefreq' => 'monthly'],
+ ['loc' => route('tools.cron'), 'priority' => '0.8', 'changefreq' => 'monthly'],
['loc' => route('about'), 'priority' => '0.5', 'changefreq' => 'monthly'],
['loc' => route('privacy'), 'priority' => '0.3', 'changefreq' => 'yearly'],
];
diff --git a/tests/Feature/WebRoutesTest.php b/tests/Feature/WebRoutesTest.php
index 5acbe3a..af89929 100644
--- a/tests/Feature/WebRoutesTest.php
+++ b/tests/Feature/WebRoutesTest.php
@@ -28,6 +28,7 @@ public function test_home_page_displays_all_tools(): void
$response->assertSee('Hash Generator');
$response->assertSee('URL Encoder');
$response->assertSee('Code Editor');
+ $response->assertSee('Cron Parser');
}
public function test_home_page_has_tool_links(): void
@@ -44,6 +45,7 @@ public function test_home_page_has_tool_links(): void
$response->assertSee('href="' . route('tools.hash') . '"', false);
$response->assertSee('href="' . route('tools.url') . '"', false);
$response->assertSee('href="' . route('tools.code-editor') . '"', false);
+ $response->assertSee('href="' . route('tools.cron') . '"', false);
}
public function test_csv_tool_page_loads(): void
@@ -230,9 +232,29 @@ public function test_code_editor_has_required_elements(): void
$response->assertSee('monaco-container');
}
+ public function test_cron_tool_page_loads(): void
+ {
+ $response = $this->get('/tools/cron');
+
+ $response->assertStatus(200);
+ $response->assertSee('Cron Expression Parser');
+ $response->assertSee('Parse and explain cron expressions');
+ }
+
+ public function test_cron_tool_has_required_elements(): void
+ {
+ $response = $this->get('/tools/cron');
+
+ $response->assertStatus(200);
+ $response->assertSee('Cron Expression');
+ $response->assertSee('Common Patterns');
+ $response->assertSee('Syntax Reference');
+ $response->assertSee('Next Run Times');
+ }
+
public function test_all_pages_have_navigation(): void
{
- $pages = ['/', '/tools/csv', '/tools/yaml', '/tools/markdown', '/tools/sql', '/tools/base64', '/tools/uuid', '/tools/hash', '/tools/url', '/tools/code-editor'];
+ $pages = ['/', '/tools/csv', '/tools/yaml', '/tools/markdown', '/tools/sql', '/tools/base64', '/tools/uuid', '/tools/hash', '/tools/url', '/tools/code-editor', '/tools/cron'];
foreach ($pages as $page) {
$response = $this->get($page);
@@ -244,7 +266,7 @@ public function test_all_pages_have_navigation(): void
public function test_all_pages_have_theme_toggle(): void
{
- $pages = ['/', '/tools/csv', '/tools/yaml', '/tools/markdown', '/tools/sql', '/tools/base64', '/tools/uuid', '/tools/hash', '/tools/url', '/tools/code-editor'];
+ $pages = ['/', '/tools/csv', '/tools/yaml', '/tools/markdown', '/tools/sql', '/tools/base64', '/tools/uuid', '/tools/hash', '/tools/url', '/tools/code-editor', '/tools/cron'];
foreach ($pages as $page) {
$response = $this->get($page);
@@ -257,7 +279,7 @@ public function test_all_pages_have_theme_toggle(): void
public function test_all_pages_load_vite_assets(): void
{
// Code editor uses standalone template without Vite
- $pages = ['/', '/tools/csv', '/tools/yaml', '/tools/markdown', '/tools/sql', '/tools/base64', '/tools/uuid', '/tools/hash', '/tools/url'];
+ $pages = ['/', '/tools/csv', '/tools/yaml', '/tools/markdown', '/tools/sql', '/tools/base64', '/tools/uuid', '/tools/hash', '/tools/url', '/tools/cron'];
foreach ($pages as $page) {
$response = $this->get($page);
@@ -270,7 +292,7 @@ public function test_all_pages_load_vite_assets(): void
public function test_all_tool_pages_have_back_link(): void
{
// Code editor uses standalone template with home link instead of back
- $toolPages = ['/tools/csv', '/tools/yaml', '/tools/markdown', '/tools/sql', '/tools/base64', '/tools/uuid', '/tools/hash', '/tools/url'];
+ $toolPages = ['/tools/csv', '/tools/yaml', '/tools/markdown', '/tools/sql', '/tools/base64', '/tools/uuid', '/tools/hash', '/tools/url', '/tools/cron'];
foreach ($toolPages as $page) {
$response = $this->get($page);
@@ -323,7 +345,7 @@ public function test_api_routes_reject_get_requests(): void
public function test_pages_have_csrf_token(): void
{
- $pages = ['/tools/csv', '/tools/yaml', '/tools/markdown', '/tools/sql', '/tools/base64', '/tools/uuid', '/tools/hash', '/tools/url', '/tools/code-editor'];
+ $pages = ['/tools/csv', '/tools/yaml', '/tools/markdown', '/tools/sql', '/tools/base64', '/tools/uuid', '/tools/hash', '/tools/url', '/tools/code-editor', '/tools/cron'];
foreach ($pages as $page) {
$response = $this->get($page);