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
Binary file not shown.
+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';
}
+20
View File
@@ -0,0 +1,20 @@
<?php
declare(strict_types=1);
namespace Bildirchin;
class Config
{
public const APP_NAME = 'مزرعه و مجتمع پرورشی بلدرچین زرین';
public const APP_SLOGAN = 'تولید و عرضه مستقیم بلدرچین گوشتی و زنده، تخم خوراکی و نطفه‌دار، دان باکیفیت و ملزومات پرورش';
public const DB_PATH = __DIR__ . '/../data/database.sqlite';
public const ADMIN_USER = 'admin';
public const ADMIN_PASS = 'admin123';
public const CURRENCY = 'تومان';
public const PHONE = '09121234567';
public const PHONE_LANDLINE = '02188889999';
public const WHATSAPP = '09121234567';
public const TELEGRAM = 'bildirchin_zarrin';
public const ADDRESS = 'تهران، جاده مخصوص، بعد از پل ایران‌خودرو، کیلومتر ۲۲، مزرعه صنعتی بلدرچین زرین';
public const EMAIL = 'info@bildirchin.msa.artacloud.ir';
}
+226
View File
@@ -0,0 +1,226 @@
<?php
declare(strict_types=1);
namespace Bildirchin\Controllers;
use Bildirchin\Models\Admin;
use Bildirchin\Models\Product;
use Bildirchin\Models\Category;
use Bildirchin\Models\Order;
use Bildirchin\Models\WholesaleInquiry;
use Bildirchin\Models\Article;
use Bildirchin\Models\Setting;
use Bildirchin\Helpers;
class AdminController
{
private function checkAuth(): void
{
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
if (empty($_SESSION['admin_logged_in'])) {
header('Location: /admin/login');
exit;
}
}
public function login(): void
{
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
if (!empty($_SESSION['admin_logged_in'])) {
header('Location: /admin/dashboard');
exit;
}
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$username = trim($_POST['username'] ?? '');
$password = trim($_POST['password'] ?? '');
$admin = Admin::authenticate($username, $password);
if ($admin) {
$_SESSION['admin_logged_in'] = true;
$_SESSION['admin_user'] = $admin;
header('Location: /admin/dashboard');
exit;
} else {
Helpers::flash('error', 'نام کاربری یا کلمه عبور اشتباه است.');
}
}
require __DIR__ . '/../../views/admin/login.php';
}
public function logout(): void
{
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
unset($_SESSION['admin_logged_in'], $_SESSION['admin_user']);
header('Location: /admin/login');
exit;
}
public function dashboard(): void
{
$this->checkAuth();
$stats = Order::getStats();
$recentOrders = Order::all(8);
$recentInquiries = WholesaleInquiry::all(5);
require __DIR__ . '/../../views/admin/dashboard.php';
}
public function products(): void
{
$this->checkAuth();
$categories = Category::all();
$products = Product::all(100);
require __DIR__ . '/../../views/admin/products.php';
}
public function productSave(): void
{
$this->checkAuth();
$id = (int)($_POST['id'] ?? 0);
$name = Helpers::sanitize($_POST['name'] ?? '');
$categoryId = (int)($_POST['category_id'] ?? 1);
$slug = Helpers::sanitize($_POST['slug'] ?? '');
if (!$slug) {
$slug = 'product-' . time();
}
$data = [
'category_id' => $categoryId,
'name' => $name,
'slug' => $slug,
'short_desc' => Helpers::sanitize($_POST['short_desc'] ?? ''),
'full_desc' => Helpers::sanitize($_POST['full_desc'] ?? ''),
'price' => (float)($_POST['price'] ?? 0),
'unit' => Helpers::sanitize($_POST['unit'] ?? 'عدد'),
'stock' => (int)($_POST['stock'] ?? 0),
'image' => Helpers::sanitize($_POST['image'] ?? '/assets/images/quail_live.svg'),
'is_wholesale_available' => isset($_POST['is_wholesale_available']) ? 1 : 0,
'wholesale_min_qty' => (int)($_POST['wholesale_min_qty'] ?? 50),
'wholesale_price' => (float)($_POST['wholesale_price'] ?? 0),
'wholesale_tier2_qty' => (int)($_POST['wholesale_tier2_qty'] ?? 200),
'wholesale_tier2_price' => (float)($_POST['wholesale_tier2_price'] ?? 0),
'is_featured' => isset($_POST['is_featured']) ? 1 : 0
];
if ($id > 0) {
Product::update($id, $data);
Helpers::flash('success', 'محصول با موفقیت به‌روزرسانی شد.');
} else {
Product::create($data);
Helpers::flash('success', 'محصول جدید با موفقیت اضافه شد.');
}
header('Location: /admin/products');
exit;
}
public function productDelete(): void
{
$this->checkAuth();
$id = (int)($_POST['id'] ?? 0);
if ($id > 0) {
Product::delete($id);
Helpers::flash('success', 'محصول با موفقیت حذف شد.');
}
header('Location: /admin/products');
exit;
}
public function orders(): void
{
$this->checkAuth();
$status = $_GET['status'] ?? null;
$orders = Order::all(100, $status);
require __DIR__ . '/../../views/admin/orders.php';
}
public function orderDetail(int $id): void
{
$this->checkAuth();
$order = Order::findById($id);
if (!$order) {
header('Location: /admin/orders');
exit;
}
require __DIR__ . '/../../views/admin/order_detail.php';
}
public function orderUpdateStatus(): void
{
$this->checkAuth();
$id = (int)($_POST['order_id'] ?? 0);
$status = Helpers::sanitize($_POST['status'] ?? 'pending');
if ($id > 0) {
Order::updateStatus($id, $status);
Helpers::flash('success', 'وضعیت سفارش به‌روزرسانی شد.');
}
header('Location: /admin/order/' . $id);
exit;
}
public function invoice(int $id): void
{
$this->checkAuth();
$order = Order::findById($id);
if (!$order) {
die('سفارش یافت نشد');
}
$settings = Setting::getAll();
require __DIR__ . '/../../views/admin/invoice.php';
}
public function wholesaleInquiries(): void
{
$this->checkAuth();
$inquiries = WholesaleInquiry::all(100);
require __DIR__ . '/../../views/admin/wholesale_inquiries.php';
}
public function inquiryUpdateStatus(): void
{
$this->checkAuth();
$id = (int)($_POST['id'] ?? 0);
$status = Helpers::sanitize($_POST['status'] ?? 'reviewed');
if ($id > 0) {
WholesaleInquiry::updateStatus($id, $status);
Helpers::flash('success', 'وضعیت درخواست همکاری به‌روز شد.');
}
header('Location: /admin/wholesale-inquiries');
exit;
}
public function settings(): void
{
$this->checkAuth();
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
foreach ($_POST as $k => $v) {
if ($k !== 'csrf') {
Setting::set($k, trim((string)$v));
}
}
Helpers::flash('success', 'تنظیمات فروشگاه با موفقیت ذخیره شد.');
header('Location: /admin/settings');
exit;
}
$settings = Setting::getAll();
require __DIR__ . '/../../views/admin/settings.php';
}
}
+38
View File
@@ -0,0 +1,38 @@
<?php
declare(strict_types=1);
namespace Bildirchin\Controllers;
use Bildirchin\Models\Product;
use Bildirchin\Helpers;
class ApiController
{
public function calculateWholesale(): void
{
$productId = (int)($_GET['product_id'] ?? 0);
$quantity = max(1, (int)($_GET['quantity'] ?? 1));
$product = Product::findById($productId);
if (!$product) {
Helpers::jsonResponse(['success' => false, 'message' => 'محصول یافت نشد'], 404);
}
$calc = Product::calculateUnitPrice($product, $quantity);
Helpers::jsonResponse([
'success' => true,
'product_name' => $product['name'],
'quantity' => $quantity,
'unit' => $product['unit'],
'unit_price' => $calc['unit_price'],
'unit_price_formatted' => Helpers::formatPrice($calc['unit_price']),
'regular_price_formatted' => Helpers::formatPrice($product['price']),
'total_price' => $calc['total_price'],
'total_price_formatted' => Helpers::formatPrice($calc['total_price']),
'is_wholesale' => $calc['is_wholesale'],
'total_saved' => $calc['total_saved'],
'total_saved_formatted' => Helpers::formatPrice($calc['total_saved'])
]);
}
}
+29
View File
@@ -0,0 +1,29 @@
<?php
declare(strict_types=1);
namespace Bildirchin\Controllers;
use Bildirchin\Models\Article;
use Bildirchin\Helpers;
class BlogController
{
public function index(): void
{
$articles = Article::all(20);
require __DIR__ . '/../../views/pages/blog.php';
}
public function detail(string $slug): void
{
$article = Article::findBySlug($slug);
if (!$article) {
http_response_code(404);
require __DIR__ . '/../../views/pages/404.php';
return;
}
$recentArticles = Article::all(4);
require __DIR__ . '/../../views/pages/blog_detail.php';
}
}
+153
View File
@@ -0,0 +1,153 @@
<?php
declare(strict_types=1);
namespace Bildirchin\Controllers;
use Bildirchin\Models\Product;
use Bildirchin\Helpers;
class CartController
{
public static function getCart(): array
{
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
return $_SESSION['cart'] ?? [];
}
public static function saveCart(array $cart): void
{
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
$_SESSION['cart'] = $cart;
}
public static function getCartDetails(): array
{
$cart = self::getCart();
$items = [];
$totalRetail = 0;
$totalFinal = 0;
$totalItemsCount = 0;
$totalSavings = 0;
foreach ($cart as $productId => $quantity) {
$product = Product::findById((int)$productId);
if (!$product) {
continue;
}
$calc = Product::calculateUnitPrice($product, (int)$quantity);
$itemRetailTotal = (float)$product['price'] * (int)$quantity;
$items[] = [
'product' => $product,
'quantity' => (int)$quantity,
'unit_price' => $calc['unit_price'],
'regular_price' => (float)$product['price'],
'total_price' => $calc['total_price'],
'is_wholesale' => $calc['is_wholesale'],
'savings' => $calc['total_saved']
];
$totalRetail += $itemRetailTotal;
$totalFinal += $calc['total_price'];
$totalItemsCount += (int)$quantity;
$totalSavings += $calc['total_saved'];
}
return [
'items' => $items,
'total_retail' => $totalRetail,
'total_final' => $totalFinal,
'total_savings' => $totalSavings,
'total_count' => $totalItemsCount
];
}
public function index(): void
{
$cartData = self::getCartDetails();
require __DIR__ . '/../../views/pages/cart.php';
}
public function add(): void
{
$productId = (int)($_POST['product_id'] ?? 0);
$quantity = max(1, (int)($_POST['quantity'] ?? 1));
$product = Product::findById($productId);
if (!$product) {
Helpers::jsonResponse(['success' => false, 'message' => 'محصول یافت نشد'], 404);
}
$cart = self::getCart();
if (isset($cart[$productId])) {
$cart[$productId] += $quantity;
} else {
$cart[$productId] = $quantity;
}
self::saveCart($cart);
if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) || (isset($_SERVER['HTTP_ACCEPT']) && strpos($_SERVER['HTTP_ACCEPT'], 'application/json') !== false)) {
$details = self::getCartDetails();
Helpers::jsonResponse([
'success' => true,
'message' => 'محصول با موفقیت به سبد خرید اضافه شد',
'cart_count' => count($details['items']),
'total_final_formatted' => Helpers::formatPrice($details['total_final'])
]);
}
Helpers::flash('success', 'محصول به سبد خرید اضافه شد');
header('Location: /cart');
exit;
}
public function update(): void
{
$productId = (int)($_POST['product_id'] ?? 0);
$quantity = (int)($_POST['quantity'] ?? 1);
$cart = self::getCart();
if ($quantity <= 0) {
unset($cart[$productId]);
} else {
$cart[$productId] = $quantity;
}
self::saveCart($cart);
$details = self::getCartDetails();
Helpers::jsonResponse([
'success' => true,
'cart' => $details,
'cart_count' => count($details['items']),
'total_final_formatted' => Helpers::formatPrice($details['total_final']),
'total_savings_formatted' => Helpers::formatPrice($details['total_savings'])
]);
}
public function remove(): void
{
$productId = (int)($_POST['product_id'] ?? 0);
$cart = self::getCart();
unset($cart[$productId]);
self::saveCart($cart);
Helpers::flash('success', 'محصول از سبد خرید حذف شد');
header('Location: /cart');
exit;
}
public static function clear(): void
{
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
unset($_SESSION['cart']);
}
}
+34
View File
@@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
namespace Bildirchin\Controllers;
use Bildirchin\Models\Product;
use Bildirchin\Models\Category;
use Bildirchin\Models\Article;
use Bildirchin\Models\Setting;
class HomeController
{
public function index(): void
{
$categories = Category::all();
$featuredProducts = Product::featured();
$latestArticles = Article::all(3);
$settings = Setting::getAll();
require __DIR__ . '/../../views/pages/home.php';
}
public function about(): void
{
$settings = Setting::getAll();
require __DIR__ . '/../../views/pages/about.php';
}
public function contact(): void
{
$settings = Setting::getAll();
require __DIR__ . '/../../views/pages/contact.php';
}
}
+119
View File
@@ -0,0 +1,119 @@
<?php
declare(strict_types=1);
namespace Bildirchin\Controllers;
use Bildirchin\Models\Order;
use Bildirchin\Models\Setting;
use Bildirchin\Helpers;
class OrderController
{
public function checkout(): void
{
$cartData = CartController::getCartDetails();
if (empty($cartData['items'])) {
header('Location: /cart');
exit;
}
$settings = Setting::getAll();
require __DIR__ . '/../../views/pages/checkout.php';
}
public function submit(): void
{
$cartData = CartController::getCartDetails();
if (empty($cartData['items'])) {
header('Location: /cart');
exit;
}
$name = Helpers::sanitize($_POST['customer_name'] ?? '');
$phone = Helpers::sanitize($_POST['customer_phone'] ?? '');
$province = Helpers::sanitize($_POST['province'] ?? '');
$city = Helpers::sanitize($_POST['city'] ?? '');
$address = Helpers::sanitize($_POST['address'] ?? '');
$postalCode = Helpers::sanitize($_POST['postal_code'] ?? '');
$notes = Helpers::sanitize($_POST['notes'] ?? '');
$shippingMethod = Helpers::sanitize($_POST['shipping_method'] ?? 'باربری');
$paymentMethod = Helpers::sanitize($_POST['payment_method'] ?? 'کارت به کارت');
if (!$name || !$phone || !$address) {
Helpers::flash('error', 'لطفا نام، شماره تماس و آدرس را به طور کامل وارد نمایید.');
header('Location: /checkout');
exit;
}
$orderCode = Helpers::generateOrderCode();
$orderData = [
'order_code' => $orderCode,
'customer_name' => $name,
'customer_phone' => $phone,
'customer_email' => Helpers::sanitize($_POST['customer_email'] ?? ''),
'province' => $province,
'city' => $city,
'address' => $address,
'postal_code' => $postalCode,
'notes' => $notes,
'shipping_method' => $shippingMethod,
'payment_method' => $paymentMethod,
'total_amount' => $cartData['total_retail'],
'discount_amount' => $cartData['total_savings'],
'final_amount' => $cartData['total_final']
];
$orderItems = [];
foreach ($cartData['items'] as $item) {
$orderItems[] = [
'product_id' => $item['product']['id'],
'product_name' => $item['product']['name'],
'quantity' => $item['quantity'],
'unit_price' => $item['unit_price'],
'total_price' => $item['total_price'],
'is_wholesale' => $item['is_wholesale']
];
}
try {
$orderId = Order::create($orderData, $orderItems);
CartController::clear();
header('Location: /order/success?code=' . urlencode($orderCode));
exit;
} catch (\Throwable $e) {
Helpers::flash('error', 'خطایی در ثبت سفارش رخ داد: ' . $e->getMessage());
header('Location: /checkout');
exit;
}
}
public function success(): void
{
$code = $_GET['code'] ?? '';
$order = Order::findByCode($code);
if (!$order) {
header('Location: /');
exit;
}
$settings = Setting::getAll();
require __DIR__ . '/../../views/pages/order_success.php';
}
public function track(): void
{
$order = null;
$searched = false;
if ($_SERVER['REQUEST_METHOD'] === 'POST' || isset($_GET['code'])) {
$code = trim($_POST['order_code'] ?? ($_GET['code'] ?? ''));
if ($code) {
$searched = true;
$order = Order::findByCode($code);
}
}
require __DIR__ . '/../../views/pages/track_order.php';
}
}
+36
View File
@@ -0,0 +1,36 @@
<?php
declare(strict_types=1);
namespace Bildirchin\Controllers;
use Bildirchin\Models\Product;
use Bildirchin\Models\Category;
use Bildirchin\Helpers;
class ProductController
{
public function index(): void
{
$categoryId = isset($_GET['cat']) ? (int)$_GET['cat'] : null;
$search = isset($_GET['q']) ? trim($_GET['q']) : null;
$categories = Category::all();
$products = Product::all(100, $categoryId, $search);
$selectedCategory = $categoryId ? Category::findById($categoryId) : null;
require __DIR__ . '/../../views/pages/products.php';
}
public function detail(string $slug): void
{
$product = Product::findBySlug($slug);
if (!$product) {
http_response_code(404);
require __DIR__ . '/../../views/pages/404.php';
return;
}
$relatedProducts = Product::all(4, (int)$product['category_id']);
require __DIR__ . '/../../views/pages/product_detail.php';
}
}
+50
View File
@@ -0,0 +1,50 @@
<?php
declare(strict_types=1);
namespace Bildirchin\Controllers;
use Bildirchin\Models\Product;
use Bildirchin\Models\WholesaleInquiry;
use Bildirchin\Models\Setting;
use Bildirchin\Helpers;
class WholesaleController
{
public function index(): void
{
$wholesaleProducts = array_filter(Product::all(100), fn($p) => (int)$p['is_wholesale_available'] === 1);
$settings = Setting::getAll();
require __DIR__ . '/../../views/pages/wholesale.php';
}
public function submitInquiry(): void
{
$name = Helpers::sanitize($_POST['customer_name'] ?? '');
$phone = Helpers::sanitize($_POST['phone'] ?? '');
$company = Helpers::sanitize($_POST['company_name'] ?? '');
$product = Helpers::sanitize($_POST['product_requested'] ?? '');
$qty = Helpers::sanitize($_POST['estimated_qty'] ?? '');
$city = Helpers::sanitize($_POST['city'] ?? '');
$notes = Helpers::sanitize($_POST['notes'] ?? '');
if (!$name || !$phone || !$product) {
Helpers::flash('error', 'لطفاً نام، شماره تماس و محصول مورد نظر را وارد نمایید.');
header('Location: /wholesale');
exit;
}
WholesaleInquiry::create([
'customer_name' => $name,
'phone' => $phone,
'company_name' => $company,
'product_requested' => $product,
'estimated_qty' => $qty,
'city' => $city,
'notes' => $notes
]);
Helpers::flash('success', 'درخواست همکاری و استعلام قیمت عمده شما با موفقیت ثبت شد. کارشناسان مزرعه در اسرع وقت با شما تماس خواهند گرفت.');
header('Location: /wholesale#success');
exit;
}
}
+198
View File
@@ -0,0 +1,198 @@
<?php
declare(strict_types=1);
namespace Bildirchin;
use PDO;
use PDOException;
class Database
{
private static ?PDO $instance = null;
public static function getConnection(): PDO
{
if (self::$instance === null) {
$dbPath = Config::DB_PATH;
$dir = dirname($dbPath);
if (!is_dir($dir)) {
mkdir($dir, 0777, true);
}
try {
self::$instance = new PDO("sqlite:" . $dbPath);
self::$instance->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
self::$instance->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
self::initSchema(self::$instance);
} catch (PDOException $e) {
die("خطا در اتصال به پایگاه داده: " . $e->getMessage());
}
}
return self::$instance;
}
private static function initSchema(PDO $db): void
{
$db->exec("
CREATE TABLE IF NOT EXISTS categories (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
slug TEXT NOT NULL UNIQUE,
icon TEXT,
description TEXT,
sort_order INTEGER DEFAULT 0
);
CREATE TABLE IF NOT EXISTS products (
id INTEGER PRIMARY KEY AUTOINCREMENT,
category_id INTEGER NOT NULL,
name TEXT NOT NULL,
slug TEXT NOT NULL UNIQUE,
short_desc TEXT,
full_desc TEXT,
price REAL NOT NULL,
unit TEXT NOT NULL DEFAULT 'عدد',
stock INTEGER DEFAULT 100,
image TEXT,
is_wholesale_available INTEGER DEFAULT 1,
wholesale_min_qty INTEGER DEFAULT 50,
wholesale_price REAL DEFAULT 0,
wholesale_tier2_qty INTEGER DEFAULT 200,
wholesale_tier2_price REAL DEFAULT 0,
is_featured INTEGER DEFAULT 0,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
FOREIGN KEY (category_id) REFERENCES categories(id)
);
CREATE TABLE IF NOT EXISTS orders (
id INTEGER PRIMARY KEY AUTOINCREMENT,
order_code TEXT NOT NULL UNIQUE,
customer_name TEXT NOT NULL,
customer_phone TEXT NOT NULL,
customer_email TEXT,
province TEXT,
city TEXT,
address TEXT,
postal_code TEXT,
notes TEXT,
shipping_method TEXT,
payment_method TEXT,
total_amount REAL NOT NULL,
discount_amount REAL DEFAULT 0,
final_amount REAL NOT NULL,
status TEXT DEFAULT 'pending',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS order_items (
id INTEGER PRIMARY KEY AUTOINCREMENT,
order_id INTEGER NOT NULL,
product_id INTEGER NOT NULL,
product_name TEXT NOT NULL,
quantity INTEGER NOT NULL,
unit_price REAL NOT NULL,
total_price REAL NOT NULL,
is_wholesale INTEGER DEFAULT 0,
FOREIGN KEY (order_id) REFERENCES orders(id)
);
CREATE TABLE IF NOT EXISTS wholesale_inquiries (
id INTEGER PRIMARY KEY AUTOINCREMENT,
customer_name TEXT NOT NULL,
phone TEXT NOT NULL,
company_name TEXT,
product_requested TEXT NOT NULL,
estimated_qty TEXT,
city TEXT,
notes TEXT,
status TEXT DEFAULT 'new',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS articles (
id INTEGER PRIMARY KEY AUTOINCREMENT,
title TEXT NOT NULL,
slug TEXT NOT NULL UNIQUE,
summary TEXT,
content TEXT,
image TEXT,
author TEXT DEFAULT 'مدیریت مزرعه',
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS settings (
key TEXT PRIMARY KEY,
value TEXT
);
CREATE TABLE IF NOT EXISTS admins (
id INTEGER PRIMARY KEY AUTOINCREMENT,
username TEXT NOT NULL UNIQUE,
password_hash TEXT NOT NULL,
display_name TEXT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
");
self::seedInitialData($db);
}
private static function seedInitialData(PDO $db): void
{
$stmt = $db->query("SELECT COUNT(*) as count FROM categories");
if ((int)$stmt->fetch()['count'] === 0) {
// Seed Categories
$db->exec("
INSERT INTO categories (name, slug, icon, description, sort_order) VALUES
('بلدرچین گوشتی و زنده', 'quail-birds', 'fas fa-feather-alt', 'انواع بلدرچین زنده، کشتار روز، منجمد و جوجه پرورشی', 1),
('تخم بلدرچین (خوراکی و نطفه‌دار)', 'quail-eggs', 'fas fa-egg', 'تخم خوراکی تازه بسته‌بندی و تخم نطفه‌دار جوجه‌کشی با هچ بالا', 2),
('دان و خوراک تخصصی', 'quail-feed', 'fas fa-seedling', 'دان پلت و آردی استارتر، رشد و تخم‌گذار با آنالیز دقیق پروتئین', 3),
('تجهیزات و ملزومات پرورش', 'equipment', 'fas fa-warehouse', 'قفس‌های استاندارد، آبخوری، دانخوری و شانه و کارتن بسته‌بندی', 4);
");
// Seed Products
$db->exec("
INSERT INTO products (category_id, name, slug, short_desc, full_desc, price, unit, stock, image, is_wholesale_available, wholesale_min_qty, wholesale_price, wholesale_tier2_qty, wholesale_tier2_price, is_featured) VALUES
(1, 'بلدرچین گوشتی کشتار روز (بسته ۴ عددی)', 'quail-meat-4pack', 'گوشت تازه بلدرچین کشتار روز، پاک‌شده و وکیوم بهداشتی تحت نظارت دامپزشکی', 'گوشت بلدرچین تازه کشتار روز مزرعه زرین، پاک‌شده کامل بدون امعاء و احشاء و بدون کله و پا، شسته‌شده با آب سرد بهداشتی و بسته‌بندی وکیوم شده در ظروف کریستالی مقاوم تحت نظارت مستقیم کارشناسان سازمان دامپزشکی کل کشور. گوشت بلدرچین منبعی بی‌نظیر از فسفر، آهن و پروتئین بدون چربی مضر است.', 185000, 'بسته', 250, '/assets/images/quail_meat.svg', 1, 20, 165000, 100, 150000, 1),
(1, 'بلدرچین زنده بالغ پرواری (سنگین وزن)', 'live-quail-adult', 'بلدرچین زنده نژاد سنگین سنگین ژاپنی، وزن میانگین ۲۲۰ الی ۲۶۰ گرم، کاملا سالم و واکسینه‌شده', 'بلدرچین‌های زنده گله مولد و پرواری نژاد ژاپنی اصلاح شده سنگین وزن (وزن زنده بین ۲۲۰ الی ۲۶۰ گرم). تغذیه شده با بهترین جیره سوپراستارتر و دان ارگانیک فاقد آنتی‌بیوتیک، مناسب جهت کشتارگاه‌ها، رستوران‌های سنتی و سالن‌های پرورشی سراسر کشور.', 58000, 'قطعه', 1500, '/assets/images/quail_live.svg', 1, 100, 49000, 500, 44000, 1),
(1, 'جوجه بلدرچین یک‌روزه اصلاح‌نژاد شده', 'quail-chick-1day', 'جوجه بلدرچین یک‌روزه نژاد سنگین تخم‌گذار و گوشتی با راندمان رشد فوق‌العاده', 'تولید هفتگی بیش از ۲۰ هزار قطعه جوجه بلدرچین یک‌روزه هچ شده در انکوباتورهای تمام‌اتوماتیک مزرعه. تفکیک شده، ضدعفونی شده و بسیار سرزنده با تضمین کمترین میزان تلفات حین حمل در کارتن‌های تهویه‌دار مخصوص.', 12000, 'قطعه', 3000, '/assets/images/quail_chick.svg', 1, 500, 9500, 2000, 8000, 0),
(2, 'تخم بلدرچین خوراکی تازه (بسته ۱۲ عددی)', 'quail-edible-eggs-12', 'تخم بلدرچین ارگانیک و تازه با زرده طلایی، سرشار از فسفر، آهن و ویتامین B12', 'تخم بلدرچین تازه تولید روز، جمع‌آوری شده با رعایت کامل اصول بهداشت و قرنطینه. مناسب برای تقویت سیستم ایمنی کودکان، ورزشکاران و سالمندان. بسته‌بندی کریستالی استاندارد و شفاف ۱۲ عددی.', 38000, 'بسته', 400, '/assets/images/quail_eggs_box.svg', 1, 50, 32000, 200, 28000, 1),
(2, 'تخم نطفه‌دار بلدرچین نژاد ژاپنی (هچ بالای ۸۵٪)', 'quail-fertile-eggs', 'تخم نطفه‌دار تازه روز، جمع‌آوری شده از گله مولد جوان و اصلاح‌شده، مناسب دستگاه جوجه‌کشی', 'تخم‌های نطفه‌دار با نسبت خروس به مرغ ۱ به ۳، جمع‌آوری روزانه و نگهداری در دمای استاندارد ۱۶ درجه سانتی‌گراد و رطوبت ۶۵ درصد. تضمین نطفه‌داری بالای ۹۰ درصد و راندمان هچ بیش از ۸۵ درصد در دستگاه‌های جوجه‌کشی استاندارد.', 4500, 'عدد', 5000, '/assets/images/quail_fertile_egg.svg', 1, 200, 3800, 1000, 3200, 1),
(3, 'دان استارتر سوپر بلدرچین (کیسه ۲۵ کیلویی)', 'quail-starter-feed-25kg', 'خوراک مخصوص هفته اول تا سوم، پروتئین ۲۴٪، غنی از ویتامین‌ها و اسیدهای آمینه ضروری', 'جیره فرموله شده توسط متخصصان تغذیه طیور با استفاده از کنجاله سویای باکیفیت و ذرت برزیلی درجه یک. حاوی ۲۴.۵ درصد پروتئین خام، متیونین، لیزین، کلسیم، فسفر و پرمیکس ویتامینه کامل برای حداکثر سرعت رشد جوجه‌ها.', 680000, 'کیسه', 80, '/assets/images/quail_feed_bag.svg', 1, 10, 620000, 50, 580000, 1),
(3, 'دان پلت رشد و پرواری بلدرچین (کیسه ۲۵ کیلویی)', 'quail-grower-feed-25kg', 'خوراک پلت دوره رشد و پروار بلدرچین، ضریب تبدیل عالی، وزن‌گیری سریع', 'خوراک پلت ریز ۲ میلی‌متری مخصوص سن ۲۱ روزگی تا زمان کشتار (حدود ۴۰ روزگی). پروتئین ۲۰.۵ درصد، انرژی بالا جهت رشد سریع عضلات سینه و ران با ضریب تبدیل غذایی ایده‌آل ۲.۱.', 640000, 'کیسه', 120, '/assets/images/quail_feed_bag.svg', 1, 10, 590000, 50, 550000, 0),
(3, 'دان پلت بلدرچین تخم‌گذار (کیسه ۲۵ کیلویی)', 'quail-layer-feed-25kg', 'جیره تخصصی بلدرچین تخم‌گذار حاوی کلسیم و فسفر بالانس شده جهت استحکام پوسته و ماندگاری تولید', 'جیره تقویتی ویژه گله‌های تخم‌گذار و مولد بلدرچین. حاوی ۳.۲ درصد کلسیم و پروتئین ۱۹ درصد جهت تضمین راندمان تخم‌گذاری مداوم بالای ۸۰ درصد و استحکام پوسته تخم بدون لمبه شدن.', 660000, 'کیسه', 100, '/assets/images/quail_feed_bag.svg', 1, 10, 610000, 50, 570000, 1),
(4, 'قفس ۴ طبقه مکانیزه بلدرچین (گالوانیزه گرم)', 'quail-cage-4layer', 'قفس صنعتی با گنجایش ۱۳۰ الی ۱۵۰ قطعه، مجهز به آبخوری نیپل اتوماتیک، سینی فضولات و دانخوری ضد هدررفت', 'قفس مهندسی‌ساز صنعتی ساخته شده از توری گالوانیزه گرم ضدزنگ و قابل شستشو با اسید و مواد شوینده قوی. مجهز به ۴ ردیف آبخوری نیپل با کاسه استیل، سیستم شیب تخم‌گذار جهت هدایت خودکار تخم‌ها به بیرون، و سینی گالوانیزه تخلیه سریع کود.', 4200000, 'دستگاه', 20, '/assets/images/quail_cage.svg', 1, 5, 3850000, 20, 3500000, 1),
(4, 'شانه و کارتن صادراتی بسته‌بندی تخم بلدرچین', 'quail-egg-packaging-carton', 'شانه پلاستیکی کریستالی ۱۲ عددی به همراه کارتن مادر مستحکم مناسب حمل و نقل فروشگاهی', 'شانه‌های شفاف فودگرید با قفل فشاری محکم به همراه کارتن‌های ۵ لایه صادراتی، مقاوم در برابر رطوبت و ضربات حین حمل بین‌شهری و باربری.', 4500, 'عدد', 2000, '/assets/images/quail_packaging.svg', 1, 500, 3600, 2000, 3100, 0);
");
// Seed Articles
$db->exec("
INSERT INTO articles (title, slug, summary, content, image) VALUES
('راهنمای گام به گام راه‌اندازی سالن پرورش بلدرچین', 'quail-farming-complete-guide', 'بررسی شرایط دما، رطوبت، نوردهی و اصول بهداشتی برای شروع پرورش بلدرچین گوشتی و تخم‌گذار در مقیاس خرد و صنعتی.', 'پرورش بلدرچین به دلیل دوره رشد کوتاه (حدود ۴۰ روز برای کشتار) و بلوغ زودرس جنسی (شروع تخم‌گذاری از سن ۴۵ الی ۵۰ روزگی) یکی از سودآورترین و مطمئن‌ترین شاخه‌های پرورش طیور است.\n\n### ۱. مشخصات سالن و تجهیزات:\n- دمای سالن برای جوجه‌ها در هفته اول باید حدود ۳۵ درجه سانتی‌گراد باشد و به تدریج کاهش یابد.\n- رطوبت نسبی بین ۶۰ تا ۶۵ درصد تنظیم شود.\n- سیستم تهویه باید هوای تازه را بدون ایجاد کوران مستقیم به سالن برساند.\n\n### ۲. مزایای استفاده از قفس استاندارد:\nاستفاده از قفس‌های مکانیزه به کاهش شدید بیماری‌ها، افزایش راندمان تخم‌گذاری و صرفه‌جویی در فضای سالن کمک شایانی می‌کند.', '/assets/images/article1.svg'),
('معجزه تخم بلدرچین: بمب ویتامین و خواص دارویی', 'quail-egg-benefits-and-nutrition', 'چرا پزشکان تخم بلدرچین را به عنوان یکی از کامل‌ترین منابع پروتئین و مواد معدنی برای کودکان و سالمندان توصیه می‌کنند؟', 'تخم بلدرچین با وجود جثه کوچکش، ارزش غذایی خارق‌العاده‌ای دارد. هر تخم بلدرچین حدود ۵ برابر تخم مرغ فسفر، ۶ برابر ویتامین B12 و ۷ برابر آهن دارد.\n\n### مهم‌ترین خواص تخم بلدرچین:\n۱. تقویت سیستم ایمنی بدن در برابر ویروس‌ها\n۲. رشد ذهنی و جسمی کودکان و نوجوانان\n۳. فاقد کلسترول بد (LDL) و بسیار مفید برای قلب\n۴. بهبود حافظه و پیشگیری از کم‌خونی و خستگی مفرط\n\nمصرف روزانه ۲ الی ۳ عدد تخم بلدرچین انرژی لازم برای یک روز کاری پرنشاط را تامین می‌کند.', '/assets/images/article2.svg'),
('فرمولاسیون و اهمیت کیفیت دان در وزن‌گیری بلدرچین', 'quail-feed-formulation-and-protein', 'نقش میزان پروتئین خام، کلسیم و متیونین در کاهش دوره پروار و افزایش کیفیت گوشت بلدرچین.', 'بلدرچین‌ها نیاز به پروتئین بسیار بالاتری نسبت به مرغ دارند. دان استارتر باید حداقل حاوی ۲۴ الی ۲۵ درصد پروتئین خام باشد تا عضلات سینه به سرعت رشد کنند.\n\n### ویژگی‌های دان باکیفیت مزرعه زرین:\n- استفاده از کنجاله سویای باکیفیت و ذرت درجه یک\n- بالانس دقیق اسیدهای آمینه لیزین و متیونین\n- پلت‌سازی با دمای کنترل‌شده جهت حفظ ویتامین‌ها\n- بدون استفاده از هرگونه آنتی‌بیوتیک غیرمجاز یا هورمون', '/assets/images/article3.svg');
");
// Seed Admin User
$adminPass = password_hash(Config::ADMIN_PASS, PASSWORD_DEFAULT);
$db->exec("
INSERT INTO admins (username, password_hash, display_name) VALUES
('admin', '$adminPass', 'مدیر مزرعه بلدرچین زرین');
");
// Seed Settings
$db->exec("
INSERT INTO settings (key, value) VALUES
('farm_name', 'مزرعه و مجتمع پرورشی بلدرچین زرین'),
('phone', '09121234567'),
('landline', '02188889999'),
('address', 'تهران، جاده مخصوص، کیلومتر ۲۲، مزرعه صنعتی بلدرچین زرین'),
('shipping_freight_rate', '120000'),
('free_shipping_threshold', '2000000'),
('card_number', '6037-9918-1234-5678'),
('card_holder', 'مزرعه پرورشی بلدرچین زرین - علیزاده');
");
}
}
}
+61
View File
@@ -0,0 +1,61 @@
<?php
declare(strict_types=1);
namespace Bildirchin;
class Helpers
{
public static function formatPrice(int|float $price): string
{
return self::toPersianDigits(number_format((float)$price, 0, '.', ',')) . ' ' . Config::CURRENCY;
}
public static function toPersianDigits(string|int|float $input): string
{
$en = ['0','1','2','3','4','5','6','7','8','9'];
$fa = ['۰','۱','۲','۳','۴','۵','۶','۷','۸','۹'];
return str_replace($en, $fa, (string)$input);
}
public static function sanitize(string $input): string
{
return htmlspecialchars(trim($input), ENT_QUOTES, 'UTF-8');
}
public static function jsonResponse(array $data, int $status = 200): void
{
http_response_code($status);
header('Content-Type: application/json; charset=utf-8');
echo json_encode($data, JSON_UNESCAPED_UNICODE | JSON_PRETTY_PRINT);
exit;
}
public static function flash(string $key, ?string $msg = null): ?string
{
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
if ($msg !== null) {
$_SESSION['flash'][$key] = $msg;
return null;
}
if (isset($_SESSION['flash'][$key])) {
$value = $_SESSION['flash'][$key];
unset($_SESSION['flash'][$key]);
return $value;
}
return null;
}
public static function getJalaliDate(?string $timestamp = null): string
{
$time = $timestamp ? strtotime($timestamp) : time();
$date = date('Y/m/d H:i', $time);
return self::toPersianDigits($date);
}
public static function generateOrderCode(): string
{
return 'BLD-' . strtoupper(substr(uniqid(), -6));
}
}
+34
View File
@@ -0,0 +1,34 @@
<?php
declare(strict_types=1);
namespace Bildirchin\Models;
use Bildirchin\Database;
use PDO;
class Admin
{
public static function authenticate(string $username, string $password): ?array
{
$db = Database::getConnection();
$stmt = $db->prepare("SELECT * FROM admins WHERE username = :username");
$stmt->execute([':username' => $username]);
$admin = $stmt->fetch();
if ($admin && password_verify($password, $admin['password_hash'])) {
return $admin;
}
return null;
}
public static function updatePassword(int $id, string $newPassword): bool
{
$db = Database::getConnection();
$stmt = $db->prepare("UPDATE admins SET password_hash = :hash WHERE id = :id");
return $stmt->execute([
':id' => $id,
':hash' => password_hash($newPassword, PASSWORD_DEFAULT)
]);
}
}
+53
View File
@@ -0,0 +1,53 @@
<?php
declare(strict_types=1);
namespace Bildirchin\Models;
use Bildirchin\Database;
use PDO;
class Article
{
public static function all(int $limit = 10): array
{
$db = Database::getConnection();
$stmt = $db->query("SELECT * FROM articles ORDER BY id DESC LIMIT " . (int)$limit);
return $stmt->fetchAll();
}
public static function findById(int $id): ?array
{
$db = Database::getConnection();
$stmt = $db->prepare("SELECT * FROM articles WHERE id = :id");
$stmt->execute([':id' => $id]);
$row = $stmt->fetch();
return $row ?: null;
}
public static function findBySlug(string $slug): ?array
{
$db = Database::getConnection();
$stmt = $db->prepare("SELECT * FROM articles WHERE slug = :slug");
$stmt->execute([':slug' => $slug]);
$row = $stmt->fetch();
return $row ?: null;
}
public static function create(array $data): int
{
$db = Database::getConnection();
$stmt = $db->prepare("
INSERT INTO articles (title, slug, summary, content, image, author)
VALUES (:title, :slug, :summary, :content, :image, :author)
");
$stmt->execute([
':title' => $data['title'],
':slug' => $data['slug'],
':summary' => $data['summary'] ?? '',
':content' => $data['content'] ?? '',
':image' => $data['image'] ?? '/assets/images/article1.svg',
':author' => $data['author'] ?? 'مدیریت مزرعه'
]);
return (int)$db->lastInsertId();
}
}
+41
View File
@@ -0,0 +1,41 @@
<?php
declare(strict_types=1);
namespace Bildirchin\Models;
use Bildirchin\Database;
use PDO;
class Category
{
public static function all(): array
{
$db = Database::getConnection();
$stmt = $db->query("
SELECT c.*, COUNT(p.id) as products_count
FROM categories c
LEFT JOIN products p ON c.id = p.category_id
GROUP BY c.id
ORDER BY c.sort_order ASC, c.id ASC
");
return $stmt->fetchAll();
}
public static function findById(int $id): ?array
{
$db = Database::getConnection();
$stmt = $db->prepare("SELECT * FROM categories WHERE id = :id");
$stmt->execute([':id' => $id]);
$row = $stmt->fetch();
return $row ?: null;
}
public static function findBySlug(string $slug): ?array
{
$db = Database::getConnection();
$stmt = $db->prepare("SELECT * FROM categories WHERE slug = :slug");
$stmt->execute([':slug' => $slug]);
$row = $stmt->fetch();
return $row ?: null;
}
}
+144
View File
@@ -0,0 +1,144 @@
<?php
declare(strict_types=1);
namespace Bildirchin\Models;
use Bildirchin\Database;
use PDO;
class Order
{
public static function all(int $limit = 50, ?string $status = null): array
{
$db = Database::getConnection();
$query = "SELECT * FROM orders WHERE 1=1";
$params = [];
if ($status !== null && $status !== '') {
$query .= " AND status = :status";
$params[':status'] = $status;
}
$query .= " ORDER BY id DESC LIMIT " . (int)$limit;
$stmt = $db->prepare($query);
$stmt->execute($params);
return $stmt->fetchAll();
}
public static function findById(int $id): ?array
{
$db = Database::getConnection();
$stmt = $db->prepare("SELECT * FROM orders WHERE id = :id");
$stmt->execute([':id' => $id]);
$order = $stmt->fetch();
if (!$order) {
return null;
}
$itemsStmt = $db->prepare("SELECT * FROM order_items WHERE order_id = :order_id");
$itemsStmt->execute([':order_id' => $id]);
$order['items'] = $itemsStmt->fetchAll();
return $order;
}
public static function findByCode(string $code): ?array
{
$db = Database::getConnection();
$stmt = $db->prepare("SELECT * FROM orders WHERE order_code = :code");
$stmt->execute([':code' => $code]);
$order = $stmt->fetch();
if (!$order) {
return null;
}
$itemsStmt = $db->prepare("SELECT * FROM order_items WHERE order_id = :order_id");
$itemsStmt->execute([':order_id' => $order['id']]);
$order['items'] = $itemsStmt->fetchAll();
return $order;
}
public static function create(array $data, array $items): int
{
$db = Database::getConnection();
$db->beginTransaction();
try {
$stmt = $db->prepare("
INSERT INTO orders (order_code, customer_name, customer_phone, customer_email, province, city, address, postal_code, notes, shipping_method, payment_method, total_amount, discount_amount, final_amount, status)
VALUES (:order_code, :customer_name, :customer_phone, :customer_email, :province, :city, :address, :postal_code, :notes, :shipping_method, :payment_method, :total_amount, :discount_amount, :final_amount, :status)
");
$stmt->execute([
':order_code' => $data['order_code'],
':customer_name' => $data['customer_name'],
':customer_phone' => $data['customer_phone'],
':customer_email' => $data['customer_email'] ?? '',
':province' => $data['province'] ?? '',
':city' => $data['city'] ?? '',
':address' => $data['address'],
':postal_code' => $data['postal_code'] ?? '',
':notes' => $data['notes'] ?? '',
':shipping_method' => $data['shipping_method'] ?? 'باربری / اتوبوس',
':payment_method' => $data['payment_method'] ?? 'کارت به کارت',
':total_amount' => $data['total_amount'],
':discount_amount' => $data['discount_amount'] ?? 0,
':final_amount' => $data['final_amount'],
':status' => 'pending'
]);
$orderId = (int)$db->lastInsertId();
$itemStmt = $db->prepare("
INSERT INTO order_items (order_id, product_id, product_name, quantity, unit_price, total_price, is_wholesale)
VALUES (:order_id, :product_id, :product_name, :quantity, :unit_price, :total_price, :is_wholesale)
");
foreach ($items as $item) {
$itemStmt->execute([
':order_id' => $orderId,
':product_id' => $item['product_id'],
':product_name' => $item['product_name'],
':quantity' => $item['quantity'],
':unit_price' => $item['unit_price'],
':total_price' => $item['total_price'],
':is_wholesale' => $item['is_wholesale'] ? 1 : 0
]);
}
$db->commit();
return $orderId;
} catch (\Throwable $e) {
$db->rollBack();
throw $e;
}
}
public static function updateStatus(int $id, string $status): bool
{
$db = Database::getConnection();
$stmt = $db->prepare("UPDATE orders SET status = :status WHERE id = :id");
return $stmt->execute([':id' => $id, ':status' => $status]);
}
public static function getStats(): array
{
$db = Database::getConnection();
$totalOrders = (int)$db->query("SELECT COUNT(*) FROM orders")->fetchColumn();
$pendingOrders = (int)$db->query("SELECT COUNT(*) FROM orders WHERE status = 'pending'")->fetchColumn();
$completedOrders = (int)$db->query("SELECT COUNT(*) FROM orders WHERE status = 'delivered'")->fetchColumn();
$totalRevenue = (float)$db->query("SELECT COALESCE(SUM(final_amount), 0) FROM orders WHERE status != 'cancelled'")->fetchColumn();
$newWholesale = (int)$db->query("SELECT COUNT(*) FROM wholesale_inquiries WHERE status = 'new'")->fetchColumn();
$productsCount = (int)$db->query("SELECT COUNT(*) FROM products")->fetchColumn();
return [
'total_orders' => $totalOrders,
'pending_orders' => $pendingOrders,
'completed_orders' => $completedOrders,
'total_revenue' => $totalRevenue,
'new_wholesale' => $newWholesale,
'products_count' => $productsCount
];
}
}
+157
View File
@@ -0,0 +1,157 @@
<?php
declare(strict_types=1);
namespace Bildirchin\Models;
use Bildirchin\Database;
use PDO;
class Product
{
public static function all(int $limit = 50, ?int $categoryId = null, ?string $search = null): array
{
$db = Database::getConnection();
$query = "SELECT p.*, c.name as category_name FROM products p JOIN categories c ON p.category_id = c.id WHERE 1=1";
$params = [];
if ($categoryId !== null) {
$query .= " AND p.category_id = :cat_id";
$params[':cat_id'] = $categoryId;
}
if ($search !== null && trim($search) !== '') {
$query .= " AND (p.name LIKE :search OR p.short_desc LIKE :search OR p.full_desc LIKE :search)";
$params[':search'] = '%' . trim($search) . '%';
}
$query .= " ORDER BY p.id DESC LIMIT " . (int)$limit;
$stmt = $db->prepare($query);
$stmt->execute($params);
return $stmt->fetchAll();
}
public static function featured(): array
{
$db = Database::getConnection();
$stmt = $db->query("SELECT p.*, c.name as category_name FROM products p JOIN categories c ON p.category_id = c.id WHERE p.is_featured = 1 ORDER BY p.id ASC LIMIT 8");
return $stmt->fetchAll();
}
public static function findById(int $id): ?array
{
$db = Database::getConnection();
$stmt = $db->prepare("SELECT p.*, c.name as category_name FROM products p JOIN categories c ON p.category_id = c.id WHERE p.id = :id");
$stmt->execute([':id' => $id]);
$row = $stmt->fetch();
return $row ?: null;
}
public static function findBySlug(string $slug): ?array
{
$db = Database::getConnection();
$stmt = $db->prepare("SELECT p.*, c.name as category_name FROM products p JOIN categories c ON p.category_id = c.id WHERE p.slug = :slug");
$stmt->execute([':slug' => $slug]);
$row = $stmt->fetch();
return $row ?: null;
}
public static function calculateUnitPrice(array $product, int $quantity): array
{
$isWholesale = false;
$unitPrice = (float)$product['price'];
if ((int)$product['is_wholesale_available'] === 1) {
if ($product['wholesale_tier2_qty'] > 0 && $quantity >= (int)$product['wholesale_tier2_qty']) {
$unitPrice = (float)$product['wholesale_tier2_price'];
$isWholesale = true;
} elseif ($product['wholesale_min_qty'] > 0 && $quantity >= (int)$product['wholesale_min_qty']) {
$unitPrice = (float)$product['wholesale_price'];
$isWholesale = true;
}
}
return [
'unit_price' => $unitPrice,
'total_price' => $unitPrice * $quantity,
'is_wholesale' => $isWholesale,
'discount_per_unit' => (float)$product['price'] - $unitPrice,
'total_saved' => max(0, ((float)$product['price'] - $unitPrice) * $quantity)
];
}
public static function create(array $data): int
{
$db = Database::getConnection();
$stmt = $db->prepare("
INSERT INTO products (category_id, name, slug, short_desc, full_desc, price, unit, stock, image, is_wholesale_available, wholesale_min_qty, wholesale_price, wholesale_tier2_qty, wholesale_tier2_price, is_featured)
VALUES (:category_id, :name, :slug, :short_desc, :full_desc, :price, :unit, :stock, :image, :is_wholesale_available, :wholesale_min_qty, :wholesale_price, :wholesale_tier2_qty, :wholesale_tier2_price, :is_featured)
");
$stmt->execute([
':category_id' => $data['category_id'],
':name' => $data['name'],
':slug' => $data['slug'],
':short_desc' => $data['short_desc'] ?? '',
':full_desc' => $data['full_desc'] ?? '',
':price' => $data['price'],
':unit' => $data['unit'] ?? 'عدد',
':stock' => $data['stock'] ?? 0,
':image' => $data['image'] ?? '/assets/images/quail_live.svg',
':is_wholesale_available' => $data['is_wholesale_available'] ?? 1,
':wholesale_min_qty' => $data['wholesale_min_qty'] ?? 50,
':wholesale_price' => $data['wholesale_price'] ?? 0,
':wholesale_tier2_qty' => $data['wholesale_tier2_qty'] ?? 200,
':wholesale_tier2_price' => $data['wholesale_tier2_price'] ?? 0,
':is_featured' => $data['is_featured'] ?? 0
]);
return (int)$db->lastInsertId();
}
public static function update(int $id, array $data): bool
{
$db = Database::getConnection();
$stmt = $db->prepare("
UPDATE products SET
category_id = :category_id,
name = :name,
slug = :slug,
short_desc = :short_desc,
full_desc = :full_desc,
price = :price,
unit = :unit,
stock = :stock,
image = :image,
is_wholesale_available = :is_wholesale_available,
wholesale_min_qty = :wholesale_min_qty,
wholesale_price = :wholesale_price,
wholesale_tier2_qty = :wholesale_tier2_qty,
wholesale_tier2_price = :wholesale_tier2_price,
is_featured = :is_featured
WHERE id = :id
");
return $stmt->execute([
':id' => $id,
':category_id' => $data['category_id'],
':name' => $data['name'],
':slug' => $data['slug'],
':short_desc' => $data['short_desc'] ?? '',
':full_desc' => $data['full_desc'] ?? '',
':price' => $data['price'],
':unit' => $data['unit'] ?? 'عدد',
':stock' => $data['stock'] ?? 0,
':image' => $data['image'] ?? '/assets/images/quail_live.svg',
':is_wholesale_available' => $data['is_wholesale_available'] ?? 1,
':wholesale_min_qty' => $data['wholesale_min_qty'] ?? 50,
':wholesale_price' => $data['wholesale_price'] ?? 0,
':wholesale_tier2_qty' => $data['wholesale_tier2_qty'] ?? 200,
':wholesale_tier2_price' => $data['wholesale_tier2_price'] ?? 0,
':is_featured' => $data['is_featured'] ?? 0
]);
}
public static function delete(int $id): bool
{
$db = Database::getConnection();
$stmt = $db->prepare("DELETE FROM products WHERE id = :id");
return $stmt->execute([':id' => $id]);
}
}
+37
View File
@@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
namespace Bildirchin\Models;
use Bildirchin\Database;
use PDO;
class Setting
{
public static function get(string $key, ?string $default = null): ?string
{
$db = Database::getConnection();
$stmt = $db->prepare("SELECT value FROM settings WHERE key = :key");
$stmt->execute([':key' => $key]);
$val = $stmt->fetchColumn();
return $val !== false ? (string)$val : $default;
}
public static function set(string $key, string $value): bool
{
$db = Database::getConnection();
$stmt = $db->prepare("INSERT OR REPLACE INTO settings (key, value) VALUES (:key, :value)");
return $stmt->execute([':key' => $key, ':value' => $value]);
}
public static function getAll(): array
{
$db = Database::getConnection();
$stmt = $db->query("SELECT key, value FROM settings");
$results = [];
while ($row = $stmt->fetch()) {
$results[$row['key']] = $row['value'];
}
return $results;
}
}
+43
View File
@@ -0,0 +1,43 @@
<?php
declare(strict_types=1);
namespace Bildirchin\Models;
use Bildirchin\Database;
use PDO;
class WholesaleInquiry
{
public static function all(int $limit = 50): array
{
$db = Database::getConnection();
$stmt = $db->query("SELECT * FROM wholesale_inquiries ORDER BY id DESC LIMIT " . (int)$limit);
return $stmt->fetchAll();
}
public static function create(array $data): int
{
$db = Database::getConnection();
$stmt = $db->prepare("
INSERT INTO wholesale_inquiries (customer_name, phone, company_name, product_requested, estimated_qty, city, notes, status)
VALUES (:customer_name, :phone, :company_name, :product_requested, :estimated_qty, :city, :notes, 'new')
");
$stmt->execute([
':customer_name' => $data['customer_name'],
':phone' => $data['phone'],
':company_name' => $data['company_name'] ?? '',
':product_requested' => $data['product_requested'],
':estimated_qty' => $data['estimated_qty'] ?? '',
':city' => $data['city'] ?? '',
':notes' => $data['notes'] ?? ''
]);
return (int)$db->lastInsertId();
}
public static function updateStatus(int $id, string $status): bool
{
$db = Database::getConnection();
$stmt = $db->prepare("UPDATE wholesale_inquiries SET status = :status WHERE id = :id");
return $stmt->execute([':id' => $id, ':status' => $status]);
}
}
+129
View File
@@ -0,0 +1,129 @@
<?php
$pageTitle = 'داشبورد و وضعیت عملکرد مزرعه';
require __DIR__ . '/layout_header.php';
?>
<!-- Stats Grid -->
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
<div class="bg-white p-6 rounded-2xl border border-stone-200 shadow-sm flex items-center justify-between">
<div>
<span class="text-xs text-stone-500 font-bold block mb-1">کل سفارش‌ها</span>
<span class="text-2xl font-black text-stone-900"><?= \Bildirchin\Helpers::toPersianDigits($stats['total_orders']) ?></span>
</div>
<div class="w-12 h-12 rounded-2xl bg-amber-50 text-amber-600 flex items-center justify-center text-xl">
<i class="fas fa-shopping-bag"></i>
</div>
</div>
<div class="bg-white p-6 rounded-2xl border border-stone-200 shadow-sm flex items-center justify-between">
<div>
<span class="text-xs text-stone-500 font-bold block mb-1">سفارش‌های در انتظار تایید</span>
<span class="text-2xl font-black text-amber-600"><?= \Bildirchin\Helpers::toPersianDigits($stats['pending_orders']) ?></span>
</div>
<div class="w-12 h-12 rounded-2xl bg-amber-50 text-amber-600 flex items-center justify-center text-xl">
<i class="fas fa-clock"></i>
</div>
</div>
<div class="bg-white p-6 rounded-2xl border border-stone-200 shadow-sm flex items-center justify-between">
<div>
<span class="text-xs text-stone-500 font-bold block mb-1">استعلام‌های عمده جدید</span>
<span class="text-2xl font-black text-sky-600"><?= \Bildirchin\Helpers::toPersianDigits($stats['new_wholesale']) ?></span>
</div>
<div class="w-12 h-12 rounded-2xl bg-sky-50 text-sky-600 flex items-center justify-center text-xl">
<i class="fas fa-handshake"></i>
</div>
</div>
<div class="bg-white p-6 rounded-2xl border border-stone-200 shadow-sm flex items-center justify-between">
<div>
<span class="text-xs text-stone-500 font-bold block mb-1">مجموع فروش ثبت‌شده</span>
<span class="text-xl font-black text-emerald-700"><?= \Bildirchin\Helpers::formatPrice($stats['total_revenue']) ?></span>
</div>
<div class="w-12 h-12 rounded-2xl bg-emerald-50 text-emerald-600 flex items-center justify-center text-xl">
<i class="fas fa-coins"></i>
</div>
</div>
</div>
<div class="grid grid-cols-1 lg:grid-cols-12 gap-8">
<!-- Recent Orders -->
<div class="lg:col-span-8 bg-white rounded-2xl border border-stone-200 shadow-sm overflow-hidden">
<div class="p-5 border-b border-stone-100 flex items-center justify-between">
<h3 class="font-bold text-stone-900 text-sm">سفارش‌های اخیر مشتریان</h3>
<a href="/admin/orders" class="text-xs text-amber-600 font-bold hover:underline">مشاهده همه</a>
</div>
<div class="overflow-x-auto">
<table class="w-full text-right text-xs">
<thead class="bg-stone-50 text-stone-500 border-b">
<tr>
<th class="p-3.5">کد سفارش</th>
<th class="p-3.5">مشتری</th>
<th class="p-3.5">مبلغ کل</th>
<th class="p-3.5">وضعیت</th>
<th class="p-3.5">عملیات</th>
</tr>
</thead>
<tbody class="divide-y divide-stone-100">
<?php if (empty($recentOrders)): ?>
<tr><td colspan="5" class="p-6 text-center text-stone-400">هنوز سفارشی ثبت نشده است.</td></tr>
<?php else: ?>
<?php foreach ($recentOrders as $ord): ?>
<tr class="hover:bg-stone-50">
<td class="p-3.5 font-bold font-mono"><?= htmlspecialchars($ord['order_code']) ?></td>
<td class="p-3.5">
<span class="font-bold text-stone-900 block"><?= htmlspecialchars($ord['customer_name']) ?></span>
<span class="text-stone-400 text-[11px]"><?= htmlspecialchars($ord['customer_phone']) ?></span>
</td>
<td class="p-3.5 font-black text-stone-900"><?= \Bildirchin\Helpers::formatPrice($ord['final_amount']) ?></td>
<td class="p-3.5">
<span class="px-2.5 py-1 rounded-full text-[10px] font-bold bg-amber-100 text-amber-800">
<?= htmlspecialchars($ord['status']) ?>
</span>
</td>
<td class="p-3.5">
<a href="/admin/order/<?= $ord['id'] ?>" class="text-amber-600 hover:text-amber-800 font-bold">
جزییات و فاکتور
</a>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
<!-- Recent Wholesale Inquiries -->
<div class="lg:col-span-4 bg-white rounded-2xl border border-stone-200 shadow-sm overflow-hidden">
<div class="p-5 border-b border-stone-100 flex items-center justify-between">
<h3 class="font-bold text-stone-900 text-sm">استعلام‌های اخیر عمده</h3>
<a href="/admin/wholesale-inquiries" class="text-xs text-amber-600 font-bold hover:underline">همه</a>
</div>
<div class="p-4 space-y-3">
<?php if (empty($recentInquiries)): ?>
<p class="text-xs text-stone-400 text-center py-6">استعلام جدیدی ثبت نشده است.</p>
<?php else: ?>
<?php foreach ($recentInquiries as $inq): ?>
<div class="bg-stone-50 p-3.5 rounded-xl border border-stone-100 text-xs space-y-1">
<div class="flex justify-between items-center">
<span class="font-bold text-stone-900"><?= htmlspecialchars($inq['customer_name']) ?></span>
<span class="text-[10px] text-stone-400"><?= \Bildirchin\Helpers::getJalaliDate($inq['created_at']) ?></span>
</div>
<p class="text-amber-800 font-medium"><?= htmlspecialchars($inq['product_requested']) ?></p>
<div class="flex justify-between text-[11px] text-stone-500 pt-1">
<span>تماس: <?= htmlspecialchars($inq['phone']) ?></span>
<span><?= htmlspecialchars($inq['city']) ?></span>
</div>
</div>
<?php endforeach; ?>
<?php endif; ?>
</div>
</div>
</div>
<?php
require __DIR__ . '/layout_footer.php';
?>
+93
View File
@@ -0,0 +1,93 @@
<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
<meta charset="UTF-8">
<title>فاکتور فروش <?= $order['order_code'] ?> - <?= \Bildirchin\Config::APP_NAME ?></title>
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://fonts.googleapis.com/css2?family=Vazirmatn:wght@400;600;700;900&display=swap" rel="stylesheet">
<style>
body { font-family: 'Vazirmatn', Tahoma, sans-serif; }
@media print {
.no-print { display: none; }
body { padding: 0; background: white; }
}
</style>
</head>
<body class="bg-stone-100 p-8 text-stone-900">
<div class="max-w-4xl mx-auto bg-white p-10 rounded-2xl shadow-sm border border-stone-200 space-y-8">
<div class="no-print flex justify-end gap-3 mb-4">
<button onclick="window.print()" class="px-4 py-2 rounded-xl bg-amber-500 font-bold text-xs hover:bg-amber-600">چاپ فاکتور</button>
<button onclick="window.close()" class="px-4 py-2 rounded-xl bg-stone-200 font-bold text-xs">بستن</button>
</div>
<!-- Header -->
<div class="flex justify-between items-center border-b pb-6">
<div>
<h1 class="text-xl font-black text-stone-900"><?= \Bildirchin\Config::APP_NAME ?></h1>
<p class="text-xs text-stone-500 mt-1">تولید و عرضه صنعتی انواع بلدرچین، تخم، دان و تجهیزات</p>
<p class="text-xs text-stone-500"><?= \Bildirchin\Config::ADDRESS ?></p>
<p class="text-xs text-stone-500">تلفن: <?= \Bildirchin\Config::PHONE ?></p>
</div>
<div class="text-left">
<span class="text-2xl font-black text-amber-700 block">پیش‌فاکتور فروش</span>
<span class="text-xs text-stone-400 block mt-1">شماره: <?= htmlspecialchars($order['order_code']) ?></span>
<span class="text-xs text-stone-400 block">تاریخ: <?= \Bildirchin\Helpers::getJalaliDate($order['created_at']) ?></span>
</div>
</div>
<!-- Buyer -->
<div class="grid grid-cols-2 gap-4 text-xs bg-stone-50 p-4 rounded-xl">
<div>
<span class="text-stone-500">خریدار:</span> <span class="font-bold"><?= htmlspecialchars($order['customer_name']) ?></span>
</div>
<div>
<span class="text-stone-500">شماره تماس:</span> <span class="font-bold"><?= htmlspecialchars($order['customer_phone']) ?></span>
</div>
<div class="col-span-2">
<span class="text-stone-500">نشانی تحویل:</span> <span class="font-bold"><?= htmlspecialchars($order['province']) ?> - <?= htmlspecialchars($order['city']) ?> - <?= htmlspecialchars($order['address']) ?></span>
</div>
</div>
<!-- Table -->
<table class="w-full text-right text-xs border border-stone-200">
<thead class="bg-stone-100 border-b">
<tr>
<th class="p-3 border-l">ردیف</th>
<th class="p-3 border-l">شرح کالا / خدمات</th>
<th class="p-3 border-l">تعداد</th>
<th class="p-3 border-l">قیمت واحد</th>
<th class="p-3">مبلغ کل (تومان)</th>
</tr>
</thead>
<tbody class="divide-y divide-stone-200">
<?php $i = 1; foreach ($order['items'] as $item): ?>
<tr>
<td class="p-3 border-l text-center"><?= $i++ ?></td>
<td class="p-3 border-l font-bold"><?= htmlspecialchars($item['product_name']) ?></td>
<td class="p-3 border-l text-center"><?= \Bildirchin\Helpers::toPersianDigits($item['quantity']) ?></td>
<td class="p-3 border-l"><?= \Bildirchin\Helpers::formatPrice($item['unit_price']) ?></td>
<td class="p-3 font-bold"><?= \Bildirchin\Helpers::formatPrice($item['total_price']) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
<tfoot class="bg-stone-50 font-bold border-t">
<tr>
<td colspan="4" class="p-3 text-left border-l">مبلغ نهایی قابل پرداخت:</td>
<td class="p-3 text-amber-900 text-sm font-black"><?= \Bildirchin\Helpers::formatPrice($order['final_amount']) ?></td>
</tr>
</tfoot>
</table>
<!-- Signatures -->
<div class="grid grid-cols-2 gap-10 pt-10 text-xs text-center">
<div>
<span class="block font-bold">مهر و امضای فروشنده</span>
<span class="text-stone-400 mt-1 block">مجتمع پرورشی بلدرچین زرین</span>
</div>
<div>
<span class="block font-bold">امضا و تایید خریدار</span>
</div>
</div>
</div>
</body>
</html>
+4
View File
@@ -0,0 +1,4 @@
</main>
</div>
</body>
</html>
+114
View File
@@ -0,0 +1,114 @@
<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?= isset($pageTitle) ? htmlspecialchars($pageTitle) . ' | ' : '' ?>پنل مدیریت مزرعه بلدرچین زرین</title>
<!-- Tailwind CSS CDN -->
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
theme: {
extend: {
colors: {
amber: {
500: '#f59e0b',
600: '#d97706',
700: '#b45309',
800: '#92400e'
}
},
fontFamily: {
sans: ['Vazirmatn', 'Tahoma', 'sans-serif']
}
}
}
}
</script>
<link href="https://fonts.googleapis.com/css2?family=Vazirmatn:wght@300;400;500;600;700;800;900&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
body { font-family: 'Vazirmatn', Tahoma, sans-serif; }
</style>
</head>
<body class="bg-stone-100 text-stone-800 flex h-screen overflow-hidden">
<!-- Sidebar -->
<aside class="w-64 bg-stone-900 text-stone-300 flex flex-col justify-between hidden md:flex border-l border-stone-800">
<div>
<!-- Brand -->
<div class="h-20 flex items-center gap-3 px-6 border-b border-stone-800">
<div class="w-10 h-10 rounded-xl bg-amber-600 text-white flex items-center justify-center font-bold">
<i class="fas fa-feather-alt text-lg"></i>
</div>
<div>
<span class="font-extrabold text-white text-sm block">مدیریت مزرعه</span>
<span class="text-[11px] text-stone-400">بلدرچین زرین</span>
</div>
</div>
<!-- Menu Links -->
<nav class="p-4 space-y-1.5 text-xs font-semibold">
<a href="/admin/dashboard" class="flex items-center gap-3 px-4 py-3 rounded-xl hover:bg-stone-800 hover:text-white transition <?= ($requestUri === '/admin' || $requestUri === '/admin/dashboard') ? 'bg-amber-600 text-white' : '' ?>">
<i class="fas fa-chart-pie w-5 text-center"></i> داشبورد و آمار
</a>
<a href="/admin/orders" class="flex items-center gap-3 px-4 py-3 rounded-xl hover:bg-stone-800 hover:text-white transition <?= (strpos($requestUri, '/admin/order') === 0) ? 'bg-amber-600 text-white' : '' ?>">
<i class="fas fa-shopping-basket w-5 text-center"></i> مدیریت سفارش‌ها
</a>
<a href="/admin/products" class="flex items-center gap-3 px-4 py-3 rounded-xl hover:bg-stone-800 hover:text-white transition <?= (strpos($requestUri, '/admin/product') === 0) ? 'bg-amber-600 text-white' : '' ?>">
<i class="fas fa-box-open w-5 text-center"></i> مدیریت محصولات و نرخ عمده
</a>
<a href="/admin/wholesale-inquiries" class="flex items-center gap-3 px-4 py-3 rounded-xl hover:bg-stone-800 hover:text-white transition <?= (strpos($requestUri, '/admin/wholesale') === 0) ? 'bg-amber-600 text-white' : '' ?>">
<i class="fas fa-handshake w-5 text-center"></i> استعلام‌های عمده‌فروشی
</a>
<a href="/admin/settings" class="flex items-center gap-3 px-4 py-3 rounded-xl hover:bg-stone-800 hover:text-white transition <?= (strpos($requestUri, '/admin/settings') === 0) ? 'bg-amber-600 text-white' : '' ?>">
<i class="fas fa-sliders w-5 text-center"></i> تنظیمات فروشگاه و حساب
</a>
<a href="/" target="_blank" class="flex items-center gap-3 px-4 py-3 rounded-xl hover:bg-stone-800 hover:text-white transition text-stone-400">
<i class="fas fa-arrow-up-right-from-square w-5 text-center"></i> مشاهده وب‌سایت
</a>
</nav>
</div>
<!-- Admin Footer -->
<div class="p-4 border-t border-stone-800">
<a href="/admin/logout" class="flex items-center gap-3 px-4 py-2.5 rounded-xl bg-rose-600/20 hover:bg-rose-600 text-rose-300 hover:text-white transition text-xs font-bold">
<i class="fas fa-power-off"></i> خروج از حساب
</a>
</div>
</aside>
<!-- Main Wrapper -->
<div class="flex-1 flex flex-col overflow-y-auto">
<!-- Top Bar -->
<header class="h-20 bg-white border-b border-stone-200 px-6 flex items-center justify-between sticky top-0 z-30 shadow-sm">
<div class="flex items-center gap-4">
<h2 class="text-base font-extrabold text-stone-900"><?= $pageTitle ?? 'داشبورد' ?></h2>
</div>
<div class="flex items-center gap-4">
<span class="text-xs text-stone-500 font-medium">کاربر مدیر: <?= htmlspecialchars($_SESSION['admin_user']['display_name'] ?? 'مدیر سیستم') ?></span>
<a href="/admin/logout" class="text-xs text-rose-600 hover:underline">خروج</a>
</div>
</header>
<!-- Flash Messages -->
<?php
$successMsg = \Bildirchin\Helpers::flash('success');
$errorMsg = \Bildirchin\Helpers::flash('error');
?>
<?php if ($successMsg): ?>
<div class="mx-6 mt-4 bg-emerald-50 border border-emerald-300 text-emerald-800 px-4 py-3 rounded-xl text-xs font-bold flex justify-between">
<span><i class="fas fa-check-circle ml-1"></i> <?= htmlspecialchars($successMsg) ?></span>
<button onclick="this.parentElement.remove()">×</button>
</div>
<?php endif; ?>
<?php if ($errorMsg): ?>
<div class="mx-6 mt-4 bg-rose-50 border border-rose-300 text-rose-800 px-4 py-3 rounded-xl text-xs font-bold flex justify-between">
<span><i class="fas fa-triangle-exclamation ml-1"></i> <?= htmlspecialchars($errorMsg) ?></span>
<button onclick="this.parentElement.remove()">×</button>
</div>
<?php endif; ?>
<!-- Main Content -->
<main class="p-6 flex-1">
+51
View File
@@ -0,0 +1,51 @@
<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ورود به مدیریت مزرعه بلدرچین زرین</title>
<script src="https://cdn.tailwindcss.com"></script>
<link href="https://fonts.googleapis.com/css2?family=Vazirmatn:wght@400;600;700;900&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>body { font-family: 'Vazirmatn', Tahoma, sans-serif; }</style>
</head>
<body class="bg-stone-900 text-stone-100 flex items-center justify-center min-h-screen p-4">
<div class="w-full max-w-md bg-stone-950/80 rounded-3xl p-8 border border-stone-800 shadow-2xl space-y-6">
<div class="text-center space-y-2">
<div class="w-16 h-16 rounded-2xl bg-amber-600 text-white flex items-center justify-center text-3xl mx-auto shadow-lg">
<i class="fas fa-feather-alt"></i>
</div>
<h1 class="text-xl font-extrabold text-white">ورود به پنل مدیریت مزرعه</h1>
<p class="text-xs text-stone-400">سامانه مدیریت سفارشات و محصولات بلدرچین زرین</p>
</div>
<?php $err = \Bildirchin\Helpers::flash('error'); if ($err): ?>
<div class="bg-rose-500/20 border border-rose-500 text-rose-300 text-xs p-3 rounded-xl">
<?= htmlspecialchars($err) ?>
</div>
<?php endif; ?>
<form action="/admin/login" method="POST" class="space-y-4">
<div>
<label class="block text-xs font-bold text-stone-300 mb-1">نام کاربری:</label>
<input type="text" name="username" value="admin" required class="w-full bg-stone-900 border border-stone-700 rounded-xl p-3 text-sm text-white focus:outline-none focus:border-amber-500">
</div>
<div>
<label class="block text-xs font-bold text-stone-300 mb-1">رمز عبور:</label>
<input type="password" name="password" value="admin123" required class="w-full bg-stone-900 border border-stone-700 rounded-xl p-3 text-sm text-white focus:outline-none focus:border-amber-500">
</div>
<button type="submit" class="w-full py-3.5 rounded-xl bg-amber-500 hover:bg-amber-600 text-stone-950 font-black text-sm transition shadow-lg mt-2">
ورود به سامانه
</button>
</form>
<div class="text-center pt-2">
<a href="/" class="text-xs text-stone-500 hover:text-amber-400 transition">
<i class="fas fa-arrow-right ml-1"></i> بازگشت به صفحه اصلی سایت
</a>
</div>
</div>
</body>
</html>
+96
View File
@@ -0,0 +1,96 @@
<?php
$pageTitle = 'جزییات سفارش ' . $order['order_code'];
require __DIR__ . '/layout_header.php';
?>
<div class="max-w-5xl mx-auto space-y-6">
<div class="flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4 bg-white p-6 rounded-2xl border border-stone-200 shadow-sm">
<div>
<span class="text-xs text-stone-400">کد رهگیری سفارش:</span>
<h2 class="text-xl font-black text-stone-900 font-mono"><?= htmlspecialchars($order['order_code']) ?></h2>
<span class="text-xs text-stone-500">ثبت در تاریخ: <?= \Bildirchin\Helpers::getJalaliDate($order['created_at']) ?></span>
</div>
<div class="flex items-center gap-3">
<a href="/admin/invoice/<?= $order['id'] ?>" target="_blank" class="px-4 py-2 rounded-xl bg-stone-800 text-white text-xs font-bold hover:bg-stone-700 transition flex items-center gap-1.5">
<i class="fas fa-print"></i> نسخه چاپی فاکتور
</a>
<!-- Status Changer -->
<form action="/admin/order/update-status" method="POST" class="flex items-center gap-2">
<input type="hidden" name="order_id" value="<?= $order['id'] ?>">
<select name="status" class="bg-stone-50 border border-stone-300 rounded-xl p-2 text-xs font-bold focus:outline-none">
<option value="pending" <?= $order['status'] === 'pending' ? 'selected' : '' ?>>در انتظار تایید</option>
<option value="confirmed" <?= $order['status'] === 'confirmed' ? 'selected' : '' ?>>تایید شده</option>
<option value="packing" <?= $order['status'] === 'packing' ? 'selected' : '' ?>>در حال بسته‌بندی</option>
<option value="shipped" <?= $order['status'] === 'shipped' ? 'selected' : '' ?>>تحویل باربری / ارسال شده</option>
<option value="delivered" <?= $order['status'] === 'delivered' ? 'selected' : '' ?>>تحویل داده شده</option>
<option value="cancelled" <?= $order['status'] === 'cancelled' ? 'selected' : '' ?>>لغو شده</option>
</select>
<button type="submit" class="px-3 py-2 rounded-xl bg-amber-500 hover:bg-amber-600 text-stone-950 font-bold text-xs">
ثبت وضعیت
</button>
</form>
</div>
</div>
<!-- Customer & Destination Card -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<div class="bg-white p-6 rounded-2xl border border-stone-200 shadow-sm text-xs space-y-3">
<h4 class="font-bold text-stone-900 border-b pb-2 text-sm">مشخصات خریدار</h4>
<div class="flex justify-between"><span>نام و نام خانوادگی:</span><span class="font-bold text-stone-900"><?= htmlspecialchars($order['customer_name']) ?></span></div>
<div class="flex justify-between"><span>شماره تماس:</span><span class="font-bold text-stone-900 font-mono"><?= htmlspecialchars($order['customer_phone']) ?></span></div>
<div class="flex justify-between"><span>شیوه پرداخت:</span><span class="font-bold text-stone-900"><?= htmlspecialchars($order['payment_method']) ?></span></div>
<div class="flex justify-between"><span>روش ارسال:</span><span class="font-bold text-stone-900"><?= htmlspecialchars($order['shipping_method']) ?></span></div>
</div>
<div class="bg-white p-6 rounded-2xl border border-stone-200 shadow-sm text-xs space-y-3">
<h4 class="font-bold text-stone-900 border-b pb-2 text-sm">آدرس و مقصد تحویل</h4>
<div class="flex justify-between"><span>استان و شهر:</span><span class="font-bold text-stone-900"><?= htmlspecialchars($order['province']) ?> - <?= htmlspecialchars($order['city']) ?></span></div>
<div class="flex justify-between"><span>کد پستی:</span><span class="font-bold text-stone-900 font-mono"><?= htmlspecialchars($order['postal_code'] ?: '-') ?></span></div>
<div><span>آدرس کامل:</span><p class="font-bold text-stone-900 mt-1"><?= htmlspecialchars($order['address']) ?></p></div>
<?php if ($order['notes']): ?>
<div><span>یادداشت:</span><p class="text-amber-800 font-bold mt-1"><?= htmlspecialchars($order['notes']) ?></p></div>
<?php endif; ?>
</div>
</div>
<!-- Items List -->
<div class="bg-white rounded-2xl border border-stone-200 shadow-sm overflow-hidden">
<div class="p-4 border-b font-bold text-sm text-stone-900">اقلام فاکتور</div>
<table class="w-full text-right text-xs">
<thead class="bg-stone-50 border-b">
<tr>
<th class="p-3">نام محصول</th>
<th class="p-3">تعداد</th>
<th class="p-3">قیمت واحد</th>
<th class="p-3">نوع نرخ</th>
<th class="p-3 text-left">مجموع</th>
</tr>
</thead>
<tbody class="divide-y divide-stone-100">
<?php foreach ($order['items'] as $it): ?>
<tr>
<td class="p-3 font-bold text-stone-900"><?= htmlspecialchars($it['product_name']) ?></td>
<td class="p-3 font-bold"><?= \Bildirchin\Helpers::toPersianDigits($it['quantity']) ?></td>
<td class="p-3"><?= \Bildirchin\Helpers::formatPrice($it['unit_price']) ?></td>
<td class="p-3">
<?= $it['is_wholesale'] ? '<span class="text-emerald-600 font-bold">نرخ عمده</span>' : 'عادی' ?>
</td>
<td class="p-3 text-left font-black text-stone-900"><?= \Bildirchin\Helpers::formatPrice($it['total_price']) ?></td>
</tr>
<?php endforeach; ?>
</tbody>
<tfoot class="bg-stone-50 font-bold">
<tr>
<td colspan="4" class="p-3 text-left">مجموع کل:</td>
<td class="p-3 text-left font-black text-amber-900 text-sm"><?= \Bildirchin\Helpers::formatPrice($order['final_amount']) ?></td>
</tr>
</tfoot>
</table>
</div>
</div>
<?php
require __DIR__ . '/layout_footer.php';
?>
+59
View File
@@ -0,0 +1,59 @@
<?php
$pageTitle = 'مدیریت سفارش‌ها';
require __DIR__ . '/layout_header.php';
?>
<div class="bg-white rounded-2xl border border-stone-200 shadow-sm overflow-hidden">
<div class="overflow-x-auto">
<table class="w-full text-right text-xs">
<thead class="bg-stone-50 text-stone-600 border-b">
<tr>
<th class="p-3.5">کد سفارش</th>
<th class="p-3.5">خریدار</th>
<th class="p-3.5">شهر / آدرس</th>
<th class="p-3.5">مبلغ کل</th>
<th class="p-3.5">روش ارسال / پرداخت</th>
<th class="p-3.5">وضعیت</th>
<th class="p-3.5">تاریخ</th>
<th class="p-3.5 text-center">عملیات</th>
</tr>
</thead>
<tbody class="divide-y divide-stone-100">
<?php if (empty($orders)): ?>
<tr><td colspan="8" class="p-8 text-center text-stone-400">سفارشی یافت نشد.</td></tr>
<?php else: ?>
<?php foreach ($orders as $ord): ?>
<tr class="hover:bg-stone-50">
<td class="p-3.5 font-bold font-mono text-stone-900"><?= htmlspecialchars($ord['order_code']) ?></td>
<td class="p-3.5">
<span class="font-bold text-stone-900 block"><?= htmlspecialchars($ord['customer_name']) ?></span>
<span class="text-[11px] text-stone-400"><?= htmlspecialchars($ord['customer_phone']) ?></span>
</td>
<td class="p-3.5 text-stone-600 max-w-xs truncate"><?= htmlspecialchars($ord['city']) ?> - <?= htmlspecialchars($ord['address']) ?></td>
<td class="p-3.5 font-black text-amber-900"><?= \Bildirchin\Helpers::formatPrice($ord['final_amount']) ?></td>
<td class="p-3.5 text-stone-500">
<span class="block"><?= htmlspecialchars($ord['shipping_method']) ?></span>
<span class="text-[10px] text-stone-400"><?= htmlspecialchars($ord['payment_method']) ?></span>
</td>
<td class="p-3.5">
<span class="px-2.5 py-1 rounded-full text-[10px] font-bold bg-amber-100 text-amber-800">
<?= htmlspecialchars($ord['status']) ?>
</span>
</td>
<td class="p-3.5 text-[11px] text-stone-400"><?= \Bildirchin\Helpers::getJalaliDate($ord['created_at']) ?></td>
<td class="p-3.5 text-center">
<a href="/admin/order/<?= $ord['id'] ?>" class="px-3 py-1.5 rounded-lg bg-stone-100 text-stone-800 hover:bg-amber-500 hover:text-stone-950 font-bold transition">
مشاهده فاکتور
</a>
</td>
</tr>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
<?php
require __DIR__ . '/layout_footer.php';
?>
+177
View File
@@ -0,0 +1,177 @@
<?php
$pageTitle = 'مدیریت محصولات، قیمت‌ها و سطوح عمده‌فروشی';
require __DIR__ . '/layout_header.php';
?>
<div class="flex justify-between items-center mb-6">
<h3 class="font-extrabold text-stone-900 text-base">لیست محصولات فعال فروشگاه</h3>
<button onclick="document.getElementById('new-product-modal').classList.remove('hidden')" class="px-4 py-2 rounded-xl bg-amber-500 hover:bg-amber-600 text-stone-950 text-xs font-bold transition flex items-center gap-1.5 shadow-sm">
<i class="fas fa-plus"></i> افزودن محصول جدید
</button>
</div>
<div class="bg-white rounded-2xl border border-stone-200 shadow-sm overflow-hidden">
<div class="overflow-x-auto">
<table class="w-full text-right text-xs">
<thead class="bg-stone-50 text-stone-600 border-b">
<tr>
<th class="p-3.5">تصویر و عنوان</th>
<th class="p-3.5">دسته</th>
<th class="p-3.5">قیمت تکی</th>
<th class="p-3.5">قیمت عمده (پله ۱)</th>
<th class="p-3.5">موجودی</th>
<th class="p-3.5 text-center">عملیات</th>
</tr>
</thead>
<tbody class="divide-y divide-stone-100">
<?php foreach ($products as $p): ?>
<tr class="hover:bg-stone-50">
<td class="p-3.5 flex items-center gap-3 font-bold text-stone-900">
<img src="<?= $p['image'] ?>" class="w-10 h-10 object-contain bg-stone-100 rounded-lg p-1">
<div>
<span><?= htmlspecialchars($p['name']) ?></span>
<span class="block text-[10px] text-stone-400 font-normal"><?= htmlspecialchars($p['slug']) ?></span>
</div>
</td>
<td class="p-3.5 text-stone-600"><?= htmlspecialchars($p['category_name']) ?></td>
<td class="p-3.5 font-bold text-stone-900"><?= \Bildirchin\Helpers::formatPrice($p['price']) ?> / <?= $p['unit'] ?></td>
<td class="p-3.5 text-amber-800 font-bold">
<?= $p['wholesale_price'] > 0 ? \Bildirchin\Helpers::formatPrice($p['wholesale_price']) : '-' ?>
</td>
<td class="p-3.5 font-bold text-stone-700"><?= \Bildirchin\Helpers::toPersianDigits($p['stock']) ?> <?= $p['unit'] ?></td>
<td class="p-3.5 text-center">
<div class="flex items-center justify-center gap-2">
<button onclick='editProduct(<?= json_encode($p) ?>)' class="px-2.5 py-1 rounded bg-stone-100 text-stone-700 hover:bg-stone-200 text-xs">ویرایش</button>
<form action="/admin/product/delete" method="POST" onsubmit="return confirm('آیا از حذف این محصول مطمئن هستید؟')">
<input type="hidden" name="id" value="<?= $p['id'] ?>">
<button type="submit" class="px-2.5 py-1 rounded bg-rose-50 text-rose-600 hover:bg-rose-100 text-xs">حذف</button>
</form>
</div>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
<!-- Modal Create / Edit Product -->
<div id="new-product-modal" class="fixed inset-0 bg-black/50 z-50 flex items-center justify-center p-4 hidden">
<div class="bg-white rounded-3xl max-w-2xl w-full max-h-[90vh] overflow-y-auto p-6 sm:p-8 space-y-4">
<div class="flex justify-between items-center border-b pb-3">
<h4 class="font-bold text-base text-stone-900" id="modal-title">افزودن / ویرایش محصول</h4>
<button onclick="document.getElementById('new-product-modal').classList.add('hidden')" class="text-stone-400 hover:text-stone-700"><i class="fas fa-times text-lg"></i></button>
</div>
<form action="/admin/product/save" method="POST" class="space-y-4 text-xs">
<input type="hidden" name="id" id="prod-id" value="0">
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div>
<label class="block font-bold text-stone-700 mb-1">نام محصول *</label>
<input type="text" name="name" id="prod-name" required class="w-full bg-stone-50 border border-stone-300 rounded-xl p-2.5 text-xs focus:ring-2 focus:ring-amber-500">
</div>
<div>
<label class="block font-bold text-stone-700 mb-1">دسته‌بندی *</label>
<select name="category_id" id="prod-cat" class="w-full bg-stone-50 border border-stone-300 rounded-xl p-2.5 text-xs">
<?php foreach ($categories as $c): ?>
<option value="<?= $c['id'] ?>"><?= htmlspecialchars($c['name']) ?></option>
<?php endforeach; ?>
</select>
</div>
</div>
<div class="grid grid-cols-1 sm:grid-cols-3 gap-4">
<div>
<label class="block font-bold text-stone-700 mb-1">قیمت مصرف‌کننده (تومان) *</label>
<input type="number" name="price" id="prod-price" required class="w-full bg-stone-50 border border-stone-300 rounded-xl p-2.5 text-xs">
</div>
<div>
<label class="block font-bold text-stone-700 mb-1">واحد اندازه‌گیری</label>
<input type="text" name="unit" id="prod-unit" value="عدد" class="w-full bg-stone-50 border border-stone-300 rounded-xl p-2.5 text-xs">
</div>
<div>
<label class="block font-bold text-stone-700 mb-1">موجودی انبار</label>
<input type="number" name="stock" id="prod-stock" value="100" class="w-full bg-stone-50 border border-stone-300 rounded-xl p-2.5 text-xs">
</div>
</div>
<div class="bg-amber-50/60 p-4 rounded-2xl border border-amber-200 space-y-3">
<span class="font-bold text-amber-900 block">تنظیمات سطوح عمده‌فروشی</span>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div>
<label class="block text-stone-600 mb-1">حداقل تعداد پله ۱ عمده:</label>
<input type="number" name="wholesale_min_qty" id="prod-wmin" value="50" class="w-full bg-white border border-stone-300 rounded-xl p-2 text-xs">
</div>
<div>
<label class="block text-stone-600 mb-1">قیمت عمده پله ۱ (تومان):</label>
<input type="number" name="wholesale_price" id="prod-wprice" value="0" class="w-full bg-white border border-stone-300 rounded-xl p-2 text-xs">
</div>
</div>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div>
<label class="block text-stone-600 mb-1">حداقل تعداد پله ۲ (تیراژ بالا):</label>
<input type="number" name="wholesale_tier2_qty" id="prod-t2qty" value="200" class="w-full bg-white border border-stone-300 rounded-xl p-2 text-xs">
</div>
<div>
<label class="block text-stone-600 mb-1">قیمت عمده پله ۲ (تومان):</label>
<input type="number" name="wholesale_tier2_price" id="prod-t2price" value="0" class="w-full bg-white border border-stone-300 rounded-xl p-2 text-xs">
</div>
</div>
</div>
<div>
<label class="block font-bold text-stone-700 mb-1">توضیح کوتاه</label>
<input type="text" name="short_desc" id="prod-short" class="w-full bg-stone-50 border border-stone-300 rounded-xl p-2.5 text-xs">
</div>
<div>
<label class="block font-bold text-stone-700 mb-1">توضیحات کامل محصول</label>
<textarea name="full_desc" id="prod-full" rows="3" class="w-full bg-stone-50 border border-stone-300 rounded-xl p-2.5 text-xs"></textarea>
</div>
<div class="flex items-center gap-6 pt-2">
<label class="flex items-center gap-2 cursor-pointer">
<input type="checkbox" name="is_wholesale_available" id="prod-is-w" checked class="text-amber-600">
<span class="font-bold">فروش عمده فعال باشد</span>
</label>
<label class="flex items-center gap-2 cursor-pointer">
<input type="checkbox" name="is_featured" id="prod-featured" checked class="text-amber-600">
<span class="font-bold">نمایش در صفحه اول</span>
</label>
</div>
<div class="pt-4 border-t flex justify-end gap-3">
<button type="button" onclick="document.getElementById('new-product-modal').classList.add('hidden')" class="px-4 py-2 rounded-xl bg-stone-200 text-stone-800 font-bold">انصراف</button>
<button type="submit" class="px-6 py-2 rounded-xl bg-amber-500 hover:bg-amber-600 text-stone-950 font-bold">ذخیره اطلاعات</button>
</div>
</form>
</div>
</div>
<script>
function editProduct(p) {
document.getElementById('prod-id').value = p.id;
document.getElementById('prod-name').value = p.name;
document.getElementById('prod-cat').value = p.category_id;
document.getElementById('prod-price').value = p.price;
document.getElementById('prod-unit').value = p.unit;
document.getElementById('prod-stock').value = p.stock;
document.getElementById('prod-wmin').value = p.wholesale_min_qty;
document.getElementById('prod-wprice').value = p.wholesale_price;
document.getElementById('prod-t2qty').value = p.wholesale_tier2_qty;
document.getElementById('prod-t2price').value = p.wholesale_tier2_price;
document.getElementById('prod-short').value = p.short_desc;
document.getElementById('prod-full').value = p.full_desc;
document.getElementById('prod-is-w').checked = parseInt(p.is_wholesale_available) === 1;
document.getElementById('prod-featured').checked = parseInt(p.is_featured) === 1;
document.getElementById('modal-title').innerText = 'ویرایش محصول: ' + p.name;
document.getElementById('new-product-modal').classList.remove('hidden');
}
</script>
<?php
require __DIR__ . '/layout_footer.php';
?>
+54
View File
@@ -0,0 +1,54 @@
<?php
$pageTitle = 'تنظیمات فروشگاه و درگاه‌های مالی';
require __DIR__ . '/layout_header.php';
?>
<div class="max-w-3xl mx-auto bg-white rounded-2xl border border-stone-200 p-8 shadow-sm">
<form action="/admin/settings" method="POST" class="space-y-6 text-xs">
<h4 class="font-bold text-sm text-stone-900 border-b pb-3">اطلاعات عمومی مزرعه</h4>
<div>
<label class="block font-bold text-stone-700 mb-1">نام کامل مجموعه / مزرعه</label>
<input type="text" name="farm_name" value="<?= htmlspecialchars($settings['farm_name'] ?? '') ?>" class="w-full bg-stone-50 border border-stone-300 rounded-xl p-3 text-xs focus:ring-2 focus:ring-amber-500">
</div>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div>
<label class="block font-bold text-stone-700 mb-1">تلفن همراه مدیریت</label>
<input type="tel" name="phone" value="<?= htmlspecialchars($settings['phone'] ?? '') ?>" class="w-full bg-stone-50 border border-stone-300 rounded-xl p-3 text-xs focus:ring-2 focus:ring-amber-500">
</div>
<div>
<label class="block font-bold text-stone-700 mb-1">تلفن ثابت دفتر</label>
<input type="tel" name="landline" value="<?= htmlspecialchars($settings['landline'] ?? '') ?>" class="w-full bg-stone-50 border border-stone-300 rounded-xl p-3 text-xs focus:ring-2 focus:ring-amber-500">
</div>
</div>
<div>
<label class="block font-bold text-stone-700 mb-1">آدرس دقیق مزرعه</label>
<input type="text" name="address" value="<?= htmlspecialchars($settings['address'] ?? '') ?>" class="w-full bg-stone-50 border border-stone-300 rounded-xl p-3 text-xs focus:ring-2 focus:ring-amber-500">
</div>
<h4 class="font-bold text-sm text-stone-900 border-b pb-3 pt-4">اطلاعات واریز کارت به کارت</h4>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div>
<label class="block font-bold text-stone-700 mb-1">شماره کارت بانکی</label>
<input type="text" name="card_number" value="<?= htmlspecialchars($settings['card_number'] ?? '') ?>" class="w-full bg-stone-50 border border-stone-300 rounded-xl p-3 text-xs font-mono">
</div>
<div>
<label class="block font-bold text-stone-700 mb-1">نام صاحب حساب</label>
<input type="text" name="card_holder" value="<?= htmlspecialchars($settings['card_holder'] ?? '') ?>" class="w-full bg-stone-50 border border-stone-300 rounded-xl p-3 text-xs">
</div>
</div>
<div class="pt-4 border-t flex justify-end">
<button type="submit" class="px-8 py-3 rounded-xl bg-amber-500 hover:bg-amber-600 text-stone-950 font-black text-xs transition shadow-md">
ذخیره تمام تغییرات
</button>
</div>
</form>
</div>
<?php
require __DIR__ . '/layout_footer.php';
?>
+66
View File
@@ -0,0 +1,66 @@
<?php
$pageTitle = 'استعلام‌ها و درخواست‌های فروش عمده';
require __DIR__ . '/layout_header.php';
?>
<div class="bg-white rounded-2xl border border-stone-200 shadow-sm overflow-hidden">
<div class="overflow-x-auto">
<table class="w-full text-right text-xs">
<thead class="bg-stone-50 text-stone-600 border-b">
<tr>
<th class="p-3.5">نام متقاضی</th>
<th class="p-3.5">شماره همراه</th>
<th class="p-3.5">شرکت / فروشگاه</th>
<th class="p-3.5">محصول مورد نظر</th>
<th class="p-3.5">حجم / تیراژ</th>
<th class="p-3.5">شهر مقصد</th>
<th class="p-3.5">وضعیت</th>
<th class="p-3.5">عملیات</th>
</tr>
</thead>
<tbody class="divide-y divide-stone-100">
<?php if (empty($inquiries)): ?>
<tr><td colspan="8" class="p-8 text-center text-stone-400">استعلامی ثبت نشده است.</td></tr>
<?php else: ?>
<?php foreach ($inquiries as $inq): ?>
<tr class="hover:bg-stone-50">
<td class="p-3.5 font-bold text-stone-900"><?= htmlspecialchars($inq['customer_name']) ?></td>
<td class="p-3.5 font-mono text-stone-700">
<a href="tel:<?= $inq['phone'] ?>" class="text-amber-700 font-bold hover:underline"><?= htmlspecialchars($inq['phone']) ?></a>
</td>
<td class="p-3.5 text-stone-600"><?= htmlspecialchars($inq['company_name'] ?: '-') ?></td>
<td class="p-3.5 font-bold text-amber-900"><?= htmlspecialchars($inq['product_requested']) ?></td>
<td class="p-3.5 text-stone-600"><?= htmlspecialchars($inq['estimated_qty'] ?: '-') ?></td>
<td class="p-3.5 text-stone-600"><?= htmlspecialchars($inq['city'] ?: '-') ?></td>
<td class="p-3.5">
<span class="px-2.5 py-1 rounded-full text-[10px] font-bold <?= $inq['status'] === 'new' ? 'bg-rose-100 text-rose-800' : 'bg-emerald-100 text-emerald-800' ?>">
<?= $inq['status'] === 'new' ? 'جدید' : 'رسیدگی شده' ?>
</span>
</td>
<td class="p-3.5">
<form action="/admin/wholesale-inquiry/update-status" method="POST">
<input type="hidden" name="id" value="<?= $inq['id'] ?>">
<input type="hidden" name="status" value="<?= $inq['status'] === 'new' ? 'contacted' : 'new' ?>">
<button type="submit" class="px-2.5 py-1 rounded bg-stone-100 hover:bg-stone-200 text-stone-700 text-xs">
<?= $inq['status'] === 'new' ? 'تغییر به بررسی‌شده' : 'تغییر به جدید' ?>
</button>
</form>
</td>
</tr>
<?php if ($inq['notes']): ?>
<tr class="bg-amber-50/30">
<td colspan="8" class="p-2.5 px-4 text-[11px] text-stone-600">
<span class="font-bold text-amber-800">یادداشت متقاضی:</span> <?= htmlspecialchars($inq['notes']) ?>
</td>
</tr>
<?php endif; ?>
<?php endforeach; ?>
<?php endif; ?>
</tbody>
</table>
</div>
</div>
<?php
require __DIR__ . '/layout_footer.php';
?>
+133
View File
@@ -0,0 +1,133 @@
<footer class="bg-stone-900 text-stone-300 mt-auto pt-14 pb-8 border-t border-stone-800">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-10 pb-10 border-b border-stone-800">
<!-- Col 1: About Farm -->
<div>
<div class="flex items-center gap-3 mb-4">
<div class="w-10 h-10 rounded-lg bg-amber-600 text-white flex items-center justify-center shadow">
<i class="fas fa-feather-alt text-xl"></i>
</div>
<span class="text-lg font-extrabold text-white"><?= \Bildirchin\Config::APP_NAME ?></span>
</div>
<p class="text-sm text-stone-400 leading-relaxed mb-5">
بزرگ‌ترین مجتمع زنجیره‌ای اصلاح نژاد، تولید و پرورش صنعتی بلدرچین در کشور. عرضه مستقیم گوشت کشتار روز، تخم نطفه‌دار و خوراکی، جیره غذایی و دان استاندارد با بالاترین کیفیت و مجوزهای رسمی دامپزشکی.
</p>
<div class="flex items-center gap-3 text-stone-400">
<a href="https://t.me/<?= \Bildirchin\Config::TELEGRAM ?>" class="w-9 h-9 rounded-full bg-stone-800 hover:bg-sky-600 hover:text-white flex items-center justify-center transition" title="کانال تلگرام"><i class="fab fa-telegram"></i></a>
<a href="https://wa.me/98<?= substr(\Bildirchin\Config::WHATSAPP, 1) ?>" class="w-9 h-9 rounded-full bg-stone-800 hover:bg-emerald-600 hover:text-white flex items-center justify-center transition" title="واتساپ"><i class="fab fa-whatsapp"></i></a>
<a href="tel:<?= \Bildirchin\Config::PHONE ?>" class="w-9 h-9 rounded-full bg-stone-800 hover:bg-amber-600 hover:text-white flex items-center justify-center transition" title="تماس تلفنی"><i class="fas fa-phone"></i></a>
</div>
</div>
<!-- Col 2: Quick Links -->
<div>
<h3 class="text-white font-bold text-base mb-4 flex items-center gap-2">
<span class="w-2 h-2 rounded-full bg-amber-500"></span> دسترسی سریع
</h3>
<ul class="space-y-2.5 text-sm">
<li><a href="/products" class="hover:text-amber-400 transition flex items-center gap-2"><i class="fas fa-angle-left text-xs text-amber-500"></i> فروشگاه و کاتالوگ محصولات</a></li>
<li><a href="/wholesale" class="hover:text-amber-400 transition flex items-center gap-2"><i class="fas fa-angle-left text-xs text-amber-500"></i> جدول تخفیف و فروش عمده</a></li>
<li><a href="/track" class="hover:text-amber-400 transition flex items-center gap-2"><i class="fas fa-angle-left text-xs text-amber-500"></i> پیگیری آنلاین وضعیت سفارش</a></li>
<li><a href="/blog" class="hover:text-amber-400 transition flex items-center gap-2"><i class="fas fa-angle-left text-xs text-amber-500"></i> مقالات و آموزش پرورش بلدرچین</a></li>
<li><a href="/about" class="hover:text-amber-400 transition flex items-center gap-2"><i class="fas fa-angle-left text-xs text-amber-500"></i> درباره تاریخچه و ظرفیت مزرعه</a></li>
<li><a href="/contact" class="hover:text-amber-400 transition flex items-center gap-2"><i class="fas fa-angle-left text-xs text-amber-500"></i> آدرس و راه‌های ارتباطی</a></li>
</ul>
</div>
<!-- Col 3: Categories -->
<div>
<h3 class="text-white font-bold text-base mb-4 flex items-center gap-2">
<span class="w-2 h-2 rounded-full bg-amber-500"></span> دسته‌بندی‌های اصلی
</h3>
<ul class="space-y-2.5 text-sm">
<li><a href="/products?cat=1" class="hover:text-amber-400 transition flex items-center gap-2"><i class="fas fa-feather text-xs text-amber-500"></i> بلدرچین زنده و کشتار روز</a></li>
<li><a href="/products?cat=2" class="hover:text-amber-400 transition flex items-center gap-2"><i class="fas fa-egg text-xs text-amber-500"></i> تخم بلدرچین خوراکی و نطفه‌دار</a></li>
<li><a href="/products?cat=3" class="hover:text-amber-400 transition flex items-center gap-2"><i class="fas fa-seedling text-xs text-amber-500"></i> دان استارتر، رشد و تخم‌گذار</a></li>
<li><a href="/products?cat=4" class="hover:text-amber-400 transition flex items-center gap-2"><i class="fas fa-warehouse text-xs text-amber-500"></i> قفس صنعتی و تجهیزات مرغداری</a></li>
</ul>
</div>
<!-- Col 4: Contact info & Trust -->
<div>
<h3 class="text-white font-bold text-base mb-4 flex items-center gap-2">
<span class="w-2 h-2 rounded-full bg-amber-500"></span> ارتباط با مدیریت فروش
</h3>
<ul class="space-y-3 text-sm text-stone-400">
<li class="flex items-start gap-3">
<i class="fas fa-map-marker-alt text-amber-500 mt-1"></i>
<span><?= \Bildirchin\Config::ADDRESS ?></span>
</li>
<li class="flex items-center gap-3">
<i class="fas fa-mobile-screen text-amber-500"></i>
<span>همراه: <a href="tel:<?= \Bildirchin\Config::PHONE ?>" class="text-white font-bold tracking-wider hover:text-amber-400"><?= \Bildirchin\Helpers::toPersianDigits(\Bildirchin\Config::PHONE) ?></a></span>
</li>
<li class="flex items-center gap-3">
<i class="fas fa-phone text-amber-500"></i>
<span>دفتر مرکزی: <a href="tel:<?= \Bildirchin\Config::PHONE_LANDLINE ?>" class="text-white tracking-wider hover:text-amber-400"><?= \Bildirchin\Helpers::toPersianDigits(\Bildirchin\Config::PHONE_LANDLINE) ?></a></span>
</li>
<li class="flex items-center gap-3">
<i class="fas fa-clock text-amber-500"></i>
<span>ساعات پاسخگویی: همه‌روزه از ۸:۰۰ الی ۲۱:۰۰</span>
</li>
</ul>
</div>
</div>
<!-- Copyright -->
<div class="mt-8 flex flex-col sm:flex-row items-center justify-between text-xs text-stone-500 gap-4">
<p>© <?= date('Y') ?> تمامی حقوق مادی و معنوی متعلق به <?= \Bildirchin\Config::APP_NAME ?> می‌باشد.</p>
<p>توسعه‌یافته بر بستر مدرن PHP و سرورهای ابری اختصاصی</p>
</div>
</div>
</footer>
<script>
// Global helper for ajax add to cart
async function addToCart(productId, quantity = 1) {
try {
const formData = new FormData();
formData.append('product_id', productId);
formData.append('quantity', quantity);
const res = await fetch('/cart/add', {
method: 'POST',
body: formData,
headers: {
'X-Requested-With': 'XMLHttpRequest',
'Accept': 'application/json'
}
});
const data = await res.json();
if (data.success) {
let badge = document.getElementById('cart-badge');
if (!badge) {
const cartBtn = document.querySelector('a[href="/cart"]');
badge = document.createElement('span');
badge.id = 'cart-badge';
badge.className = 'absolute -top-1.5 -right-1.5 bg-rose-600 text-white text-xs font-bold w-5 h-5 rounded-full flex items-center justify-center shadow-sm';
cartBtn.appendChild(badge);
}
badge.innerText = data.cart_count;
// Show notification toast
showToast(data.message || 'به سبد خرید اضافه شد');
}
} catch (e) {
console.error(e);
window.location.href = '/cart';
}
}
function showToast(msg) {
const toast = document.createElement('div');
toast.className = 'fixed bottom-5 left-5 bg-stone-900 text-white px-5 py-3 rounded-xl shadow-2xl z-50 flex items-center gap-3 border border-amber-500 transition transform duration-300';
toast.innerHTML = '<i class="fas fa-check-circle text-emerald-400 text-lg"></i><span class="text-sm font-medium">' + msg + '</span>';
document.body.appendChild(toast);
setTimeout(() => {
toast.classList.add('opacity-0', 'translate-y-2');
setTimeout(() => toast.remove(), 300);
}, 3000);
}
</script>
</body>
</html>
+52
View File
@@ -0,0 +1,52 @@
<!DOCTYPE html>
<html lang="fa" dir="rtl">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?= isset($pageTitle) ? htmlspecialchars($pageTitle) . ' | ' : '' ?><?= \Bildirchin\Config::APP_NAME ?></title>
<meta name="description" content="<?= \Bildirchin\Config::APP_SLOGAN ?>">
<!-- Tailwind CSS CDN -->
<script src="https://cdn.tailwindcss.com"></script>
<script>
tailwind.config = {
theme: {
extend: {
colors: {
primary: {
50: '#f0fdf4',
100: '#dcfce7',
500: '#22c55e',
600: '#16a34a',
700: '#15803d',
800: '#166534',
900: '#14532d'
},
amber: {
500: '#f59e0b',
600: '#d97706',
700: '#b45309',
800: '#92400e'
}
},
fontFamily: {
sans: ['Vazirmatn', 'Tahoma', 'sans-serif']
}
}
}
}
</script>
<!-- Google Font Vazirmatn & FontAwesome -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Vazirmatn:wght@300;400;500;600;700;800;900&display=swap" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<style>
body {
font-family: 'Vazirmatn', Tahoma, sans-serif;
}
.persian-num {
font-feature-settings: "ss01";
}
</style>
</head>
<body class="bg-stone-50 text-stone-800 flex flex-col min-h-screen">
+127
View File
@@ -0,0 +1,127 @@
<?php
$cartCount = count(\Bildirchin\Controllers\CartController::getCart());
?>
<!-- Top Notification Bar -->
<div class="bg-amber-600 text-white text-xs py-1.5 px-4 text-center font-medium flex justify-between items-center max-w-7xl mx-auto w-full">
<div class="hidden md:flex items-center gap-4">
<span><i class="fas fa-truck-fast ml-1"></i> ارسال مستقیم از مزرعه به سراسر کشور با باربری و خودرو یخچال‌دار</span>
<span class="text-amber-200">|</span>
<span><i class="fas fa-shield-alt ml-1"></i> تضمین هچ و کیفیت سلامت گله</span>
</div>
<div class="flex items-center justify-between w-full md:w-auto gap-4">
<span><i class="fas fa-phone-volume ml-1"></i> مشاوره و سفارش: <a href="tel:<?= \Bildirchin\Config::PHONE ?>" class="font-bold underline tracking-wider"><?= \Bildirchin\Helpers::toPersianDigits(\Bildirchin\Config::PHONE) ?></a></span>
<a href="/track" class="text-amber-100 hover:text-white underline"><i class="fas fa-magnifying-glass ml-1"></i> پیگیری سفارش</a>
</div>
</div>
<!-- Main Header & Navigation -->
<header class="bg-white border-b border-stone-200 sticky top-0 z-50 shadow-sm">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex justify-between items-center h-20">
<!-- Brand Logo -->
<a href="/" class="flex items-center gap-3 group">
<div class="w-12 h-12 rounded-xl bg-gradient-to-tr from-amber-600 to-amber-500 text-white flex items-center justify-center shadow-md group-hover:scale-105 transition">
<i class="fas fa-feather-alt text-2xl"></i>
</div>
<div>
<span class="text-xl font-extrabold text-stone-900 block tracking-tight group-hover:text-amber-600 transition"><?= \Bildirchin\Config::APP_NAME ?></span>
<span class="text-xs text-stone-500 block font-normal">مرکز تخصصی پرورش و فروش عمده و خرد بلدرچین</span>
</div>
</a>
<!-- Search Bar (Desktop) -->
<div class="hidden lg:block flex-1 max-w-md mx-8">
<form action="/products" method="GET" class="relative">
<input type="text" name="q" placeholder="جستجوی بلدرچین، تخم نطفه‌دار، دان، قفس..."
class="w-full bg-stone-100 border border-stone-300 rounded-full py-2.5 pr-11 pl-4 text-sm focus:outline-none focus:ring-2 focus:ring-amber-500 focus:bg-white transition">
<button type="submit" class="absolute right-3.5 top-3 text-stone-400 hover:text-amber-600">
<i class="fas fa-search text-base"></i>
</button>
</form>
</div>
<!-- Action Buttons -->
<div class="flex items-center gap-3">
<!-- Wholesale Badge Link -->
<a href="/wholesale" class="hidden sm:inline-flex items-center gap-1.5 px-3.5 py-2 rounded-lg bg-amber-50 text-amber-800 border border-amber-200 text-sm font-semibold hover:bg-amber-100 transition shadow-sm animate-pulse">
<i class="fas fa-boxes-stacked text-amber-600"></i>
<span>بخش فروش عمده</span>
</a>
<!-- Cart Button -->
<a href="/cart" class="relative flex items-center justify-center w-11 h-11 rounded-xl bg-stone-100 hover:bg-amber-50 hover:text-amber-700 text-stone-700 transition border border-stone-200" title="سبد خرید">
<i class="fas fa-shopping-basket text-lg"></i>
<?php if ($cartCount > 0): ?>
<span class="absolute -top-1.5 -right-1.5 bg-rose-600 text-white text-xs font-bold w-5 h-5 rounded-full flex items-center justify-center shadow-sm" id="cart-badge">
<?= \Bildirchin\Helpers::toPersianDigits($cartCount) ?>
</span>
<?php endif; ?>
</a>
<!-- Admin Link -->
<a href="/admin" class="flex items-center justify-center w-11 h-11 rounded-xl bg-stone-100 hover:bg-stone-200 text-stone-600 transition border border-stone-200" title="پنل مدیریت">
<i class="fas fa-user-shield text-base"></i>
</a>
</div>
</div>
<!-- Navigation Links -->
<nav class="flex items-center gap-1 sm:gap-6 py-2.5 overflow-x-auto text-sm font-medium border-t border-stone-100 no-scrollbar">
<a href="/" class="px-3 py-1.5 rounded-lg text-stone-700 hover:text-amber-600 hover:bg-amber-50 transition flex items-center gap-1.5">
<i class="fas fa-home text-stone-400"></i> صفحه اصلی
</a>
<a href="/products" class="px-3 py-1.5 rounded-lg text-stone-700 hover:text-amber-600 hover:bg-amber-50 transition flex items-center gap-1.5">
<i class="fas fa-store text-stone-400"></i> همه محصولات
</a>
<a href="/products?cat=1" class="px-3 py-1.5 rounded-lg text-stone-700 hover:text-amber-600 hover:bg-amber-50 transition flex items-center gap-1.5">
<i class="fas fa-feather-alt text-amber-500"></i> بلدرچین زنده و گوشت
</a>
<a href="/products?cat=2" class="px-3 py-1.5 rounded-lg text-stone-700 hover:text-amber-600 hover:bg-amber-50 transition flex items-center gap-1.5">
<i class="fas fa-egg text-amber-500"></i> تخم خوراکی و نطفه‌دار
</a>
<a href="/products?cat=3" class="px-3 py-1.5 rounded-lg text-stone-700 hover:text-amber-600 hover:bg-amber-50 transition flex items-center gap-1.5">
<i class="fas fa-seedling text-emerald-500"></i> دان و جیره غذایی
</a>
<a href="/products?cat=4" class="px-3 py-1.5 rounded-lg text-stone-700 hover:text-amber-600 hover:bg-amber-50 transition flex items-center gap-1.5">
<i class="fas fa-warehouse text-sky-500"></i> قفس و ملزومات
</a>
<a href="/wholesale" class="px-3 py-1.5 rounded-lg text-amber-700 font-bold hover:text-amber-800 hover:bg-amber-100 transition flex items-center gap-1.5">
<i class="fas fa-calculator text-amber-600"></i> استعلام قیمت عمده
</a>
<a href="/blog" class="px-3 py-1.5 rounded-lg text-stone-700 hover:text-amber-600 hover:bg-amber-50 transition flex items-center gap-1.5">
<i class="fas fa-book-open text-stone-400"></i> مقالات و آموزش
</a>
<a href="/about" class="px-3 py-1.5 rounded-lg text-stone-700 hover:text-amber-600 hover:bg-amber-50 transition">درباره مزرعه</a>
<a href="/contact" class="px-3 py-1.5 rounded-lg text-stone-700 hover:text-amber-600 hover:bg-amber-50 transition">تماس با ما</a>
</nav>
</div>
</header>
<!-- Flash Messages -->
<?php
$successMsg = \Bildirchin\Helpers::flash('success');
$errorMsg = \Bildirchin\Helpers::flash('error');
?>
<?php if ($successMsg): ?>
<div class="max-w-7xl mx-auto px-4 mt-4">
<div class="bg-emerald-50 border border-emerald-300 text-emerald-800 px-4 py-3 rounded-xl flex items-center justify-between shadow-sm">
<div class="flex items-center gap-2">
<i class="fas fa-check-circle text-emerald-600 text-lg"></i>
<span class="font-medium text-sm"><?= htmlspecialchars($successMsg) ?></span>
</div>
<button onclick="this.parentElement.remove()" class="text-emerald-500 hover:text-emerald-800"><i class="fas fa-times"></i></button>
</div>
</div>
<?php endif; ?>
<?php if ($errorMsg): ?>
<div class="max-w-7xl mx-auto px-4 mt-4">
<div class="bg-rose-50 border border-rose-300 text-rose-800 px-4 py-3 rounded-xl flex items-center justify-between shadow-sm">
<div class="flex items-center gap-2">
<i class="fas fa-exclamation-triangle text-rose-600 text-lg"></i>
<span class="font-medium text-sm"><?= htmlspecialchars($errorMsg) ?></span>
</div>
<button onclick="this.parentElement.remove()" class="text-rose-500 hover:text-rose-800"><i class="fas fa-times"></i></button>
</div>
</div>
<?php endif; ?>
+18
View File
@@ -0,0 +1,18 @@
<?php
$pageTitle = 'صفحه یافت نشد - ۴۰۴';
require __DIR__ . '/../layout/header.php';
require __DIR__ . '/../layout/navbar.php';
?>
<div class="max-w-xl mx-auto px-4 py-20 text-center space-y-5">
<span class="text-7xl font-black text-amber-500 block persian-num">۴۰۴</span>
<h1 class="text-2xl font-bold text-stone-800">صفحه مورد نظر پیدا نشد!</h1>
<p class="text-xs text-stone-500">آدرس وارد شده تغییر کرده یا حذف شده است.</p>
<a href="/" class="inline-block px-6 py-3 rounded-xl bg-amber-500 text-stone-950 font-bold text-xs hover:bg-amber-600 transition">
بازگشت به صفحه اصلی
</a>
</div>
<?php
require __DIR__ . '/../layout/footer.php';
?>
+45
View File
@@ -0,0 +1,45 @@
<?php
$pageTitle = 'درباره مزرعه و مجتمع پرورشی بلدرچین زرین';
require __DIR__ . '/../layout/header.php';
require __DIR__ . '/../layout/navbar.php';
?>
<div class="bg-stone-100/60 py-10 border-b border-stone-200">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-center space-y-2">
<h1 class="text-3xl font-black text-stone-900">درباره مجتمع پرورشی بلدرچین زرین</h1>
<p class="text-sm text-stone-500 max-w-2xl mx-auto">پیشگام در تولید صنعتی و سالم طیور با بیش از یک دهه سابقه درخشان</p>
</div>
</div>
<div class="max-w-5xl mx-auto px-4 sm:px-6 lg:px-8 py-12 space-y-12">
<div class="bg-white rounded-3xl border border-stone-200 p-8 sm:p-12 shadow-sm space-y-6 text-sm text-stone-600 leading-loose">
<h2 class="text-xl font-bold text-stone-900 flex items-center gap-2">
<i class="fas fa-seedling text-amber-600"></i> داستان شکل‌گیری و رسالت مزرعه
</h2>
<p>
مجتمع پرورشی بلدرچین زرین با هدف تامین پروتئین سالم، ارگانیک و باکیفیت برای سفره خانواده‌های ایرانی و تامین پایدار نیاز صنایع غذایی، رستوران‌ها و سالن‌داران در سال ۱۳۹۰ تاسیس شد. این مجموعه اکنون با بهره‌گیری از پیشرفته‌ترین سالن‌های تمام‌مکانیزه، خطوط مدرن بسته‌بندی تحت خلاء، و سالن‌های اختصاصی جوجه‌کشی با ظرفیت سالانه صدها هزار قطعه، به یکی از معتبرترین قطب‌های تولید بلدرچین در کشور تبدیل شده است.
</p>
<div class="grid grid-cols-1 md:grid-cols-3 gap-6 pt-6">
<div class="bg-stone-50 p-5 rounded-2xl border border-stone-100 text-center">
<i class="fas fa-award text-3xl text-amber-500 mb-3 block"></i>
<h4 class="font-bold text-stone-900 mb-1">مجوز رسمی دامپزشکی</h4>
<p class="text-xs text-stone-500">نظارت مداوم بهداشتی و قرنطینه استاندارد</p>
</div>
<div class="bg-stone-50 p-5 rounded-2xl border border-stone-100 text-center">
<i class="fas fa-truck-fast text-3xl text-emerald-500 mb-3 block"></i>
<h4 class="font-bold text-stone-900 mb-1">ناوگان ارسال مجهز</h4>
<p class="text-xs text-stone-500">ارسال کشتار روز با خودروهای سردخانه‌دار</p>
</div>
<div class="bg-stone-50 p-5 rounded-2xl border border-stone-100 text-center">
<i class="fas fa-dna text-3xl text-sky-500 mb-3 block"></i>
<h4 class="font-bold text-stone-900 mb-1">اصلاح نژاد سنگین</h4>
<p class="text-xs text-stone-500">بهترین راندمان گوشتی و تخم‌گذاری بالا</p>
</div>
</div>
</div>
</div>
<?php
require __DIR__ . '/../layout/footer.php';
?>
+48
View File
@@ -0,0 +1,48 @@
<?php
$pageTitle = 'دانشنامه و مقالات آموزشی پرورش بلدرچین';
require __DIR__ . '/../layout/header.php';
require __DIR__ . '/../layout/navbar.php';
?>
<div class="bg-stone-100/60 py-8 border-b border-stone-200">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<h1 class="text-2xl sm:text-3xl font-extrabold text-stone-900">دانشنامه و مقالات آموزشی</h1>
<p class="text-xs sm:text-sm text-stone-500 mt-1">راهنمای علمی و تجربی پرورش، تغذیه، بیماری‌ها و خواص محصولات بلدرچین</p>
</div>
</div>
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-10">
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
<?php foreach ($articles as $art): ?>
<div class="bg-white rounded-2xl border border-stone-200 overflow-hidden shadow-sm hover:shadow-md transition flex flex-col justify-between group">
<a href="/blog/<?= $art['slug'] ?>" class="block h-52 bg-stone-900 overflow-hidden">
<img src="<?= $art['image'] ?>" alt="<?= htmlspecialchars($art['title']) ?>" class="w-full h-full object-cover group-hover:scale-105 transition duration-300">
</a>
<div class="p-6 flex-1 flex flex-col justify-between">
<div>
<div class="flex items-center gap-2 text-xs text-stone-400 mb-2">
<i class="far fa-calendar-alt"></i>
<span><?= \Bildirchin\Helpers::getJalaliDate($art['created_at']) ?></span>
<span>•</span>
<span>نویسنده: <?= htmlspecialchars($art['author']) ?></span>
</div>
<a href="/blog/<?= $art['slug'] ?>" class="font-extrabold text-base text-stone-900 group-hover:text-amber-600 transition mb-3 block leading-snug">
<?= htmlspecialchars($art['title']) ?>
</a>
<p class="text-xs text-stone-500 line-clamp-3 leading-relaxed mb-4">
<?= htmlspecialchars($art['summary']) ?>
</p>
</div>
<a href="/blog/<?= $art['slug'] ?>" class="text-xs font-bold text-amber-600 hover:text-amber-700 flex items-center gap-1.5 pt-3 border-t border-stone-100">
<span>مطالعه کامل مقاله</span>
<i class="fas fa-arrow-left"></i>
</a>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
<?php
require __DIR__ . '/../layout/footer.php';
?>
+50
View File
@@ -0,0 +1,50 @@
<?php
$pageTitle = $article['title'];
require __DIR__ . '/../layout/header.php';
require __DIR__ . '/../layout/navbar.php';
?>
<div class="max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-10">
<div class="bg-white rounded-3xl border border-stone-200 overflow-hidden shadow-sm p-6 sm:p-10 space-y-6">
<div class="flex items-center gap-3 text-xs text-stone-400">
<a href="/blog" class="text-amber-600 font-bold hover:underline">بازگشت به مقالات</a>
<span>•</span>
<span>تاریخ انتشار: <?= \Bildirchin\Helpers::getJalaliDate($article['created_at']) ?></span>
<span>•</span>
<span><?= htmlspecialchars($article['author']) ?></span>
</div>
<h1 class="text-2xl sm:text-3xl font-black text-stone-900 leading-tight">
<?= htmlspecialchars($article['title']) ?>
</h1>
<div class="rounded-2xl overflow-hidden bg-stone-900 h-64 sm:h-80">
<img src="<?= $article['image'] ?>" class="w-full h-full object-cover">
</div>
<div class="bg-amber-50/70 p-4 rounded-xl border border-amber-200 text-xs sm:text-sm text-stone-700 leading-relaxed font-medium">
<i class="fas fa-quote-right text-amber-600 ml-1"></i>
<?= htmlspecialchars($article['summary']) ?>
</div>
<div class="prose max-w-none text-sm text-stone-700 leading-loose space-y-4 pt-4 border-t border-stone-100">
<?= nl2br(htmlspecialchars($article['content'])) ?>
</div>
<!-- Share and CTA box -->
<div class="bg-stone-50 rounded-2xl p-6 border border-stone-200 mt-10 flex flex-col sm:flex-row items-center justify-between gap-4">
<div>
<h4 class="font-bold text-sm text-stone-900">نیاز به مشاوره جهت راه‌اندازی سالن یا خرید دان دارید؟</h4>
<p class="text-xs text-stone-500 mt-0.5">کارشناسان فنی مزرعه بلدرچین زرین به صورت رایگان پاسخگوی شما هستند.</p>
</div>
<a href="tel:<?= \Bildirchin\Config::PHONE ?>" class="px-5 py-2.5 rounded-xl bg-amber-500 text-stone-950 font-bold text-xs hover:bg-amber-600 transition flex items-center gap-2">
<i class="fas fa-phone-volume"></i>
<span>تماس با مشاور</span>
</a>
</div>
</div>
</div>
<?php
require __DIR__ . '/../layout/footer.php';
?>
+140
View File
@@ -0,0 +1,140 @@
<?php
$pageTitle = 'سبد خرید';
require __DIR__ . '/../layout/header.php';
require __DIR__ . '/../layout/navbar.php';
?>
<div class="bg-stone-100/60 py-6 border-b border-stone-200">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<h1 class="text-2xl font-extrabold text-stone-900">سبد خرید شما</h1>
<p class="text-xs text-stone-500 mt-1">بررسی اقلام انتخابی و اعمال خودکار تخفیف‌های عمده‌فروشی</p>
</div>
</div>
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-10">
<?php if (empty($cartData['items'])): ?>
<div class="text-center py-20 bg-white rounded-3xl border border-stone-200 p-8 shadow-sm">
<div class="w-20 h-20 rounded-full bg-amber-50 text-amber-600 flex items-center justify-center text-3xl mx-auto mb-4">
<i class="fas fa-shopping-basket"></i>
</div>
<h2 class="text-xl font-bold text-stone-800">سبد خرید شما خالی است!</h2>
<p class="text-xs text-stone-400 mt-2 max-w-sm mx-auto">می‌توانید انواع بلدرچین، تخم خوراکی و نطفه‌دار، دان باکیفیت و ملزومات پرورش را از فروشگاه انتخاب کنید.</p>
<a href="/products" class="inline-block mt-6 px-8 py-3 rounded-xl bg-amber-500 text-stone-950 text-sm font-extrabold hover:bg-amber-600 transition shadow-md">
مشاهده و خرید محصولات
</a>
</div>
<?php else: ?>
<div class="grid grid-cols-1 lg:grid-cols-12 gap-8 items-start">
<!-- Items Table -->
<div class="lg:col-span-8 bg-white rounded-2xl border border-stone-200 overflow-hidden shadow-sm">
<div class="p-4 sm:p-6 border-b border-stone-100 flex items-center justify-between">
<span class="font-bold text-stone-900 text-sm">اقلام انتخابی (<?= \Bildirchin\Helpers::toPersianDigits(count($cartData['items'])) ?> قلم)</span>
<span class="text-xs text-amber-700 bg-amber-50 px-2.5 py-1 rounded-md font-bold"><i class="fas fa-magic ml-1"></i> تخفیف عمده خودکار فعال است</span>
</div>
<div class="divide-y divide-stone-100">
<?php foreach ($cartData['items'] as $item): ?>
<div class="p-4 sm:p-6 flex flex-col sm:flex-row items-start sm:items-center justify-between gap-4">
<div class="flex items-center gap-4">
<img src="<?= $item['product']['image'] ?>" class="w-16 h-16 rounded-xl object-contain bg-stone-50 p-2 border border-stone-100">
<div>
<a href="/product/<?= $item['product']['slug'] ?>" class="font-bold text-stone-900 hover:text-amber-600 transition text-sm sm:text-base block">
<?= htmlspecialchars($item['product']['name']) ?>
</a>
<div class="flex items-center gap-3 mt-1 text-xs">
<span class="text-stone-500">قیمت واحد: <?= \Bildirchin\Helpers::formatPrice($item['unit_price']) ?></span>
<?php if ($item['is_wholesale']): ?>
<span class="bg-emerald-100 text-emerald-800 text-[11px] font-bold px-2 py-0.5 rounded">
<i class="fas fa-tag ml-1"></i> نرخ عمده
</span>
<?php endif; ?>
</div>
</div>
</div>
<!-- Quantity Controller & Total -->
<div class="flex items-center justify-between w-full sm:w-auto gap-6">
<div class="flex items-center border border-stone-200 rounded-xl bg-stone-50 p-1">
<button type="button" onclick="updateCartItem(<?= $item['product']['id'] ?>, <?= $item['quantity'] - 1 ?>)" class="w-8 h-8 rounded-lg bg-white hover:bg-stone-200 text-stone-700 flex items-center justify-center font-bold">-</button>
<input type="number" value="<?= $item['quantity'] ?>" min="1" onchange="updateCartItem(<?= $item['product']['id'] ?>, this.value)" class="w-14 text-center font-bold text-sm bg-transparent focus:outline-none">
<button type="button" onclick="updateCartItem(<?= $item['product']['id'] ?>, <?= $item['quantity'] + 1 ?>)" class="w-8 h-8 rounded-lg bg-white hover:bg-stone-200 text-stone-700 flex items-center justify-center font-bold">+</button>
</div>
<div class="text-left">
<span class="block font-black text-stone-900 text-base"><?= \Bildirchin\Helpers::formatPrice($item['total_price']) ?></span>
<?php if ($item['savings'] > 0): ?>
<span class="text-[11px] text-emerald-600 font-bold block">سود: <?= \Bildirchin\Helpers::formatPrice($item['savings']) ?></span>
<?php endif; ?>
</div>
<a href="/cart/remove?product_id=<?= $item['product']['id'] ?>" class="text-stone-400 hover:text-rose-600 transition" title="حذف">
<i class="fas fa-trash-can text-sm"></i>
</a>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
<!-- Order Summary Card -->
<div class="lg:col-span-4 bg-white rounded-2xl border border-stone-200 p-6 shadow-sm space-y-5">
<h3 class="font-extrabold text-base text-stone-900 border-b pb-3">خلاصه پیش‌فاکتور</h3>
<div class="space-y-3 text-xs sm:text-sm text-stone-600">
<div class="flex justify-between">
<span>مجموع قیمت کالاها:</span>
<span class="font-bold text-stone-900"><?= \Bildirchin\Helpers::formatPrice($cartData['total_retail']) ?></span>
</div>
<?php if ($cartData['total_savings'] > 0): ?>
<div class="flex justify-between text-emerald-600 font-bold bg-emerald-50 p-2.5 rounded-xl border border-emerald-200">
<span>تخفیف همکاری و عمده‌فروشی:</span>
<span><?= \Bildirchin\Helpers::formatPrice($cartData['total_savings']) ?>-</span>
</div>
<?php endif; ?>
<div class="flex justify-between text-xs text-stone-400 pt-2 border-t">
<span>هزینه بسته‌بندی و ارسال:</span>
<span class="text-stone-700 font-medium">محاسبه در مرحله بعد (بر اساس مقصد)</span>
</div>
<div class="flex justify-between text-base font-black text-stone-900 pt-3 border-t">
<span>مبلغ قابل پرداخت:</span>
<span class="text-amber-800 text-lg"><?= \Bildirchin\Helpers::formatPrice($cartData['total_final']) ?></span>
</div>
</div>
<a href="/checkout" class="block w-full py-3.5 rounded-xl bg-amber-500 hover:bg-amber-600 text-stone-950 text-center font-black text-sm transition shadow-md">
ادامه و تکمیل اطلاعات سفارش <i class="fas fa-arrow-left mr-1"></i>
</a>
<a href="/products" class="block text-center text-xs text-stone-500 hover:text-amber-700 font-bold">
<i class="fas fa-plus ml-1"></i> افزودن محصولات دیگر
</a>
</div>
</div>
<?php endif; ?>
</div>
<script>
async function updateCartItem(productId, qty) {
if (qty < 0) qty = 0;
const formData = new FormData();
formData.append('product_id', productId);
formData.append('quantity', qty);
const res = await fetch('/cart/update', {
method: 'POST',
body: formData,
headers: {'X-Requested-With': 'XMLHttpRequest'}
});
const data = await res.json();
if (data.success) {
window.location.reload();
}
}
</script>
<?php
require __DIR__ . '/../layout/footer.php';
?>
+165
View File
@@ -0,0 +1,165 @@
<?php
$pageTitle = 'تکمیل سفارش و تسویه حساب';
require __DIR__ . '/../layout/header.php';
require __DIR__ . '/../layout/navbar.php';
?>
<div class="bg-stone-100/60 py-6 border-b border-stone-200">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<h1 class="text-2xl font-extrabold text-stone-900">تکمیل اطلاعات و ثبت سفارش</h1>
<p class="text-xs text-stone-500 mt-1">مشخصات تحویل‌گیرنده و انتخاب نحوه ارسال و پرداخت</p>
</div>
</div>
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-10">
<form action="/order/submit" method="POST">
<div class="grid grid-cols-1 lg:grid-cols-12 gap-8 items-start">
<!-- Customer Info & Shipping -->
<div class="lg:col-span-8 space-y-6">
<!-- Section 1: Receiver Details -->
<div class="bg-white rounded-2xl border border-stone-200 p-6 shadow-sm space-y-4">
<h3 class="font-extrabold text-base text-stone-900 flex items-center gap-2 border-b pb-3">
<i class="fas fa-user-circle text-amber-600"></i> ۱. مشخصات خریدار / تحویل‌گیرنده
</h3>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div>
<label class="block text-xs font-bold text-stone-700 mb-1">نام و نام‌خانوادگی *</label>
<input type="text" name="customer_name" required class="w-full bg-stone-50 border border-stone-300 rounded-xl p-3 text-sm focus:outline-none focus:ring-2 focus:ring-amber-500">
</div>
<div>
<label class="block text-xs font-bold text-stone-700 mb-1">شماره همراه تماس * (جهت دریافت کد رهگیری)</label>
<input type="tel" name="customer_phone" required placeholder="۰۹۱۲۳۴۵۶۷۸۹" class="w-full bg-stone-50 border border-stone-300 rounded-xl p-3 text-sm focus:outline-none focus:ring-2 focus:ring-amber-500">
</div>
</div>
<div class="grid grid-cols-1 sm:grid-cols-3 gap-4">
<div>
<label class="block text-xs font-bold text-stone-700 mb-1">استان *</label>
<input type="text" name="province" required placeholder="مثال: تهران / خراسان رضوی" class="w-full bg-stone-50 border border-stone-300 rounded-xl p-3 text-sm focus:outline-none focus:ring-2 focus:ring-amber-500">
</div>
<div>
<label class="block text-xs font-bold text-stone-700 mb-1">شهر *</label>
<input type="text" name="city" required placeholder="مثال: تهران / مشهد" class="w-full bg-stone-50 border border-stone-300 rounded-xl p-3 text-sm focus:outline-none focus:ring-2 focus:ring-amber-500">
</div>
<div>
<label class="block text-xs font-bold text-stone-700 mb-1">کد پستی</label>
<input type="text" name="postal_code" placeholder="۱۰ رقمی (اختیاری)" class="w-full bg-stone-50 border border-stone-300 rounded-xl p-3 text-sm focus:outline-none focus:ring-2 focus:ring-amber-500">
</div>
</div>
<div>
<label class="block text-xs font-bold text-stone-700 mb-1">آدرس دقیق پستی / باربری مقصد *</label>
<textarea name="address" rows="3" required placeholder="خیابان، کوچه، پلاک، یا آدرس ترمینال/باربری تحویل‌گیرنده..." class="w-full bg-stone-50 border border-stone-300 rounded-xl p-3 text-sm focus:outline-none focus:ring-2 focus:ring-amber-500"></textarea>
</div>
<div>
<label class="block text-xs font-bold text-stone-700 mb-1">یادداشت و هماهنگی خاص (اختیاری)</label>
<input type="text" name="notes" placeholder="مثال: تحویل عصر انجام شود یا هماهنگی باربری..." class="w-full bg-stone-50 border border-stone-300 rounded-xl p-3 text-sm focus:outline-none focus:ring-2 focus:ring-amber-500">
</div>
</div>
<!-- Section 2: Shipping Method -->
<div class="bg-white rounded-2xl border border-stone-200 p-6 shadow-sm space-y-4">
<h3 class="font-extrabold text-base text-stone-900 flex items-center gap-2 border-b pb-3">
<i class="fas fa-truck-fast text-amber-600"></i> ۲. روش ارسال
</h3>
<div class="grid grid-cols-1 sm:grid-cols-3 gap-3">
<label class="border border-stone-200 rounded-xl p-3.5 flex items-start gap-3 cursor-pointer hover:border-amber-500 has-[:checked]:border-amber-600 has-[:checked]:bg-amber-50/50 transition">
<input type="radio" name="shipping_method" value="باربری و ترمینال (بین‌شهری)" checked class="mt-1 text-amber-600 focus:ring-amber-500">
<div>
<span class="font-bold text-xs text-stone-900 block">باربری و اتوبوس</span>
<span class="text-[11px] text-stone-500">مناسب دان، تخم نطفه‌دار و بلدرچین زنده (پس‌کرایه)</span>
</div>
</label>
<label class="border border-stone-200 rounded-xl p-3.5 flex items-start gap-3 cursor-pointer hover:border-amber-500 has-[:checked]:border-amber-600 has-[:checked]:bg-amber-50/50 transition">
<input type="radio" name="shipping_method" value="وانت یخچال‌دار مزرعه" class="mt-1 text-amber-600 focus:ring-amber-500">
<div>
<span class="font-bold text-xs text-stone-900 block">وانت یخچال‌دار</span>
<span class="text-[11px] text-stone-500">ویژه گوشت کشتار روز در تهران و حومه</span>
</div>
</label>
<label class="border border-stone-200 rounded-xl p-3.5 flex items-start gap-3 cursor-pointer hover:border-amber-500 has-[:checked]:border-amber-600 has-[:checked]:bg-amber-50/50 transition">
<input type="radio" name="shipping_method" value="تحویل حضوری در مزرعه" class="mt-1 text-amber-600 focus:ring-amber-500">
<div>
<span class="font-bold text-xs text-stone-900 block">تحویل حضوری درب مزرعه</span>
<span class="text-[11px] text-stone-500">بارگیری مستقیم توسط خریدار در مزرعه</span>
</div>
</label>
</div>
</div>
<!-- Section 3: Payment Method -->
<div class="bg-white rounded-2xl border border-stone-200 p-6 shadow-sm space-y-4">
<h3 class="font-extrabold text-base text-stone-900 flex items-center gap-2 border-b pb-3">
<i class="fas fa-credit-card text-amber-600"></i> ۳. شیوه پرداخت
</h3>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
<label class="border border-stone-200 rounded-xl p-4 flex items-start gap-3 cursor-pointer hover:border-amber-500 has-[:checked]:border-amber-600 has-[:checked]:bg-amber-50/50 transition">
<input type="radio" name="payment_method" value="کارت به کارت / فیش واریزی" checked class="mt-1 text-amber-600 focus:ring-amber-500">
<div>
<span class="font-bold text-xs text-stone-900 block">واریز کارت به کارت / حواله پایا</span>
<span class="text-[11px] text-stone-500">شماره حساب و کارت مزرعه پس از ثبت نمایش داده می‌شود.</span>
</div>
</label>
<label class="border border-stone-200 rounded-xl p-4 flex items-start gap-3 cursor-pointer hover:border-amber-500 has-[:checked]:border-amber-600 has-[:checked]:bg-amber-50/50 transition">
<input type="radio" name="payment_method" value="تسویه در محل / زمان بارگیری" class="mt-1 text-amber-600 focus:ring-amber-500">
<div>
<span class="font-bold text-xs text-stone-900 block">تسویه هنگام تحویل و بارگیری</span>
<span class="text-[11px] text-stone-500">ویژه مشتریان ثابت، تحویل حضوری یا تهران</span>
</div>
</label>
</div>
</div>
</div>
<!-- Order Review Sidebar -->
<div class="lg:col-span-4 bg-white rounded-2xl border border-stone-200 p-6 shadow-sm space-y-5 sticky top-24">
<h3 class="font-extrabold text-base text-stone-900 border-b pb-3">اقلام فاکتور</h3>
<div class="max-h-60 overflow-y-auto space-y-3 pr-1 text-xs">
<?php foreach ($cartData['items'] as $it): ?>
<div class="flex items-center justify-between border-b border-stone-100 pb-2">
<div>
<span class="font-bold text-stone-800 block"><?= htmlspecialchars($it['product']['name']) ?></span>
<span class="text-stone-400"><?= \Bildirchin\Helpers::toPersianDigits($it['quantity']) ?> <?= $it['product']['unit'] ?> × <?= \Bildirchin\Helpers::formatPrice($it['unit_price']) ?></span>
</div>
<span class="font-black text-stone-900"><?= \Bildirchin\Helpers::formatPrice($it['total_price']) ?></span>
</div>
<?php endforeach; ?>
</div>
<div class="pt-3 border-t space-y-2 text-xs">
<div class="flex justify-between">
<span>مجموع قیمت:</span>
<span><?= \Bildirchin\Helpers::formatPrice($cartData['total_retail']) ?></span>
</div>
<?php if ($cartData['total_savings'] > 0): ?>
<div class="flex justify-between text-emerald-600 font-bold">
<span>تخفیف عمده:</span>
<span><?= \Bildirchin\Helpers::formatPrice($cartData['total_savings']) ?>-</span>
</div>
<?php endif; ?>
<div class="flex justify-between font-black text-sm text-stone-900 pt-2 border-t">
<span>مبلغ نهایی سفارش:</span>
<span class="text-amber-800 text-base"><?= \Bildirchin\Helpers::formatPrice($cartData['total_final']) ?></span>
</div>
</div>
<button type="submit" class="w-full py-4 rounded-xl bg-emerald-600 hover:bg-emerald-700 text-white font-extrabold text-sm transition shadow-lg flex items-center justify-center gap-2">
<i class="fas fa-check-double"></i>
<span>ثبت نهایی و دریافت کد رهگیری</span>
</button>
</div>
</div>
</form>
</div>
<?php
require __DIR__ . '/../layout/footer.php';
?>
+89
View File
@@ -0,0 +1,89 @@
<?php
$pageTitle = 'تماس با ما و آدرس مزرعه';
require __DIR__ . '/../layout/header.php';
require __DIR__ . '/../layout/navbar.php';
?>
<div class="max-w-6xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
<div class="grid grid-cols-1 lg:grid-cols-12 gap-10">
<!-- Contact Info -->
<div class="lg:col-span-5 bg-stone-900 text-white rounded-3xl p-8 sm:p-10 shadow-xl space-y-6">
<span class="text-xs font-bold text-amber-400 uppercase tracking-widest block">راه‌های ارتباطی</span>
<h2 class="text-2xl font-black">پاسخگوی سوالات و سفارش‌های شما هستیم</h2>
<p class="text-stone-400 text-xs sm:text-sm leading-relaxed">
جهت خرید حضوری، هماهنگی بارگیری، استعلام قیمت روز عمده یا مشاوره پرورش می‌توانید با شماره‌های زیر در ارتباط باشید.
</p>
<div class="space-y-4 pt-4 text-xs sm:text-sm text-stone-300">
<div class="flex items-start gap-3">
<i class="fas fa-map-location-dot text-amber-400 text-lg mt-0.5"></i>
<div>
<span class="font-bold text-white block mb-0.5">آدرس مجتمع پرورشی:</span>
<span><?= \Bildirchin\Config::ADDRESS ?></span>
</div>
</div>
<div class="flex items-center gap-3">
<i class="fas fa-phone-volume text-amber-400 text-lg"></i>
<div>
<span class="font-bold text-white block mb-0.5">تلفن همراه و مدیریت فروش:</span>
<a href="tel:<?= \Bildirchin\Config::PHONE ?>" class="text-amber-300 font-bold tracking-wider"><?= \Bildirchin\Helpers::toPersianDigits(\Bildirchin\Config::PHONE) ?></a>
</div>
</div>
<div class="flex items-center gap-3">
<i class="fas fa-phone text-amber-400 text-lg"></i>
<div>
<span class="font-bold text-white block mb-0.5">تلفن دفتر مرکزی:</span>
<a href="tel:<?= \Bildirchin\Config::PHONE_LANDLINE ?>" class="text-amber-300 tracking-wider"><?= \Bildirchin\Helpers::toPersianDigits(\Bildirchin\Config::PHONE_LANDLINE) ?></a>
</div>
</div>
<div class="flex items-center gap-3">
<i class="fab fa-whatsapp text-emerald-400 text-xl"></i>
<div>
<span class="font-bold text-white block mb-0.5">واتساپ و ارسال فیش:</span>
<a href="https://wa.me/98<?= substr(\Bildirchin\Config::WHATSAPP, 1) ?>" class="text-emerald-400 font-bold tracking-wider"><?= \Bildirchin\Helpers::toPersianDigits(\Bildirchin\Config::WHATSAPP) ?></a>
</div>
</div>
</div>
</div>
<!-- Fast Contact Message Form -->
<div class="lg:col-span-7 bg-white rounded-3xl border border-stone-200 p-8 sm:p-10 shadow-sm">
<h3 class="text-xl font-bold text-stone-900 mb-2">ارسال پیام به مدیریت مزرعه</h3>
<p class="text-xs text-stone-500 mb-6">پیام‌ها در طول ساعات کاری بررسی و پاسخ داده می‌شوند.</p>
<form action="/wholesale/inquiry" method="POST" class="space-y-4">
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div>
<label class="block text-xs font-bold text-stone-700 mb-1">نام شما *</label>
<input type="text" name="customer_name" required class="w-full bg-stone-50 border border-stone-300 rounded-xl p-3 text-sm focus:outline-none focus:ring-2 focus:ring-amber-500">
</div>
<div>
<label class="block text-xs font-bold text-stone-700 mb-1">شماره تماس *</label>
<input type="tel" name="phone" required class="w-full bg-stone-50 border border-stone-300 rounded-xl p-3 text-sm focus:outline-none focus:ring-2 focus:ring-amber-500">
</div>
</div>
<div>
<label class="block text-xs font-bold text-stone-700 mb-1">موضوع پیام / محصول مورد نظر</label>
<input type="text" name="product_requested" required placeholder="مثال: سوال درباره نحوه ارسال تخم نطفه‌دار" class="w-full bg-stone-50 border border-stone-300 rounded-xl p-3 text-sm focus:outline-none focus:ring-2 focus:ring-amber-500">
</div>
<div>
<label class="block text-xs font-bold text-stone-700 mb-1">متن پیام</label>
<textarea name="notes" rows="4" required class="w-full bg-stone-50 border border-stone-300 rounded-xl p-3 text-sm focus:outline-none focus:ring-2 focus:ring-amber-500"></textarea>
</div>
<button type="submit" class="w-full py-3.5 rounded-xl bg-amber-500 hover:bg-amber-600 text-stone-950 font-extrabold text-sm transition shadow-md">
ارسال پیام
</button>
</form>
</div>
</div>
</div>
<?php
require __DIR__ . '/../layout/footer.php';
?>
+391
View File
@@ -0,0 +1,391 @@
<?php
$pageTitle = 'صفحه اصلی';
require __DIR__ . '/../layout/header.php';
require __DIR__ . '/../layout/navbar.php';
?>
<!-- Hero Section -->
<section class="relative bg-gradient-to-br from-stone-900 via-stone-850 to-amber-950 text-white overflow-hidden py-16 md:py-24">
<div class="absolute inset-0 opacity-10 bg-[radial-gradient(#f59e0b_1px,transparent_1px)] [background-size:16px_16px]"></div>
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
<div class="grid grid-cols-1 lg:grid-cols-12 gap-12 items-center">
<!-- Hero Text -->
<div class="lg:col-span-7 space-y-6 text-center lg:text-right">
<div class="inline-flex items-center gap-2 px-3.5 py-1.5 rounded-full bg-amber-500/20 text-amber-300 border border-amber-500/30 text-xs font-semibold">
<i class="fas fa-certificate text-amber-400"></i>
<span>بزرگ‌ترین مجتمع پرورشی و اصلاح نژاد بلدرچین در کشور</span>
</div>
<h1 class="text-3xl sm:text-5xl font-black tracking-tight leading-tight sm:leading-snug">
خرید مستقیم و بی‌واسطه <br>
<span class="text-transparent bg-clip-text bg-gradient-to-r from-amber-400 to-amber-200">بلدرچین، تخم نطفه‌دار و خوراکی، دان و قفس</span>
</h1>
<p class="text-stone-300 text-base sm:text-lg leading-relaxed max-w-2xl mx-auto lg:mx-0">
تولید روزانه با بالاترین استانداردهای بهداشتی دامپزشکی. امکان خرید آنلاین در مقیاس خرد و ارائه بهترین قیمت‌های رقابتی برای سفارش‌های عمده، رستوران‌ها، هچری‌ها و سالن‌داران سراسر کشور.
</p>
<!-- CTA Buttons -->
<div class="flex flex-wrap items-center justify-center lg:justify-start gap-4 pt-2">
<a href="/products" class="px-7 py-3.5 rounded-xl bg-amber-500 hover:bg-amber-600 text-stone-950 font-extrabold text-base shadow-lg shadow-amber-500/25 transition transform hover:-translate-y-0.5 flex items-center gap-2">
<i class="fas fa-shopping-bag"></i>
<span>مشاهده محصولات و خرید</span>
</a>
<a href="/wholesale" class="px-7 py-3.5 rounded-xl bg-white/10 hover:bg-white/20 text-white font-bold text-base border border-white/20 backdrop-blur-sm transition flex items-center gap-2">
<i class="fas fa-boxes-stacked text-amber-400"></i>
<span>استعلام قیمت عمده و تناژ</span>
</a>
</div>
<!-- Fast Phone Banner -->
<div class="pt-4 flex items-center justify-center lg:justify-start gap-3 text-stone-400 text-sm">
<i class="fas fa-headset text-amber-400 text-lg"></i>
<span>پاسخگویی سریع و ثبت تلفنی:</span>
<a href="tel:<?= \Bildirchin\Config::PHONE ?>" class="text-amber-300 font-bold hover:underline tracking-wider"><?= \Bildirchin\Helpers::toPersianDigits(\Bildirchin\Config::PHONE) ?></a>
</div>
</div>
<!-- Hero Feature Card -->
<div class="lg:col-span-5">
<div class="bg-gradient-to-b from-stone-800/90 to-stone-900/90 p-6 sm:p-8 rounded-3xl border border-stone-700 shadow-2xl backdrop-blur-md relative overflow-hidden">
<div class="absolute -top-12 -right-12 w-40 h-40 bg-amber-500/10 rounded-full blur-2xl"></div>
<div class="text-center pb-6 border-b border-stone-700/80">
<span class="text-xs uppercase tracking-wider text-amber-400 font-bold block mb-1">ظرفیت و توانمندی مزرعه</span>
<h3 class="text-xl font-bold text-white">تامین پایدار برای مشتریان سراسر کشور</h3>
</div>
<div class="grid grid-cols-2 gap-4 my-6">
<div class="bg-stone-950/60 p-4 rounded-2xl border border-stone-800 text-center">
<span class="text-2xl font-black text-amber-400 block persian-num">۵۰,۰۰۰+</span>
<span class="text-xs text-stone-400 mt-1 block">تولید ماهانه بلدرچین</span>
</div>
<div class="bg-stone-950/60 p-4 rounded-2xl border border-stone-800 text-center">
<span class="text-2xl font-black text-emerald-400 block persian-num">۸۵٪ +</span>
<span class="text-xs text-stone-400 mt-1 block">تضمین هچ تخم نطفه‌دار</span>
</div>
<div class="bg-stone-950/60 p-4 rounded-2xl border border-stone-800 text-center">
<span class="text-2xl font-black text-sky-400 block persian-num">۱۰۰٪</span>
<span class="text-xs text-stone-400 mt-1 block">کشتار روز و ارگانیک</span>
</div>
<div class="bg-stone-950/60 p-4 rounded-2xl border border-stone-800 text-center">
<span class="text-2xl font-black text-rose-400 block persian-num">۲۴ ساعته</span>
<span class="text-xs text-stone-400 mt-1 block">ارسال با ماشین یخچال‌دار</span>
</div>
</div>
<a href="/wholesale" class="block w-full py-3 px-4 rounded-xl bg-amber-500 hover:bg-amber-600 text-stone-950 text-center font-bold text-sm transition">
دریافت پیش‌فاکتور رسمی و خرید تیراژ <i class="fas fa-arrow-left mr-1"></i>
</a>
</div>
</div>
</div>
</div>
</section>
<!-- Trust Badges -->
<section class="bg-white border-b border-stone-200 py-6">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="grid grid-cols-2 md:grid-cols-4 gap-6 text-center">
<div class="flex flex-col items-center justify-center p-3">
<div class="w-12 h-12 rounded-2xl bg-amber-50 text-amber-600 flex items-center justify-center text-xl mb-2 shadow-sm">
<i class="fas fa-hand-holding-dollar"></i>
</div>
<h4 class="font-bold text-stone-900 text-sm">قیمت مستقیم درب مزرعه</h4>
<p class="text-xs text-stone-500 mt-0.5">بدون واسطه و دلال با بهترین نرخ</p>
</div>
<div class="flex flex-col items-center justify-center p-3">
<div class="w-12 h-12 rounded-2xl bg-emerald-50 text-emerald-600 flex items-center justify-center text-xl mb-2 shadow-sm">
<i class="fas fa-shield-virus"></i>
</div>
<h4 class="font-bold text-stone-900 text-sm">مجوز و نظارت دامپزشکی</h4>
<p class="text-xs text-stone-500 mt-0.5">سلامت تضمین‌شده گله و کشتار بهداشتی</p>
</div>
<div class="flex flex-col items-center justify-center p-3">
<div class="w-12 h-12 rounded-2xl bg-sky-50 text-sky-600 flex items-center justify-center text-xl mb-2 shadow-sm">
<i class="fas fa-truck-ramp-box"></i>
</div>
<h4 class="font-bold text-stone-900 text-sm">ارسال به تمام استان‌ها</h4>
<p class="text-xs text-stone-500 mt-0.5">بسته‌بندی تخصصی بدون افت تلفات</p>
</div>
<div class="flex flex-col items-center justify-center p-3">
<div class="w-12 h-12 rounded-2xl bg-rose-50 text-rose-600 flex items-center justify-center text-xl mb-2 shadow-sm">
<i class="fas fa-headset"></i>
</div>
<h4 class="font-bold text-stone-900 text-sm">مشاوره رایگان پرورش</h4>
<p class="text-xs text-stone-500 mt-0.5">پشتیبانی فنی از دان تا جوجه‌کشی</p>
</div>
</div>
</div>
</section>
<!-- Categories Cards -->
<section class="py-14 max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="text-center max-w-2xl mx-auto mb-10">
<span class="text-xs font-bold text-amber-600 uppercase tracking-widest block mb-1">دسته‌بندی‌ها</span>
<h2 class="text-2xl sm:text-3xl font-extrabold text-stone-900">محصولات تولیدی و خدمات مزرعه</h2>
</div>
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6">
<?php foreach ($categories as $cat): ?>
<a href="/products?cat=<?= $cat['id'] ?>" class="group bg-white rounded-2xl p-6 border border-stone-200 hover:border-amber-400 shadow-sm hover:shadow-md transition flex flex-col justify-between">
<div>
<div class="w-14 h-14 rounded-2xl bg-amber-50 group-hover:bg-amber-500 text-amber-600 group-hover:text-white flex items-center justify-center text-2xl mb-5 transition shadow-sm">
<i class="<?= $cat['icon'] ?>"></i>
</div>
<h3 class="font-extrabold text-lg text-stone-900 group-hover:text-amber-600 transition mb-2"><?= htmlspecialchars($cat['name']) ?></h3>
<p class="text-xs text-stone-500 leading-relaxed"><?= htmlspecialchars($cat['description']) ?></p>
</div>
<div class="mt-6 pt-4 border-t border-stone-100 flex items-center justify-between text-xs font-bold text-stone-600 group-hover:text-amber-600">
<span>مشاهده محصولات</span>
<i class="fas fa-arrow-left transform group-hover:-translate-x-1 transition"></i>
</div>
</a>
<?php endforeach; ?>
</div>
</section>
<!-- Featured Products Section -->
<section class="py-14 bg-stone-100/70 border-y border-stone-200">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex flex-col sm:flex-row items-start sm:items-end justify-between mb-10 gap-4">
<div>
<span class="text-xs font-bold text-amber-600 uppercase tracking-widest block mb-1">محصولات برگزیده</span>
<h2 class="text-2xl sm:text-3xl font-extrabold text-stone-900">پرفروش‌ترین‌های مزرعه</h2>
</div>
<a href="/products" class="inline-flex items-center gap-2 text-sm font-bold text-amber-700 hover:text-amber-800 bg-white px-4 py-2 rounded-xl border border-stone-200 shadow-sm">
<span>مشاهده تمام محصولات</span>
<i class="fas fa-angle-left"></i>
</a>
</div>
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-6">
<?php foreach ($featuredProducts as $prod): ?>
<div class="bg-white rounded-2xl border border-stone-200 overflow-hidden shadow-sm hover:shadow-lg transition flex flex-col justify-between group">
<div class="relative">
<a href="/product/<?= $prod['slug'] ?>" class="block h-52 bg-stone-50 overflow-hidden p-4 flex items-center justify-center">
<img src="<?= $prod['image'] ?>" alt="<?= htmlspecialchars($prod['name']) ?>" class="max-h-full max-w-full object-contain group-hover:scale-105 transition duration-300">
</a>
<?php if ((int)$prod['is_wholesale_available'] === 1): ?>
<span class="absolute top-3 right-3 bg-amber-500 text-stone-950 text-[11px] font-extrabold px-2.5 py-1 rounded-lg shadow-sm">
<i class="fas fa-boxes-stacked ml-1"></i> تخفیف عمده
</span>
<?php endif; ?>
</div>
<div class="p-5 flex-1 flex flex-col justify-between">
<div>
<span class="text-[11px] font-semibold text-amber-700 block mb-1"><?= htmlspecialchars($prod['category_name']) ?></span>
<a href="/product/<?= $prod['slug'] ?>" class="font-bold text-stone-900 group-hover:text-amber-600 transition text-base block mb-2 leading-snug">
<?= htmlspecialchars($prod['name']) ?>
</a>
<p class="text-xs text-stone-500 line-clamp-2 mb-4 leading-relaxed">
<?= htmlspecialchars($prod['short_desc']) ?>
</p>
</div>
<div>
<!-- Price breakdown -->
<div class="bg-stone-50 p-3 rounded-xl mb-4 border border-stone-100">
<div class="flex items-center justify-between">
<span class="text-xs text-stone-500">قیمت مصرف‌کننده:</span>
<span class="text-base font-black text-stone-900"><?= \Bildirchin\Helpers::formatPrice($prod['price']) ?></span>
</div>
<?php if ((int)$prod['is_wholesale_available'] === 1 && $prod['wholesale_price'] > 0): ?>
<div class="flex items-center justify-between mt-1 pt-1 border-t border-stone-200/60 text-xs">
<span class="text-amber-700 font-medium">عمده (از <?= \Bildirchin\Helpers::toPersianDigits($prod['wholesale_min_qty']) ?> <?= $prod['unit'] ?>):</span>
<span class="font-bold text-emerald-700"><?= \Bildirchin\Helpers::formatPrice($prod['wholesale_price']) ?></span>
</div>
<?php endif; ?>
</div>
<!-- Buttons -->
<div class="flex items-center gap-2">
<a href="/product/<?= $prod['slug'] ?>" class="flex-1 text-center py-2.5 px-3 rounded-xl bg-stone-100 hover:bg-stone-200 text-stone-800 text-xs font-bold transition">
جزییات و خرید
</a>
<button onclick="addToCart(<?= $prod['id'] ?>, 1)" class="w-10 h-10 rounded-xl bg-amber-500 hover:bg-amber-600 text-stone-950 flex items-center justify-center transition shadow-sm" title="افزودن به سبد خرید">
<i class="fas fa-cart-plus"></i>
</button>
</div>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
</div>
</section>
<!-- Wholesale Calculator Interactive Banner -->
<section class="py-16 max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="bg-gradient-to-r from-amber-700 via-amber-800 to-stone-900 rounded-3xl text-white p-8 sm:p-12 shadow-xl border border-amber-600/30">
<div class="grid grid-cols-1 lg:grid-cols-12 gap-10 items-center">
<div class="lg:col-span-6 space-y-5 text-center lg:text-right">
<div class="inline-flex items-center gap-2 px-3 py-1 rounded-full bg-amber-400/20 text-amber-200 text-xs font-bold">
<i class="fas fa-calculator text-amber-300"></i>
<span>سیستم قیمت‌گذاری هوشمند عمده</span>
</div>
<h2 class="text-2xl sm:text-4xl font-extrabold leading-snug">
خرید عمده تناژ و تیراژ بالا <br>با تخفیف‌های ویژه مزرعه
</h2>
<p class="text-stone-300 text-sm leading-relaxed">
اگر صاحب رستوران، هتل، سالن پرورش، فروشگاه پروتئینی یا کارگاه جوجه‌کشی هستید، قیمت‌ها برای شما با نرخ عمده محاسبه می‌شود. همین حالا تیراژ مورد نیاز خود را در ماشین‌حساب روبرو انتخاب کنید.
</p>
<div class="pt-2 flex flex-wrap gap-4 justify-center lg:justify-start">
<a href="/wholesale" class="px-6 py-3 rounded-xl bg-white text-stone-900 font-extrabold text-sm hover:bg-amber-50 transition shadow">
مشاهده شرایط و ثبت استعلام رسمی
</a>
</div>
</div>
<!-- Interactive Mini Calculator -->
<div class="lg:col-span-6">
<div class="bg-white text-stone-800 p-6 sm:p-8 rounded-2xl shadow-2xl space-y-5">
<h3 class="font-bold text-base text-stone-900 flex items-center justify-between border-b pb-3">
<span><i class="fas fa-coins text-amber-600 ml-1.5"></i> محاسبه‌گر تخفیف تیراژ</span>
<span class="text-xs text-amber-700 bg-amber-50 px-2.5 py-1 rounded-md font-semibold">محاسبه آنلاین</span>
</h3>
<div>
<label class="block text-xs font-bold text-stone-700 mb-1.5">انتخاب محصول عمده:</label>
<select id="calc-product" class="w-full bg-stone-50 border border-stone-300 rounded-xl p-2.5 text-sm focus:ring-2 focus:ring-amber-500 focus:outline-none">
<?php foreach ($featuredProducts as $p): ?>
<?php if ((int)$p['is_wholesale_available'] === 1): ?>
<option value="<?= $p['id'] ?>" data-price="<?= $p['price'] ?>" data-min="<?= $p['wholesale_min_qty'] ?>" data-wprice="<?= $p['wholesale_price'] ?>" data-t2qty="<?= $p['wholesale_tier2_qty'] ?>" data-t2price="<?= $p['wholesale_tier2_price'] ?>" data-unit="<?= $p['unit'] ?>">
<?= htmlspecialchars($p['name']) ?>
</option>
<?php endif; ?>
<?php endforeach; ?>
</select>
</div>
<div>
<div class="flex justify-between items-center mb-1.5">
<label class="text-xs font-bold text-stone-700">تعداد / مقدار درخواستی:</label>
<span class="text-xs text-stone-500" id="calc-unit-label">واحد: عدد</span>
</div>
<div class="flex items-center gap-3">
<input type="number" id="calc-qty" value="100" min="1" class="flex-1 bg-stone-50 border border-stone-300 rounded-xl p-2.5 text-sm font-bold focus:ring-2 focus:ring-amber-500 focus:outline-none">
</div>
</div>
<!-- Result Box -->
<div class="bg-amber-50 rounded-xl p-4 border border-amber-200 space-y-2">
<div class="flex justify-between text-xs text-stone-600">
<span>نرخ هر واحد در این تیراژ:</span>
<span class="font-bold text-stone-900" id="calc-unit-price">-</span>
</div>
<div class="flex justify-between text-xs text-emerald-700 font-bold">
<span>میزان سود و تخفیف شما:</span>
<span id="calc-savings">-</span>
</div>
<div class="flex justify-between text-sm font-extrabold text-stone-900 pt-2 border-t border-amber-200">
<span>مبلغ کل فاکتور:</span>
<span class="text-amber-800 text-base" id="calc-total-price">-</span>
</div>
</div>
<button id="calc-add-btn" class="w-full py-3 rounded-xl bg-amber-500 hover:bg-amber-600 text-stone-950 font-extrabold text-sm transition flex items-center justify-center gap-2 shadow-sm">
<i class="fas fa-cart-plus"></i>
<span>افزودن این سفارش به سبد خرید</span>
</button>
</div>
</div>
</div>
</div>
</section>
<!-- Latest Blog Articles -->
<section class="py-14 max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex flex-col sm:flex-row items-start sm:items-end justify-between mb-10 gap-4">
<div>
<span class="text-xs font-bold text-amber-600 uppercase tracking-widest block mb-1">دانشنامه و آموزش</span>
<h2 class="text-2xl sm:text-3xl font-extrabold text-stone-900">مقالات تخصصی پرورش بلدرچین</h2>
</div>
<a href="/blog" class="inline-flex items-center gap-2 text-sm font-bold text-amber-700 hover:text-amber-800 bg-white px-4 py-2 rounded-xl border border-stone-200 shadow-sm">
<span>مشاهده تمام مقالات</span>
<i class="fas fa-angle-left"></i>
</a>
</div>
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
<?php foreach ($latestArticles as $art): ?>
<div class="bg-white rounded-2xl border border-stone-200 overflow-hidden shadow-sm hover:shadow-md transition flex flex-col justify-between group">
<a href="/blog/<?= $art['slug'] ?>" class="block h-48 bg-stone-800 overflow-hidden">
<img src="<?= $art['image'] ?>" alt="<?= htmlspecialchars($art['title']) ?>" class="w-full h-full object-cover group-hover:scale-105 transition duration-300">
</a>
<div class="p-6 flex-1 flex flex-col justify-between">
<div>
<div class="flex items-center gap-2 text-xs text-stone-400 mb-2">
<i class="far fa-calendar-alt"></i>
<span><?= \Bildirchin\Helpers::getJalaliDate($art['created_at']) ?></span>
</div>
<a href="/blog/<?= $art['slug'] ?>" class="font-extrabold text-base text-stone-900 group-hover:text-amber-600 transition mb-3 block leading-snug">
<?= htmlspecialchars($art['title']) ?>
</a>
<p class="text-xs text-stone-500 line-clamp-3 leading-relaxed mb-4">
<?= htmlspecialchars($art['summary']) ?>
</p>
</div>
<a href="/blog/<?= $art['slug'] ?>" class="text-xs font-bold text-amber-600 hover:text-amber-700 flex items-center gap-1.5">
<span>مطالعه کامل مقاله</span>
<i class="fas fa-arrow-left"></i>
</a>
</div>
</div>
<?php endforeach; ?>
</div>
</section>
<script>
// Dynamic Calculator Script
function runCalculator() {
const sel = document.getElementById('calc-product');
const opt = sel.options[sel.selectedIndex];
const qty = parseInt(document.getElementById('calc-qty').value) || 1;
const regularPrice = parseFloat(opt.dataset.price);
const minQty = parseInt(opt.dataset.min);
const wPrice = parseFloat(opt.dataset.wprice);
const t2Qty = parseInt(opt.dataset.t2qty);
const t2Price = parseFloat(opt.dataset.t2price);
const unit = opt.dataset.unit;
document.getElementById('calc-unit-label').innerText = 'واحد: ' + unit;
let unitPrice = regularPrice;
if (t2Qty > 0 && qty >= t2Qty && t2Price > 0) {
unitPrice = t2Price;
} else if (minQty > 0 && qty >= minQty && wPrice > 0) {
unitPrice = wPrice;
}
const totalPrice = unitPrice * qty;
const savings = Math.max(0, (regularPrice - unitPrice) * qty);
const formatFa = (num) => new Intl.NumberFormat('fa-IR').format(num) + ' تومان';
document.getElementById('calc-unit-price').innerText = formatFa(unitPrice);
document.getElementById('calc-total-price').innerText = formatFa(totalPrice);
document.getElementById('calc-savings').innerText = savings > 0 ? formatFa(savings) + ' (تخفیف ویژه)' : 'نرخ خرده‌فروشی عادی';
}
document.getElementById('calc-product').addEventListener('change', runCalculator);
document.getElementById('calc-qty').addEventListener('input', runCalculator);
runCalculator();
document.getElementById('calc-add-btn').addEventListener('click', function() {
const prodId = document.getElementById('calc-product').value;
const qty = parseInt(document.getElementById('calc-qty').value) || 1;
addToCart(prodId, qty);
});
</script>
<?php
require __DIR__ . '/../layout/footer.php';
?>
+65
View File
@@ -0,0 +1,65 @@
<?php
$pageTitle = 'ثبت موفق سفارش';
require __DIR__ . '/../layout/header.php';
require __DIR__ . '/../layout/navbar.php';
?>
<div class="max-w-3xl mx-auto px-4 py-16">
<div class="bg-white rounded-3xl border border-stone-200 p-8 sm:p-12 shadow-sm text-center space-y-6">
<div class="w-20 h-20 rounded-full bg-emerald-100 text-emerald-600 flex items-center justify-center text-4xl mx-auto shadow-sm animate-bounce">
<i class="fas fa-check"></i>
</div>
<div>
<span class="text-xs font-bold text-emerald-600 bg-emerald-50 px-3 py-1 rounded-full uppercase">سفارش شما با موفقیت ثبت شد</span>
<h1 class="text-2xl sm:text-3xl font-extrabold text-stone-900 mt-2">از حسن اعتماد و خرید شما سپاسگزاریم</h1>
<p class="text-xs sm:text-sm text-stone-500 mt-1">کارشناسان مزرعه جهت هماهنگی و آماده‌سازی ارسال با شما تماس خواهند گرفت.</p>
</div>
<!-- Tracking Code Card -->
<div class="bg-stone-50 rounded-2xl p-6 border border-stone-200 max-w-md mx-auto space-y-3">
<span class="text-xs text-stone-500 font-medium block">کد رهگیری اختصاصی سفارش شما:</span>
<span class="text-2xl font-black text-amber-800 tracking-wider font-mono select-all block"><?= htmlspecialchars($order['order_code']) ?></span>
<p class="text-[11px] text-stone-400">این کد را جهت پیگیری وضعیت سفارش ذخیره فرمایید.</p>
</div>
<!-- Bank Card Payment Info -->
<?php if ($order['payment_method'] === 'کارت به کارت / فیش واریزی'): ?>
<div class="bg-amber-50/80 rounded-2xl p-6 border border-amber-200 text-right space-y-3">
<h4 class="font-bold text-sm text-amber-900 flex items-center gap-2">
<i class="fas fa-credit-card text-amber-600"></i> اطلاعات حساب جهت واریز مبلغ فاکتور:
</h4>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-3 text-xs text-stone-700">
<div>
<span class="text-stone-500">شماره کارت:</span>
<span class="font-bold block text-sm tracking-wider font-mono mt-0.5 text-stone-900"><?= $settings['card_number'] ?? '۶۰۳۷-۹۹۱۸-۱۲۳۴-۵۶۷۸' ?></span>
</div>
<div>
<span class="text-stone-500">به نام:</span>
<span class="font-bold block mt-0.5 text-stone-900"><?= $settings['card_holder'] ?? 'مزرعه پرورشی بلدرچین زرین' ?></span>
</div>
<div>
<span class="text-stone-500">مبلغ قابل واریز:</span>
<span class="font-black text-amber-900 block mt-0.5 text-sm"><?= \Bildirchin\Helpers::formatPrice($order['final_amount']) ?></span>
</div>
</div>
<p class="text-[11px] text-amber-700 pt-2 border-t border-amber-200">
پس از واریز، تصویر فیش را به همراه کد رهگیری به شماره واتساپ <span class="font-bold tracking-wider"><?= \Bildirchin\Helpers::toPersianDigits(\Bildirchin\Config::WHATSAPP) ?></span> ارسال فرمایید.
</p>
</div>
<?php endif; ?>
<div class="flex flex-wrap items-center justify-center gap-4 pt-4">
<a href="/track?code=<?= urlencode($order['order_code']) ?>" class="px-6 py-2.5 rounded-xl bg-amber-500 text-stone-950 text-xs font-bold hover:bg-amber-600 transition">
<i class="fas fa-magnifying-glass ml-1"></i> پیگیری این سفارش
</a>
<a href="/products" class="px-6 py-2.5 rounded-xl bg-stone-100 text-stone-700 text-xs font-bold hover:bg-stone-200 transition">
بازگشت به فروشگاه
</a>
</div>
</div>
</div>
<?php
require __DIR__ . '/../layout/footer.php';
?>
+128
View File
@@ -0,0 +1,128 @@
<?php
$pageTitle = $product['name'];
require __DIR__ . '/../layout/header.php';
require __DIR__ . '/../layout/navbar.php';
?>
<div class="bg-stone-100/50 py-4 border-b border-stone-200 text-xs text-stone-500">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex items-center gap-2">
<a href="/" class="hover:text-amber-600">خانه</a>
<span>/</span>
<a href="/products" class="hover:text-amber-600">محصولات</a>
<span>/</span>
<a href="/products?cat=<?= $product['category_id'] ?>" class="hover:text-amber-600"><?= htmlspecialchars($product['category_name']) ?></a>
<span>/</span>
<span class="text-stone-800 font-bold"><?= htmlspecialchars($product['name']) ?></span>
</div>
</div>
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-10">
<div class="bg-white rounded-3xl border border-stone-200 overflow-hidden shadow-sm p-6 sm:p-10 mb-12">
<div class="grid grid-cols-1 lg:grid-cols-12 gap-10">
<!-- Product Image -->
<div class="lg:col-span-5 flex flex-col items-center justify-center bg-stone-50 rounded-2xl p-6 border border-stone-100">
<img src="<?= $product['image'] ?>" alt="<?= htmlspecialchars($product['name']) ?>" class="max-h-80 w-auto object-contain">
<div class="mt-4 flex items-center gap-2 text-xs text-emerald-700 bg-emerald-50 px-3 py-1.5 rounded-full font-bold">
<i class="fas fa-check-circle"></i>
<span>موجودی در انبار مزرعه: <?= \Bildirchin\Helpers::toPersianDigits($product['stock']) ?> <?= $product['unit'] ?></span>
</div>
</div>
<!-- Product Specs & Purchase -->
<div class="lg:col-span-7 space-y-6">
<div>
<span class="text-xs font-bold text-amber-600 uppercase tracking-wider block mb-1"><?= htmlspecialchars($product['category_name']) ?></span>
<h1 class="text-2xl sm:text-3xl font-extrabold text-stone-900"><?= htmlspecialchars($product['name']) ?></h1>
<p class="text-sm text-stone-500 mt-2 leading-relaxed"><?= htmlspecialchars($product['short_desc']) ?></p>
</div>
<!-- Price & Wholesale Tiers Table -->
<div class="bg-stone-50 rounded-2xl p-5 border border-stone-200 space-y-4">
<div class="flex items-baseline justify-between">
<span class="text-sm text-stone-600 font-medium">قیمت پایه (تکی):</span>
<span class="text-2xl font-black text-stone-900"><?= \Bildirchin\Helpers::formatPrice($product['price']) ?> <span class="text-xs font-normal text-stone-500">/ هر <?= $product['unit'] ?></span></span>
</div>
<?php if ((int)$product['is_wholesale_available'] === 1): ?>
<div class="pt-3 border-t border-stone-200">
<span class="text-xs font-extrabold text-amber-800 flex items-center gap-1.5 mb-2.5">
<i class="fas fa-tags text-amber-600"></i> جدول تخفیف پلکانی عمده‌فروشی:
</span>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-3 text-xs">
<?php if ($product['wholesale_min_qty'] > 0 && $product['wholesale_price'] > 0): ?>
<div class="bg-white p-3 rounded-xl border border-amber-200 flex justify-between items-center shadow-sm">
<div>
<span class="font-bold text-stone-800 block">پله اول (از <?= \Bildirchin\Helpers::toPersianDigits($product['wholesale_min_qty']) ?> <?= $product['unit'] ?>)</span>
<span class="text-[11px] text-emerald-600">سود شما: <?= \Bildirchin\Helpers::formatPrice($product['price'] - $product['wholesale_price']) ?> در هر واحد</span>
</div>
<span class="font-black text-amber-800 text-sm"><?= \Bildirchin\Helpers::formatPrice($product['wholesale_price']) ?></span>
</div>
<?php endif; ?>
<?php if ($product['wholesale_tier2_qty'] > 0 && $product['wholesale_tier2_price'] > 0): ?>
<div class="bg-white p-3 rounded-xl border border-amber-300 flex justify-between items-center shadow-sm bg-amber-50/40">
<div>
<span class="font-bold text-stone-800 block">پله دوم (از <?= \Bildirchin\Helpers::toPersianDigits($product['wholesale_tier2_qty']) ?> <?= $product['unit'] ?>)</span>
<span class="text-[11px] text-emerald-600">سود شما: <?= \Bildirchin\Helpers::formatPrice($product['price'] - $product['wholesale_tier2_price']) ?> در هر واحد</span>
</div>
<span class="font-black text-amber-900 text-sm"><?= \Bildirchin\Helpers::formatPrice($product['wholesale_tier2_price']) ?></span>
</div>
<?php endif; ?>
</div>
</div>
<?php endif; ?>
</div>
<!-- Add to Cart Form -->
<form action="/cart/add" method="POST" class="space-y-4">
<input type="hidden" name="product_id" value="<?= $product['id'] ?>">
<div class="flex flex-col sm:flex-row items-center gap-4">
<div class="flex items-center border border-stone-300 rounded-xl bg-white p-1 w-full sm:w-auto">
<button type="button" onclick="changeQty(-1)" class="w-10 h-10 rounded-lg bg-stone-100 hover:bg-stone-200 text-stone-700 flex items-center justify-center font-bold text-lg">-</button>
<input type="number" name="quantity" id="prod-quantity" value="1" min="1" max="<?= $product['stock'] ?>" class="w-20 text-center font-bold text-base focus:outline-none">
<button type="button" onclick="changeQty(1)" class="w-10 h-10 rounded-lg bg-stone-100 hover:bg-stone-200 text-stone-700 flex items-center justify-center font-bold text-lg">+</button>
</div>
<button type="submit" class="flex-1 w-full py-3.5 px-6 rounded-xl bg-amber-500 hover:bg-amber-600 text-stone-950 font-extrabold text-sm transition flex items-center justify-center gap-2 shadow-md">
<i class="fas fa-shopping-basket"></i>
<span>افزودن به سبد خرید</span>
</button>
</div>
</form>
<!-- Features list -->
<div class="grid grid-cols-2 gap-3 pt-4 border-t border-stone-100 text-xs text-stone-600">
<div class="flex items-center gap-2"><i class="fas fa-truck text-amber-500"></i> ارسال فوری از سالن تولید</div>
<div class="flex items-center gap-2"><i class="fas fa-shield-alt text-emerald-500"></i> ضمانت کیفیت و سلامت کالا</div>
<div class="flex items-center gap-2"><i class="fas fa-receipt text-sky-500"></i> صدور فاکتور معتبر و رسمی</div>
<div class="flex items-center gap-2"><i class="fas fa-phone-volume text-rose-500"></i> مشاوره تخصصی قبل از خرید</div>
</div>
</div>
</div>
<!-- Full Description & Tabs -->
<div class="mt-12 pt-8 border-t border-stone-200">
<h3 class="text-xl font-bold text-stone-900 mb-4 flex items-center gap-2">
<i class="fas fa-circle-info text-amber-600"></i> توضیحات و مشخصات فنی محصول
</h3>
<div class="prose max-w-none text-sm text-stone-600 leading-loose space-y-4">
<?= nl2br(htmlspecialchars($product['full_desc'] ?: $product['short_desc'])) ?>
</div>
</div>
</div>
</div>
<script>
function changeQty(delta) {
const input = document.getElementById('prod-quantity');
let val = parseInt(input.value) || 1;
val += delta;
if (val < 1) val = 1;
input.value = val;
}
</script>
<?php
require __DIR__ . '/../layout/footer.php';
?>
+105
View File
@@ -0,0 +1,105 @@
<?php
$pageTitle = $selectedCategory ? $selectedCategory['name'] : 'کاتالوگ و فروشگاه محصولات';
require __DIR__ . '/../layout/header.php';
require __DIR__ . '/../layout/navbar.php';
?>
<div class="bg-stone-100/60 py-8 border-b border-stone-200">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex flex-col md:flex-row md:items-center justify-between gap-4">
<div>
<h1 class="text-2xl sm:text-3xl font-extrabold text-stone-900">
<?= $selectedCategory ? htmlspecialchars($selectedCategory['name']) : 'کلیه محصولات و ملزومات پرورش بلدرچین' ?>
</h1>
<p class="text-xs sm:text-sm text-stone-500 mt-1">
<?= $selectedCategory ? htmlspecialchars($selectedCategory['description']) : 'تولید و توزیع مستقیم گوشت، تخم، دان و تجهیزات استاندارد' ?>
</p>
</div>
<!-- Category Pills -->
<div class="flex flex-wrap gap-2">
<a href="/products" class="px-3.5 py-2 rounded-xl text-xs font-bold transition <?= !$categoryId ? 'bg-amber-600 text-white shadow-sm' : 'bg-white text-stone-700 hover:bg-stone-200 border border-stone-200' ?>">
همه دسته‌ها
</a>
<?php foreach ($categories as $cat): ?>
<a href="/products?cat=<?= $cat['id'] ?>" class="px-3.5 py-2 rounded-xl text-xs font-bold transition <?= ($categoryId == $cat['id']) ? 'bg-amber-600 text-white shadow-sm' : 'bg-white text-stone-700 hover:bg-stone-200 border border-stone-200' ?>">
<?= htmlspecialchars($cat['name']) ?>
</a>
<?php endforeach; ?>
</div>
</div>
</div>
</div>
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-10">
<?php if (empty($products)): ?>
<div class="text-center py-20 bg-white rounded-3xl border border-stone-200 p-8">
<i class="fas fa-box-open text-5xl text-stone-300 mb-4 block"></i>
<h3 class="text-lg font-bold text-stone-700">هیچ محصولی در این بخش یافت نشد.</h3>
<p class="text-xs text-stone-400 mt-1">می‌توانید سایر دسته‌بندی‌ها را مشاهده نمایید.</p>
<a href="/products" class="inline-block mt-5 px-6 py-2.5 rounded-xl bg-amber-500 text-stone-900 text-xs font-bold hover:bg-amber-600 transition">
مشاهده همه محصولات
</a>
</div>
<?php else: ?>
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6">
<?php foreach ($products as $prod): ?>
<div class="bg-white rounded-2xl border border-stone-200 overflow-hidden shadow-sm hover:shadow-lg transition flex flex-col justify-between group">
<div class="relative">
<a href="/product/<?= $prod['slug'] ?>" class="block h-52 bg-stone-50 overflow-hidden p-4 flex items-center justify-center">
<img src="<?= $prod['image'] ?>" alt="<?= htmlspecialchars($prod['name']) ?>" class="max-h-full max-w-full object-contain group-hover:scale-105 transition duration-300">
</a>
<?php if ((int)$prod['is_wholesale_available'] === 1): ?>
<span class="absolute top-3 right-3 bg-amber-500 text-stone-950 text-[11px] font-extrabold px-2.5 py-1 rounded-lg shadow-sm">
<i class="fas fa-boxes-stacked ml-1"></i> تخفیف عمده
</span>
<?php endif; ?>
</div>
<div class="p-5 flex-1 flex flex-col justify-between">
<div>
<span class="text-[11px] font-semibold text-amber-700 block mb-1"><?= htmlspecialchars($prod['category_name']) ?></span>
<a href="/product/<?= $prod['slug'] ?>" class="font-bold text-stone-900 group-hover:text-amber-600 transition text-base block mb-2 leading-snug">
<?= htmlspecialchars($prod['name']) ?>
</a>
<p class="text-xs text-stone-500 line-clamp-2 mb-4 leading-relaxed">
<?= htmlspecialchars($prod['short_desc']) ?>
</p>
</div>
<div>
<!-- Price box -->
<div class="bg-stone-50 p-3 rounded-xl mb-4 border border-stone-100">
<div class="flex items-center justify-between">
<span class="text-xs text-stone-500">قیمت مصرف‌کننده:</span>
<span class="text-base font-black text-stone-900"><?= \Bildirchin\Helpers::formatPrice($prod['price']) ?></span>
</div>
<?php if ((int)$prod['is_wholesale_available'] === 1 && $prod['wholesale_price'] > 0): ?>
<div class="flex items-center justify-between mt-1 pt-1 border-t border-stone-200/60 text-xs">
<span class="text-amber-700 font-medium">عمده (از <?= \Bildirchin\Helpers::toPersianDigits($prod['wholesale_min_qty']) ?> <?= $prod['unit'] ?>):</span>
<span class="font-bold text-emerald-700"><?= \Bildirchin\Helpers::formatPrice($prod['wholesale_price']) ?></span>
</div>
<?php endif; ?>
</div>
<!-- Action buttons -->
<div class="flex items-center gap-2">
<a href="/product/<?= $prod['slug'] ?>" class="flex-1 text-center py-2.5 px-3 rounded-xl bg-stone-100 hover:bg-stone-200 text-stone-800 text-xs font-bold transition">
جزییات و خرید
</a>
<button onclick="addToCart(<?= $prod['id'] ?>, 1)" class="w-10 h-10 rounded-xl bg-amber-500 hover:bg-amber-600 text-stone-950 flex items-center justify-center transition shadow-sm" title="افزودن به سبد خرید">
<i class="fas fa-cart-plus"></i>
</button>
</div>
</div>
</div>
</div>
<?php endforeach; ?>
</div>
<?php endif; ?>
</div>
<?php
require __DIR__ . '/../layout/footer.php';
?>
+110
View File
@@ -0,0 +1,110 @@
<?php
$pageTitle = 'پیگیری آنلاین سفارش';
require __DIR__ . '/../layout/header.php';
require __DIR__ . '/../layout/navbar.php';
?>
<div class="max-w-4xl mx-auto px-4 sm:px-6 py-12">
<div class="text-center max-w-xl mx-auto mb-8">
<div class="w-14 h-14 rounded-2xl bg-amber-50 text-amber-600 flex items-center justify-center text-2xl mx-auto mb-3 shadow-sm">
<i class="fas fa-magnifying-glass-location"></i>
</div>
<h1 class="text-2xl sm:text-3xl font-extrabold text-stone-900">پیگیری وضعیت سفارش</h1>
<p class="text-xs sm:text-sm text-stone-500 mt-1">کد رهگیری دریافت شده پس از ثبت سفارش را در کادر زیر وارد نمایید.</p>
</div>
<!-- Search Box -->
<div class="bg-white rounded-2xl border border-stone-200 p-6 sm:p-8 shadow-sm mb-8">
<form action="/track" method="POST" class="flex flex-col sm:flex-row gap-3">
<input type="text" name="order_code" value="<?= htmlspecialchars($_POST['order_code'] ?? ($_GET['code'] ?? '')) ?>" required placeholder="مثال: BLD-A1B2C3" class="flex-1 bg-stone-50 border border-stone-300 rounded-xl px-4 py-3 text-sm font-mono tracking-wider focus:ring-2 focus:ring-amber-500 focus:outline-none uppercase">
<button type="submit" class="py-3 px-8 rounded-xl bg-amber-500 hover:bg-amber-600 text-stone-950 font-extrabold text-sm transition shadow-sm">
استعلام وضعیت
</button>
</form>
</div>
<?php if ($searched): ?>
<?php if ($order): ?>
<div class="bg-white rounded-3xl border border-stone-200 p-6 sm:p-8 shadow-sm space-y-6">
<!-- Status Timeline -->
<?php
$statusMap = [
'pending' => ['label' => 'در انتظار بررسی و تایید مالی', 'step' => 1, 'color' => 'amber'],
'confirmed' => ['label' => 'سفارش تایید شد', 'step' => 2, 'color' => 'sky'],
'packing' => ['label' => 'در حال بسته‌بندی و آماده‌سازی در مزرعه', 'step' => 3, 'color' => 'indigo'],
'shipped' => ['label' => 'تحویل باربری / ارسال شد', 'step' => 4, 'color' => 'emerald'],
'delivered' => ['label' => 'تحویل داده شده', 'step' => 5, 'color' => 'emerald'],
'cancelled' => ['label' => 'سفارش لغو شد', 'step' => 0, 'color' => 'rose']
];
$currentStatus = $statusMap[$order['status']] ?? ['label' => $order['status'], 'step' => 1, 'color' => 'amber'];
?>
<div class="flex flex-col sm:flex-row sm:items-center justify-between pb-4 border-b gap-2">
<div>
<span class="text-xs text-stone-400">شماره سفارش:</span>
<span class="text-lg font-black text-stone-900 block"><?= htmlspecialchars($order['order_code']) ?></span>
</div>
<div class="text-left">
<span class="text-xs text-stone-400 block">وضعیت فعلی:</span>
<span class="inline-block mt-0.5 px-3 py-1 rounded-full text-xs font-extrabold bg-<?= $currentStatus['color'] ?>-100 text-<?= $currentStatus['color'] ?>-800">
<?= $currentStatus['label'] ?>
</span>
</div>
</div>
<!-- Order Details Grid -->
<div class="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 gap-4 text-xs bg-stone-50 p-4 rounded-2xl border border-stone-100">
<div>
<span class="text-stone-400 block">نام تحویل‌گیرنده:</span>
<span class="font-bold text-stone-800 mt-0.5 block"><?= htmlspecialchars($order['customer_name']) ?></span>
</div>
<div>
<span class="text-stone-400 block">شماره تماس:</span>
<span class="font-bold text-stone-800 mt-0.5 block"><?= htmlspecialchars($order['customer_phone']) ?></span>
</div>
<div>
<span class="text-stone-400 block">تاریخ ثبت:</span>
<span class="font-bold text-stone-800 mt-0.5 block"><?= \Bildirchin\Helpers::getJalaliDate($order['created_at']) ?></span>
</div>
<div>
<span class="text-stone-400 block">روش ارسال:</span>
<span class="font-bold text-stone-800 mt-0.5 block"><?= htmlspecialchars($order['shipping_method']) ?></span>
</div>
<div>
<span class="text-stone-400 block">نحوه تسویه:</span>
<span class="font-bold text-stone-800 mt-0.5 block"><?= htmlspecialchars($order['payment_method']) ?></span>
</div>
<div>
<span class="text-stone-400 block">مبلغ کل فاکتور:</span>
<span class="font-black text-amber-900 mt-0.5 block text-sm"><?= \Bildirchin\Helpers::formatPrice($order['final_amount']) ?></span>
</div>
</div>
<!-- Order Items -->
<div>
<h4 class="font-bold text-xs text-stone-700 mb-2">اقلام سفارش داده شده:</h4>
<div class="border border-stone-200 rounded-xl overflow-hidden divide-y text-xs">
<?php foreach ($order['items'] as $item): ?>
<div class="p-3 flex justify-between items-center">
<div>
<span class="font-bold text-stone-800"><?= htmlspecialchars($item['product_name']) ?></span>
<span class="text-stone-400 mr-2">(تعداد: <?= \Bildirchin\Helpers::toPersianDigits($item['quantity']) ?>)</span>
</div>
<span class="font-bold text-stone-900"><?= \Bildirchin\Helpers::formatPrice($item['total_price']) ?></span>
</div>
<?php endforeach; ?>
</div>
</div>
</div>
<?php else: ?>
<div class="bg-rose-50 border border-rose-200 text-rose-800 p-6 rounded-2xl text-center text-sm">
<i class="fas fa-circle-xmark text-2xl text-rose-500 mb-2 block"></i>
سفارشی با این کد رهگیری در سامانه مزرعه ثبت نشده است. لطفاً از صحت کد وارد شده اطمینان حاصل فرمایید.
</div>
<?php endif; ?>
<?php endif; ?>
</div>
<?php
require __DIR__ . '/../layout/footer.php';
?>
+138
View File
@@ -0,0 +1,138 @@
<?php
$pageTitle = 'پرتال و شرایط فروش عمده بلدرچین، تخم و خوراک';
require __DIR__ . '/../layout/header.php';
require __DIR__ . '/../layout/navbar.php';
?>
<!-- Wholesale Hero -->
<div class="bg-gradient-to-br from-stone-900 via-amber-950 to-stone-900 text-white py-16">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-center space-y-4">
<div class="inline-flex items-center gap-2 px-3.5 py-1.5 rounded-full bg-amber-500/20 text-amber-300 border border-amber-500/30 text-xs font-bold">
<i class="fas fa-handshake"></i>
<span>تامین پایدار برای رستوران‌ها، هایپرمارکت‌ها، مراکز جوجه‌کشی و پرورشی</span>
</div>
<h1 class="text-3xl sm:text-5xl font-black">بخش فروش عمده، تناژ و تامین قراردادی</h1>
<p class="text-stone-300 text-base max-w-3xl mx-auto leading-relaxed">
مزرعه بلدرچین زرین با ظرفیت تولید صنعتی، آماده عقد قراردادهای بلندمدت و ارسال منظم بار به سراسر ایران با نازل‌ترین نرخ درب مزرعه و مجوزهای رسمی دامپزشکی می‌باشد.
</p>
</div>
</div>
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12">
<!-- Wholesale Tier Table -->
<div class="mb-14">
<div class="text-center max-w-2xl mx-auto mb-8">
<span class="text-xs font-bold text-amber-600 uppercase tracking-widest block mb-1">جدول قیمت‌های همکاری</span>
<h2 class="text-2xl font-extrabold text-stone-900">لیست نرخ عمده و حداقل سفارش محصولات</h2>
</div>
<div class="bg-white rounded-2xl border border-stone-200 overflow-hidden shadow-sm">
<div class="overflow-x-auto">
<table class="w-full text-right text-xs sm:text-sm">
<thead class="bg-stone-100 text-stone-700 border-b border-stone-200">
<tr>
<th class="py-3.5 px-4 font-bold">نام محصول</th>
<th class="py-3.5 px-4 font-bold">قیمت تک‌فروشی</th>
<th class="py-3.5 px-4 font-bold">پله اول عمده</th>
<th class="py-3.5 px-4 font-bold">پله دوم (تیراژ بالا)</th>
<th class="py-3.5 px-4 font-bold text-center">سفارش آنلاین</th>
</tr>
</thead>
<tbody class="divide-y divide-stone-100">
<?php foreach ($wholesaleProducts as $p): ?>
<tr class="hover:bg-amber-50/40 transition">
<td class="py-3.5 px-4 font-bold text-stone-900 flex items-center gap-3">
<img src="<?= $p['image'] ?>" class="w-8 h-8 object-contain">
<span><?= htmlspecialchars($p['name']) ?></span>
</td>
<td class="py-3.5 px-4 text-stone-500"><?= \Bildirchin\Helpers::formatPrice($p['price']) ?> / <?= $p['unit'] ?></td>
<td class="py-3.5 px-4 font-bold text-amber-800">
<?= \Bildirchin\Helpers::formatPrice($p['wholesale_price']) ?>
<span class="block text-[11px] text-stone-400 font-normal">از <?= \Bildirchin\Helpers::toPersianDigits($p['wholesale_min_qty']) ?> <?= $p['unit'] ?></span>
</td>
<td class="py-3.5 px-4 font-black text-emerald-800">
<?= \Bildirchin\Helpers::formatPrice($p['wholesale_tier2_price']) ?>
<span class="block text-[11px] text-stone-400 font-normal">از <?= \Bildirchin\Helpers::toPersianDigits($p['wholesale_tier2_qty']) ?> <?= $p['unit'] ?></span>
</td>
<td class="py-3.5 px-4 text-center">
<button onclick="addToCart(<?= $p['id'] ?>, <?= $p['wholesale_min_qty'] ?>)" class="px-3 py-1.5 rounded-lg bg-amber-500 hover:bg-amber-600 text-stone-950 text-xs font-bold transition shadow-sm">
<i class="fas fa-cart-plus ml-1"></i> خرید <?= \Bildirchin\Helpers::toPersianDigits($p['wholesale_min_qty']) ?> <?= $p['unit'] ?>
</button>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</div>
</div>
</div>
<!-- Wholesale Inquiry Form -->
<div id="quote-form" class="bg-stone-900 rounded-3xl text-white p-8 sm:p-12 shadow-2xl border border-stone-800">
<div class="grid grid-cols-1 lg:grid-cols-12 gap-10">
<div class="lg:col-span-5 space-y-5">
<span class="text-xs font-bold text-amber-400 uppercase tracking-widest block">فرم درخواست همکاری و استعلام</span>
<h3 class="text-2xl sm:text-3xl font-extrabold leading-snug">ثبت درخواست پیش‌فاکتور و خرید تناژ</h3>
<p class="text-stone-400 text-sm leading-relaxed">
چنانچه حجم سفارش شما فراتر از مقادیر جدول بالاست یا نیاز به ارسال دوره‌ای (هفتگی/ماهانه) دارید، اطلاعات زیر را ثبت نمایید تا مسئول بازرگانی مزرعه در سریع‌ترین زمان ممکن با شما تماس بگیرد.
</p>
<div class="pt-4 space-y-3 text-sm text-stone-300">
<div class="flex items-center gap-3"><i class="fas fa-phone-alt text-amber-400"></i> تماس مستقیم بازرگانی: <a href="tel:<?= \Bildirchin\Config::PHONE ?>" class="text-white font-bold tracking-wider"><?= \Bildirchin\Helpers::toPersianDigits(\Bildirchin\Config::PHONE) ?></a></div>
<div class="flex items-center gap-3"><i class="fab fa-whatsapp text-emerald-400 text-lg"></i> پشتیبانی واتساپ: <a href="https://wa.me/98<?= substr(\Bildirchin\Config::WHATSAPP, 1) ?>" class="text-emerald-300 font-bold"><?= \Bildirchin\Helpers::toPersianDigits(\Bildirchin\Config::WHATSAPP) ?></a></div>
</div>
</div>
<!-- Form -->
<div class="lg:col-span-7 bg-stone-950/70 p-6 sm:p-8 rounded-2xl border border-stone-800">
<form action="/wholesale/inquiry" method="POST" class="space-y-4">
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div>
<label class="block text-xs font-bold text-stone-300 mb-1">نام و نام‌خانوادگی *</label>
<input type="text" name="customer_name" required class="w-full bg-stone-900 border border-stone-700 rounded-xl p-3 text-sm text-white focus:outline-none focus:border-amber-500" placeholder="مثال: علی احمدی">
</div>
<div>
<label class="block text-xs font-bold text-stone-300 mb-1">شماره همراه تماس *</label>
<input type="tel" name="phone" required class="w-full bg-stone-900 border border-stone-700 rounded-xl p-3 text-sm text-white focus:outline-none focus:border-amber-500" placeholder="۰۹۱۲۳۴۵۶۷۸۹">
</div>
</div>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div>
<label class="block text-xs font-bold text-stone-300 mb-1">نام فروشگاه / رستوران / شرکت</label>
<input type="text" name="company_name" class="w-full bg-stone-900 border border-stone-700 rounded-xl p-3 text-sm text-white focus:outline-none focus:border-amber-500" placeholder="اختیاری">
</div>
<div>
<label class="block text-xs font-bold text-stone-300 mb-1">شهر و استان مقصد</label>
<input type="text" name="city" class="w-full bg-stone-900 border border-stone-700 rounded-xl p-3 text-sm text-white focus:outline-none focus:border-amber-500" placeholder="مثال: اصفهان">
</div>
</div>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-4">
<div>
<label class="block text-xs font-bold text-stone-300 mb-1">محصول مورد تقاضا *</label>
<input type="text" name="product_requested" required class="w-full bg-stone-900 border border-stone-700 rounded-xl p-3 text-sm text-white focus:outline-none focus:border-amber-500" placeholder="مثال: ۱۰ هزار تخم نطفه‌دار / ۱ تن گوشت">
</div>
<div>
<label class="block text-xs font-bold text-stone-300 mb-1">حجم یا تیراژ تخمینی</label>
<input type="text" name="estimated_qty" class="w-full bg-stone-900 border border-stone-700 rounded-xl p-3 text-sm text-white focus:outline-none focus:border-amber-500" placeholder="مثال: خرید هفتگی ۵۰۰ کیلوگرم">
</div>
</div>
<div>
<label class="block text-xs font-bold text-stone-300 mb-1">توضیحات و نیازمندی‌های خاص</label>
<textarea name="notes" rows="3" class="w-full bg-stone-900 border border-stone-700 rounded-xl p-3 text-sm text-white focus:outline-none focus:border-amber-500" placeholder="زمان تحویل مورد نظر، نحوه بسته‌بندی و..."></textarea>
</div>
<button type="submit" class="w-full py-3.5 rounded-xl bg-amber-500 hover:bg-amber-600 text-stone-950 font-extrabold text-sm transition shadow-lg flex items-center justify-center gap-2">
<i class="fas fa-paper-plane"></i>
<span>ارسال استعلام و ثبت درخواست پیش‌فاکتور</span>
</button>
</form>
</div>
</div>
</div>
</div>
<?php
require __DIR__ . '/../layout/footer.php';
?>