feat: complete Bildirchin Quail Farm web app with wholesale & retail system

This commit is contained in:
Antigravity Bot
2026-08-30 21:56:25 +03:30
parent 53e5c055ea
commit d44b57080a
57 changed files with 4440 additions and 0 deletions
+6
View File
@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 250" width="100%" height="100%">
<rect width="400" height="250" rx="16" fill="#0f172a"/>
<circle cx="320" cy="80" r="70" fill="#0284c7" opacity="0.3"/>
<text x="200" y="115" font-size="18" font-family="sans-serif" font-weight="bold" fill="#38bdf8" text-anchor="middle">سالن مدرن پرورش بلدرچین</text>
<text x="200" y="150" font-size="13" font-family="sans-serif" fill="#94a3b8" text-anchor="middle">اصول تهویه، رطوبت، نور و قفس‌های مکانیزه</text>
</svg>

After

Width:  |  Height:  |  Size: 573 B

+6
View File
@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 250" width="100%" height="100%">
<rect width="400" height="250" rx="16" fill="#064e3b"/>
<circle cx="80" cy="180" r="90" fill="#059669" opacity="0.3"/>
<text x="200" y="115" font-size="18" font-family="sans-serif" font-weight="bold" fill="#34d399" text-anchor="middle">معجزه سلامت: خواص تخم بلدرچین</text>
<text x="200" y="150" font-size="13" font-family="sans-serif" fill="#a7f3d0" text-anchor="middle">ویتامین B12، آهن، فسفر و انرژی فراوان</text>
</svg>

After

Width:  |  Height:  |  Size: 573 B

+6
View File
@@ -0,0 +1,6 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 250" width="100%" height="100%">
<rect width="400" height="250" rx="16" fill="#451a03"/>
<circle cx="200" cy="125" r="80" fill="#b45309" opacity="0.3"/>
<text x="200" y="115" font-size="18" font-family="sans-serif" font-weight="bold" fill="#fbbf24" text-anchor="middle">فرمولاسیون جیره غذایی و دان</text>
<text x="200" y="150" font-size="13" font-family="sans-serif" fill="#fde68a" text-anchor="middle">پروتئین خام، ضریب تبدیل و وزن‌گیری سریع</text>
</svg>

After

Width:  |  Height:  |  Size: 579 B

+30
View File
@@ -0,0 +1,30 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 300" width="100%" height="100%">
<rect width="400" height="300" rx="16" fill="#f8fafc"/>
<!-- Cage Frame -->
<rect x="90" y="50" width="220" height="200" fill="none" stroke="#64748b" stroke-width="4"/>
<!-- Cage Shelves / Layers -->
<line x1="90" y1="100" x2="310" y2="100" stroke="#64748b" stroke-width="3"/>
<line x1="90" y1="150" x2="310" y2="150" stroke="#64748b" stroke-width="3"/>
<line x1="90" y1="200" x2="310" y2="200" stroke="#64748b" stroke-width="3"/>
<!-- Wire Grid Lines Vertical -->
<line x1="120" y1="50" x2="120" y2="250" stroke="#94a3b8" stroke-width="1.5"/>
<line x1="150" y1="50" x2="150" y2="250" stroke="#94a3b8" stroke-width="1.5"/>
<line x1="180" y1="50" x2="180" y2="250" stroke="#94a3b8" stroke-width="1.5"/>
<line x1="210" y1="50" x2="210" y2="250" stroke="#94a3b8" stroke-width="1.5"/>
<line x1="240" y1="50" x2="240" y2="250" stroke="#94a3b8" stroke-width="1.5"/>
<line x1="270" y1="50" x2="270" y2="250" stroke="#94a3b8" stroke-width="1.5"/>
<!-- Automatic Nipple Drinker Pipe -->
<rect x="80" y="70" width="240" height="8" rx="3" fill="#ef4444"/>
<rect x="80" y="120" width="240" height="8" rx="3" fill="#ef4444"/>
<rect x="80" y="170" width="240" height="8" rx="3" fill="#ef4444"/>
<rect x="80" y="220" width="240" height="8" rx="3" fill="#ef4444"/>
<!-- Feeder Trough -->
<rect x="85" y="85" width="230" height="12" rx="2" fill="#e2e8f0" stroke="#94a3b8" stroke-width="1.5"/>
<rect x="85" y="135" width="230" height="12" rx="2" fill="#e2e8f0" stroke="#94a3b8" stroke-width="1.5"/>
<!-- Waste Trays -->
<rect x="85" y="103" width="230" height="6" rx="1" fill="#475569"/>
<rect x="85" y="153" width="230" height="6" rx="1" fill="#475569"/>
<!-- Stand Legs -->
<line x1="90" y1="250" x2="80" y2="280" stroke="#64748b" stroke-width="4"/>
<line x1="310" y1="250" x2="320" y2="280" stroke="#64748b" stroke-width="4"/>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

+19
View File
@@ -0,0 +1,19 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 300" width="100%" height="100%">
<rect width="400" height="300" rx="16" fill="#fef9c3"/>
<!-- Cute Quail Chick Body -->
<ellipse cx="200" cy="180" rx="45" ry="38" fill="#facc15"/>
<ellipse cx="180" cy="135" rx="30" ry="28" fill="#facc15"/>
<!-- Stripes on back -->
<path d="M 180 150 Q 220 160 235 180" stroke="#854d0e" stroke-width="4" fill="none"/>
<path d="M 185 160 Q 215 175 225 195" stroke="#854d0e" stroke-width="3" fill="none"/>
<!-- Eye -->
<circle cx="168" cy="130" r="5" fill="#000"/>
<circle cx="166" cy="128" r="1.5" fill="#fff"/>
<!-- Tiny Beak -->
<path d="M 152 135 L 140 138 L 152 143 Z" fill="#f97316"/>
<!-- Wing -->
<ellipse cx="210" cy="180" rx="18" ry="12" fill="#eab308"/>
<!-- Feet -->
<line x1="185" y1="218" x2="180" y2="245" stroke="#ea580c" stroke-width="3"/>
<line x1="210" y1="218" x2="205" y2="245" stroke="#ea580c" stroke-width="3"/>
</svg>

After

Width:  |  Height:  |  Size: 964 B

+36
View File
@@ -0,0 +1,36 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 300" width="100%" height="100%">
<rect width="400" height="300" rx="16" fill="#fefce8"/>
<!-- Egg Box / Carton -->
<rect x="60" y="70" width="280" height="160" rx="15" fill="#fef08a" stroke="#ca8a04" stroke-width="3"/>
<rect x="75" y="85" width="250" height="130" rx="10" fill="#fef9c3"/>
<!-- Eggs Grid -->
<!-- Row 1 -->
<ellipse cx="110" cy="115" rx="18" ry="24" fill="#fef3c7" stroke="#d97706" stroke-width="1.5"/>
<circle cx="106" cy="110" r="1.5" fill="#78350f"/><circle cx="114" cy="122" r="2" fill="#78350f"/><circle cx="112" cy="105" r="1" fill="#78350f"/>
<ellipse cx="160" cy="115" rx="18" ry="24" fill="#fef3c7" stroke="#d97706" stroke-width="1.5"/>
<circle cx="158" cy="112" r="2" fill="#78350f"/><circle cx="165" cy="120" r="1.5" fill="#78350f"/><circle cx="155" cy="124" r="2" fill="#78350f"/>
<ellipse cx="210" cy="115" rx="18" ry="24" fill="#fef3c7" stroke="#d97706" stroke-width="1.5"/>
<circle cx="208" cy="110" r="2" fill="#78350f"/><circle cx="214" cy="120" r="1.5" fill="#78350f"/>
<ellipse cx="260" cy="115" rx="18" ry="24" fill="#fef3c7" stroke="#d97706" stroke-width="1.5"/>
<circle cx="258" cy="112" r="1.5" fill="#78350f"/><circle cx="263" cy="124" r="2" fill="#78350f"/>
<!-- Row 2 -->
<ellipse cx="110" cy="175" rx="18" ry="24" fill="#fef3c7" stroke="#d97706" stroke-width="1.5"/>
<circle cx="112" cy="170" r="2" fill="#78350f"/><circle cx="107" cy="182" r="1.5" fill="#78350f"/>
<ellipse cx="160" cy="175" rx="18" ry="24" fill="#fef3c7" stroke="#d97706" stroke-width="1.5"/>
<circle cx="158" cy="175" r="1.5" fill="#78350f"/><circle cx="164" cy="180" r="2" fill="#78350f"/>
<ellipse cx="210" cy="175" rx="18" ry="24" fill="#fef3c7" stroke="#d97706" stroke-width="1.5"/>
<circle cx="206" cy="172" r="2" fill="#78350f"/><circle cx="212" cy="180" r="1.5" fill="#78350f"/>
<ellipse cx="260" cy="175" rx="18" ry="24" fill="#fef3c7" stroke="#d97706" stroke-width="1.5"/>
<circle cx="258" cy="170" r="1.5" fill="#78350f"/><circle cx="265" cy="178" r="2" fill="#78350f"/>
<!-- Ribbon Badge -->
<rect x="270" y="60" width="45" height="25" rx="5" fill="#e11d48"/>
<text x="292" y="77" font-size="11" font-weight="bold" fill="#fff" text-anchor="middle">۱۲ عددی</text>
</svg>

After

Width:  |  Height:  |  Size: 2.3 KiB

+19
View File
@@ -0,0 +1,19 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 300" width="100%" height="100%">
<rect width="400" height="300" rx="16" fill="#fffbeb"/>
<!-- Bag / Sack -->
<path d="M 130 80 L 270 80 L 285 240 L 115 240 Z" fill="#d97706" stroke="#92400e" stroke-width="3"/>
<!-- Bag Fold Top -->
<rect x="120" y="65" width="160" height="25" rx="6" fill="#b45309"/>
<!-- Stitching line -->
<path d="M 125 78 L 275 78" stroke="#fef3c7" stroke-dasharray="6,4" stroke-width="2"/>
<!-- Label on bag -->
<rect x="145" y="110" width="110" height="90" rx="8" fill="#ffffff" stroke="#b45309" stroke-width="2"/>
<text x="200" y="135" font-size="12" font-family="sans-serif" font-weight="bold" fill="#92400e" text-anchor="middle">خوراک بلدرچین</text>
<text x="200" y="155" font-size="10" font-family="sans-serif" font-weight="bold" fill="#16a34a" text-anchor="middle">پروتئین ۲۴٪</text>
<text x="200" y="180" font-size="14" font-family="sans-serif" font-weight="bold" fill="#d97706" text-anchor="middle">۲۵ KG</text>
<!-- Pellets scattered -->
<ellipse cx="295" cy="235" rx="6" ry="3" fill="#78350f"/>
<ellipse cx="310" cy="240" rx="7" ry="4" fill="#92400e"/>
<ellipse cx="320" cy="230" rx="5" ry="3" fill="#78350f"/>
<ellipse cx="300" cy="245" rx="6" ry="3" fill="#b45309"/>
</svg>

After

Width:  |  Height:  |  Size: 1.3 KiB

@@ -0,0 +1,17 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 300" width="100%" height="100%">
<rect width="400" height="300" rx="16" fill="#f0fdf4"/>
<circle cx="200" cy="150" r="100" fill="#dcfce7"/>
<!-- Single Large Fertile Egg -->
<ellipse cx="200" cy="150" rx="65" ry="90" fill="#fef3c7" stroke="#b45309" stroke-width="3"/>
<!-- Natural Spots -->
<circle cx="180" cy="120" r="5" fill="#78350f"/>
<circle cx="215" cy="135" r="7" fill="#78350f"/>
<circle cx="170" cy="160" r="6" fill="#78350f"/>
<circle cx="225" cy="175" r="4" fill="#78350f"/>
<circle cx="195" cy="190" r="8" fill="#78350f"/>
<circle cx="160" cy="130" r="3" fill="#78350f"/>
<circle cx="230" cy="110" r="3" fill="#78350f"/>
<!-- Hatching Sparkles -->
<path d="M 280 80 L 290 100 L 310 110 L 290 120 L 280 140 L 270 120 L 250 110 L 270 100 Z" fill="#16a34a" opacity="0.8"/>
<text x="200" y="270" font-size="14" font-weight="bold" font-family="sans-serif" fill="#15803d" text-anchor="middle">هچ بالای ۸۵٪ - نطفه‌دار تضمینی</text>
</svg>

After

Width:  |  Height:  |  Size: 1.0 KiB

+49
View File
@@ -0,0 +1,49 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 300" width="100%" height="100%">
<defs>
<linearGradient id="bgGrad" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#fef3c7"/>
<stop offset="100%" stop-color="#d97706"/>
</linearGradient>
<linearGradient id="quailBody" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#78350f"/>
<stop offset="50%" stop-color="#92400e"/>
<stop offset="100%" stop-color="#b45309"/>
</linearGradient>
<linearGradient id="quailBreast" x1="0%" y1="0%" x2="100%" y2="100%">
<stop offset="0%" stop-color="#fef3c7"/>
<stop offset="100%" stop-color="#fde68a"/>
</linearGradient>
</defs>
<rect width="400" height="300" rx="16" fill="url(#bgGrad)" opacity="0.15"/>
<circle cx="200" cy="150" r="110" fill="#fef9c3" opacity="0.6"/>
<!-- Quail Body -->
<ellipse cx="200" cy="170" rx="75" ry="55" fill="url(#quailBody)"/>
<!-- Wing -->
<path d="M 160 145 C 190 140 230 160 250 185 C 230 200 180 190 155 170 Z" fill="#451a03"/>
<!-- Wing feathers detail -->
<path d="M 175 155 C 195 155 220 170 235 185" stroke="#fef3c7" stroke-width="2" fill="none"/>
<path d="M 180 165 C 195 165 215 178 225 190" stroke="#fef3c7" stroke-width="2" fill="none"/>
<!-- Breast -->
<path d="M 140 150 C 130 175 145 205 175 215 C 150 195 145 170 150 150 Z" fill="url(#quailBreast)"/>
<!-- Speckles -->
<circle cx="155" cy="175" r="2" fill="#78350f"/>
<circle cx="160" cy="185" r="2.5" fill="#78350f"/>
<circle cx="150" cy="190" r="2" fill="#78350f"/>
<circle cx="165" cy="195" r="2" fill="#78350f"/>
<!-- Head -->
<circle cx="140" cy="130" r="30" fill="#78350f"/>
<!-- Eye Stripe -->
<path d="M 120 128 Q 140 120 165 126" stroke="#fef3c7" stroke-width="4" fill="none" stroke-linecap="round"/>
<!-- Eye -->
<circle cx="135" cy="126" r="5" fill="#000"/>
<circle cx="134" cy="124" r="1.5" fill="#fff"/>
<!-- Beak -->
<path d="M 115 128 L 95 133 L 115 138 Z" fill="#d97706"/>
<!-- Crown Plume (Crest) -->
<path d="M 135 105 Q 125 85 110 90 Q 125 95 132 105" fill="#451a03"/>
<!-- Legs -->
<path d="M 185 220 L 180 260 M 180 260 L 165 265 M 180 260 L 185 267 M 180 260 L 172 268" stroke="#d97706" stroke-width="4" stroke-linecap="round"/>
<path d="M 215 220 L 210 260 M 210 260 L 195 265 M 210 260 L 215 267 M 210 260 L 202 268" stroke="#d97706" stroke-width="4" stroke-linecap="round"/>
<!-- Grass ground -->
<path d="M 60 270 Q 200 255 340 270" stroke="#16a34a" stroke-width="6" fill="none" stroke-linecap="round"/>
</svg>

After

Width:  |  Height:  |  Size: 2.5 KiB

+21
View File
@@ -0,0 +1,21 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 300" width="100%" height="100%">
<rect width="400" height="300" rx="16" fill="#eff6ff"/>
<!-- Tray / Packaging Base -->
<rect x="70" y="80" width="260" height="150" rx="20" fill="#0284c7" opacity="0.2"/>
<rect x="80" y="90" width="240" height="130" rx="14" fill="#ffffff" stroke="#0284c7" stroke-width="3"/>
<!-- Cleaned Quail Meat 1 -->
<ellipse cx="150" cy="155" rx="40" ry="30" fill="#fed7aa" stroke="#fb923c" stroke-width="2"/>
<ellipse cx="135" cy="140" rx="18" ry="14" fill="#fed7aa" stroke="#fb923c" stroke-width="1.5"/>
<path d="M 175 160 Q 195 175 190 185 Q 175 180 165 170" fill="#fdba74" stroke="#ea580c" stroke-width="1.5"/>
<!-- Cleaned Quail Meat 2 -->
<ellipse cx="240" cy="155" rx="40" ry="30" fill="#fed7aa" stroke="#fb923c" stroke-width="2"/>
<ellipse cx="225" cy="140" rx="18" ry="14" fill="#fed7aa" stroke="#fb923c" stroke-width="1.5"/>
<path d="M 265 160 Q 285 175 280 185 Q 265 180 255 170" fill="#fdba74" stroke="#ea580c" stroke-width="1.5"/>
<!-- Plastic Wrap Gloss -->
<path d="M 90 100 L 290 120" stroke="#ffffff" stroke-width="4" stroke-linecap="round" opacity="0.8"/>
<path d="M 100 120 L 220 135" stroke="#ffffff" stroke-width="2" stroke-linecap="round" opacity="0.6"/>
<!-- Fresh Organic Stamp -->
<circle cx="285" cy="115" r="24" fill="#16a34a"/>
<text x="285" y="113" font-size="10" font-family="sans-serif" font-weight="bold" fill="#fff" text-anchor="middle">کشتار</text>
<text x="285" y="125" font-size="9" font-family="sans-serif" font-weight="bold" fill="#fff" text-anchor="middle">روز</text>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

+8
View File
@@ -0,0 +1,8 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 400 300" width="100%" height="100%">
<rect width="400" height="300" rx="16" fill="#f1f5f9"/>
<!-- Cardboard Box -->
<polygon points="120,100 200,60 280,100 200,140" fill="#d97706"/>
<polygon points="120,100 200,140 200,230 120,190" fill="#b45309"/>
<polygon points="200,140 280,100 280,190 200,230" fill="#92400e"/>
<text x="200" y="185" font-size="12" font-weight="bold" fill="#fef3c7" text-anchor="middle">بسته‌بندی صادراتی</text>
</svg>

After

Width:  |  Height:  |  Size: 522 B

+103
View File
@@ -0,0 +1,103 @@
<?php
declare(strict_types=1);
namespace Bildirchin;
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
// Autoloader for Bildirchin namespace
spl_autoload_register(function ($class) {
$prefix = 'Bildirchin\\';
$baseDir = __DIR__ . '/../src/';
$len = strlen($prefix);
if (strncmp($prefix, $class, $len) !== 0) {
return;
}
$relativeClass = substr($class, $len);
$file = $baseDir . str_replace('\\', '/', $relativeClass) . '.php';
if (file_exists($file)) {
require $file;
}
});
// Initialize database schema & seed if needed
Database::getConnection();
// Parse Request URI
$requestUri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH) ?? '/';
$requestMethod = $_SERVER['REQUEST_METHOD'];
// Simple routing system
if ($requestUri === '/' || $requestUri === '') {
(new Controllers\HomeController())->index();
} elseif ($requestUri === '/about') {
(new Controllers\HomeController())->about();
} elseif ($requestUri === '/contact') {
(new Controllers\HomeController())->contact();
} elseif ($requestUri === '/products') {
(new Controllers\ProductController())->index();
} elseif (preg_match('#^/product/([a-zA-Z0-9_-]+)$#', $requestUri, $matches)) {
(new Controllers\ProductController())->detail($matches[1]);
} elseif ($requestUri === '/cart') {
(new Controllers\CartController())->index();
} elseif ($requestUri === '/cart/add' && $requestMethod === 'POST') {
(new Controllers\CartController())->add();
} elseif ($requestUri === '/cart/update' && $requestMethod === 'POST') {
(new Controllers\CartController())->update();
} elseif ($requestUri === '/cart/remove') {
(new Controllers\CartController())->remove();
} elseif ($requestUri === '/checkout') {
(new Controllers\OrderController())->checkout();
} elseif ($requestUri === '/order/submit' && $requestMethod === 'POST') {
(new Controllers\OrderController())->submit();
} elseif ($requestUri === '/order/success') {
(new Controllers\OrderController())->success();
} elseif ($requestUri === '/track') {
(new Controllers\OrderController())->track();
} elseif ($requestUri === '/wholesale') {
(new Controllers\WholesaleController())->index();
} elseif ($requestUri === '/wholesale/inquiry' && $requestMethod === 'POST') {
(new Controllers\WholesaleController())->submitInquiry();
} elseif ($requestUri === '/blog') {
(new Controllers\BlogController())->index();
} elseif (preg_match('#^/blog/([a-zA-Z0-9_-]+)$#', $requestUri, $matches)) {
(new Controllers\BlogController())->detail($matches[1]);
} elseif ($requestUri === '/api/wholesale/calculate') {
(new Controllers\ApiController())->calculateWholesale();
}
// Admin Routes
elseif ($requestUri === '/admin' || $requestUri === '/admin/dashboard') {
(new Controllers\AdminController())->dashboard();
} elseif ($requestUri === '/admin/login') {
(new Controllers\AdminController())->login();
} elseif ($requestUri === '/admin/logout') {
(new Controllers\AdminController())->logout();
} elseif ($requestUri === '/admin/products') {
(new Controllers\AdminController())->products();
} elseif ($requestUri === '/admin/product/save' && $requestMethod === 'POST') {
(new Controllers\AdminController())->productSave();
} elseif ($requestUri === '/admin/product/delete' && $requestMethod === 'POST') {
(new Controllers\AdminController())->productDelete();
} elseif ($requestUri === '/admin/orders') {
(new Controllers\AdminController())->orders();
} elseif (preg_match('#^/admin/order/([0-9]+)$#', $requestUri, $matches)) {
(new Controllers\AdminController())->orderDetail((int)$matches[1]);
} elseif ($requestUri === '/admin/order/update-status' && $requestMethod === 'POST') {
(new Controllers\AdminController())->orderUpdateStatus();
} elseif (preg_match('#^/admin/invoice/([0-9]+)$#', $requestUri, $matches)) {
(new Controllers\AdminController())->invoice((int)$matches[1]);
} elseif ($requestUri === '/admin/wholesale-inquiries') {
(new Controllers\AdminController())->wholesaleInquiries();
} elseif ($requestUri === '/admin/wholesale-inquiry/update-status' && $requestMethod === 'POST') {
(new Controllers\AdminController())->inquiryUpdateStatus();
} elseif ($requestUri === '/admin/settings') {
(new Controllers\AdminController())->settings();
} else {
http_response_code(404);
require __DIR__ . '/../views/pages/404.php';
}