File manager - Edit - /home/cipherteam/htdocs/cipherteam.in/admin3/IPOCalandar.php
Back
<?php include 'config.php'; session_start(); if (!isset($_SESSION['loggedin']) || $_SESSION['loggedin'] !== true) { header("Location: login.php"); exit; } /* Permanent Theme */ $THEME = '#8CA9FF'; /* Filters */ $allowedEvents = ['ALL','OPEN','CLOSE','ALLOTMENT','LISTING']; $allowedTypes = ['ALL','SME','MAINLINE']; $eventFilter = strtoupper($_GET['event'] ?? 'ALL'); $typeFilter = strtoupper($_GET['type'] ?? 'ALL'); if (!in_array($eventFilter, $allowedEvents, true)) $eventFilter = 'ALL'; if (!in_array($typeFilter, $allowedTypes, true)) $typeFilter = 'ALL'; /* Helpers */ function safe($v){ return htmlspecialchars((string)$v, ENT_QUOTES, 'UTF-8'); } function dmy($d){ if(!$d) return ''; $t = strtotime($d); return $t ? date('d-m-Y', $t) : ''; } function typeLabel($t){ return strtoupper((string)$t)==='S' ? 'SME' : 'MAINLINE'; } function isActive($a,$b){ return $a===$b ? 'active' : ''; } function urlWith($arr){ return basename($_SERVER['PHP_SELF']).'?'.http_build_query(array_merge($_GET,$arr)); } function allotmentRegistrar($url){ $map = [ 'bigshare' => 'Bigshare', 'mufg' => 'MUFG', 'kfintech' => 'KFintech Kosmic', 'skylinerta' => 'Skyline', 'cameo' => 'Cameo', 'purvashare' => 'Purva', 'maashitla' => 'Maashitla', 'masserv' => 'Mas Services', 'satellite' => 'Satellite Corporate', 'alankit' => 'Alankit', 'integrated' => 'Integrated Registry' ]; $url = strtolower((string)$url); foreach ($map as $key => $name) { if (strpos($url, $key) !== false) return $name; } return 'Not Found/Error'; } /* Fetch IPOs (added allotment field ONLY; nothing else changed) */ $sql = "SELECT id, c_name, TYPE, ipo_open, ipo_close, ipo_allotment, ipo_listing, allotment FROM ipo_post"; $stmt = $pdo->prepare($sql); $stmt->execute(); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); date_default_timezone_set("Asia/Kolkata"); $today = new DateTime(); $todayKey = $today->format('d-m-Y'); $tomorrowKey = (clone $today)->modify('+1 day')->format('d-m-Y'); /* Build calendar */ $calendar = []; foreach($rows as $r){ $type = typeLabel($r['TYPE'] ?? ''); if($typeFilter!=='ALL' && $type!==$typeFilter) continue; $events = [ 'OPEN' => dmy($r['ipo_open'] ?? ''), 'CLOSE' => dmy($r['ipo_close'] ?? ''), 'ALLOTMENT' => dmy($r['ipo_allotment'] ?? ''), 'LISTING' => dmy($r['ipo_listing'] ?? ''), ]; foreach($events as $label=>$date){ if(!$date) continue; if($eventFilter!=='ALL' && $label!==$eventFilter) continue; $calendar[$date][] = [ 'id' => $r['id'], 'name' => $r['c_name'], 'type' => $type, 'event' => $label, // Tooltip for ALLOTMENT only (no UI change) 'title' => ($label === 'ALLOTMENT' && !empty($r['allotment'])) ? allotmentRegistrar($r['allotment']) : $label ]; } } /* Next 30 days only */ $dates = []; for($i=0;$i<30;$i++){ $d = clone $today; $d->modify("+$i day"); $k = $d->format('d-m-Y'); if(isset($calendar[$k])) $dates[$k] = $calendar[$k]; } ?> <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>IPO Calendar</title> <meta name="viewport" content="width=device-width, initial-scale=1"> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet"> <link rel="preconnect" href="https://fonts.googleapis.com"> <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap" rel="stylesheet"> <style> :root { --primary: #4f46e5; --primary-light: #e0e7ff; --primary-dark: #3730a3; --surface: #ffffff; --surface-alt: #f8fafc; --border: #e2e8f0; --text: #1e293b; --text-muted: #64748b; --success: #059669; --success-light: #ecfdf5; --danger: #dc2626; --danger-light: #fef2f2; --warning: #d97706; --warning-light: #fffbeb; --info: #0284c7; --info-light: #f0f9ff; --teal: #0d9488; --teal-light: #f0fdfa; --radius: 12px; --radius-sm: 8px; --shadow-sm: 0 1px 2px rgba(0,0,0,0.05); --shadow: 0 1px 3px rgba(0,0,0,0.08), 0 1px 2px rgba(0,0,0,0.04); --shadow-md: 0 4px 6px -1px rgba(0,0,0,0.08), 0 2px 4px -2px rgba(0,0,0,0.04); --shadow-lg: 0 10px 15px -3px rgba(0,0,0,0.08), 0 4px 6px -4px rgba(0,0,0,0.04); } * { box-sizing: border-box; } body { font-family: 'Inter', -apple-system, BlinkMacSystemFont, sans-serif; background: #f1f5f9; color: var(--text); min-height: 100vh; margin: 0; padding: 0; } /* ── Top Bar ── */ .top-bar { background: var(--surface); border-bottom: 1px solid var(--border); padding: 16px 0; position: sticky; top: 0; z-index: 100; box-shadow: var(--shadow-sm); } .top-bar .inner { max-width: 1280px; margin: 0 auto; padding: 0 24px; display: flex; align-items: center; justify-content: space-between; } .brand { display: flex; align-items: center; gap: 10px; font-weight: 700; font-size: 20px; color: var(--primary); } .brand-icon { width: 36px; height: 36px; background: var(--primary); color: #fff; border-radius: 10px; display: grid; place-items: center; font-size: 18px; flex-shrink: 0; } .btn-back { background: var(--surface-alt); color: var(--text-muted); border: 1px solid var(--border); padding: 8px 18px; border-radius: var(--radius-sm); font-weight: 500; font-size: 13px; text-decoration: none; transition: all 0.2s; display: inline-flex; align-items: center; gap: 6px; } .btn-back:hover { background: var(--primary-light); color: var(--primary); border-color: var(--primary); } /* ── Main ── */ .main-wrap { max-width: 1280px; margin: 0 auto; padding: 24px; } /* ── Filter Card ── */ .filter-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 20px 24px; margin-bottom: 24px; box-shadow: var(--shadow); display: flex; flex-wrap: wrap; gap: 20px; align-items: flex-start; } .filter-section { display: flex; flex-direction: column; gap: 8px; } .filter-label { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-muted); } .filter-pills { display: flex; flex-wrap: wrap; gap: 6px; } .filter-pills a { padding: 7px 16px; border-radius: 20px; font-size: 12px; font-weight: 600; text-decoration: none; border: 1px solid var(--border); background: var(--surface); color: var(--text-muted); transition: all 0.2s; } .filter-pills a:hover { border-color: var(--primary); color: var(--primary); background: var(--primary-light); } .filter-pills a.active { background: var(--primary); color: #fff; border-color: var(--primary); } /* ── Stats ── */ .stats-line { font-size: 13px; color: var(--text-muted); font-weight: 500; margin-bottom: 20px; display: flex; align-items: center; gap: 8px; } .stats-line .count { background: var(--primary-light); color: var(--primary); padding: 2px 10px; border-radius: 20px; font-weight: 700; font-size: 12px; } /* ── Calendar Cards ── */ .cal-card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); overflow: hidden; height: 100%; box-shadow: var(--shadow); transition: all 0.2s; } .cal-card:hover { box-shadow: var(--shadow-md); } /* Today / Tomorrow */ .cal-today { border: 2px solid var(--primary); box-shadow: 0 0 0 4px var(--primary-light), var(--shadow); } .cal-tomorrow { border: 2px dashed #a5b4fc; } .cal-head { padding: 14px 18px; background: var(--surface-alt); border-bottom: 1px solid var(--border); display: flex; justify-content: space-between; align-items: center; } .cal-head-left { display: flex; flex-direction: column; } .cal-day-name { font-size: 14px; font-weight: 700; color: var(--text); } .cal-date { font-size: 12px; color: var(--text-muted); font-weight: 500; margin-top: 1px; } .pill-today { background: var(--primary); color: #fff; padding: 3px 12px; border-radius: 20px; font-size: 11px; font-weight: 700; letter-spacing: 0.03em; } .pill-tomorrow { background: var(--primary-light); color: var(--primary); padding: 3px 12px; border-radius: 20px; font-size: 11px; font-weight: 700; letter-spacing: 0.03em; border: 1px solid #c7d2fe; } /* ── Event Rows ── */ .event-row { padding: 14px 18px; border-bottom: 1px solid var(--border); display: flex; justify-content: space-between; align-items: center; gap: 12px; transition: background 0.15s; } .event-row:last-child { border-bottom: none; } .event-row:hover { background: var(--surface-alt); } .event-left { display: flex; flex-direction: column; gap: 6px; min-width: 0; } .event-name { font-weight: 600; font-size: 14px; color: var(--text); text-decoration: none; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } .event-name:hover { color: var(--primary); } /* ── Badge line (type + registrar side by side) ── */ .badge-line { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; } .badge-type { display: inline-flex; align-items: center; padding: 3px 10px; border-radius: 5px; font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.04em; width: fit-content; } .badge-type-sme { background: #fef3c7; color: #92400e; } .badge-type-mainline { background: #dbeafe; color: #1e40af; } /* ── Registrar copy button (allotment only) ── */ .badge-registrar { display: inline-flex; align-items: center; gap: 5px; padding: 3px 10px; border-radius: 5px; font-size: 10px; font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; background: var(--warning-light); color: var(--warning); border: 1px solid #fde68a; width: fit-content; cursor: pointer; font-family: inherit; transition: all 0.15s; } .badge-registrar:hover { background: #fef08a; border-color: #fcd34d; } .badge-registrar:active { transform: scale(0.96); } .badge-registrar svg { width: 12px; height: 12px; flex-shrink: 0; } .badge-registrar.copied { background: var(--success-light); color: var(--success); border-color: #6ee7b7; } .badge-event { padding: 5px 14px; border-radius: 6px; font-size: 11px; font-weight: 700; color: #fff; white-space: nowrap; flex-shrink: 0; letter-spacing: 0.02em; } .badge-OPEN { background: var(--success); } .badge-CLOSE { background: var(--danger); } .badge-ALLOTMENT { background: var(--warning); } .badge-LISTING { background: var(--teal); } /* ── Empty State ── */ .empty-state { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius); padding: 48px 24px; text-align: center; box-shadow: var(--shadow); } .empty-icon { font-size: 36px; margin-bottom: 12px; } .empty-text { font-size: 14px; color: var(--text-muted); font-weight: 500; } /* ── Responsive ── */ @media (max-width: 768px) { .main-wrap { padding: 16px; } .filter-card { padding: 16px; gap: 14px; } .filter-pills a { padding: 6px 12px; font-size: 11px; } .event-row { padding: 12px 14px; } .event-name { font-size: 13px; } .cal-head { padding: 12px 14px; } } @media (max-width: 480px) { .brand { font-size: 17px; } } </style> </head> <body> <!-- Top Bar --> <div class="top-bar"> <div class="inner"> <div class="brand"> <div class="brand-icon">📅</div> IPO Calendar </div> <a href="index.php" class="btn-back">← Back to List</a> </div> </div> <div class="main-wrap"> <!-- Filters --> <div class="filter-card"> <div class="filter-section"> <span class="filter-label">Event Type</span> <div class="filter-pills"> <a class="<?=isActive('ALL',$eventFilter)?>" href="<?=urlWith(['event'=>'ALL'])?>">All</a> <a class="<?=isActive('OPEN',$eventFilter)?>" href="<?=urlWith(['event'=>'OPEN'])?>">Open</a> <a class="<?=isActive('CLOSE',$eventFilter)?>" href="<?=urlWith(['event'=>'CLOSE'])?>">Close</a> <a class="<?=isActive('ALLOTMENT',$eventFilter)?>" href="<?=urlWith(['event'=>'ALLOTMENT'])?>">Allotment</a> <a class="<?=isActive('LISTING',$eventFilter)?>" href="<?=urlWith(['event'=>'LISTING'])?>">Listing</a> </div> </div> <div class="filter-section"> <span class="filter-label">IPO Type</span> <div class="filter-pills"> <a class="<?=isActive('ALL',$typeFilter)?>" href="<?=urlWith(['type'=>'ALL'])?>">All</a> <a class="<?=isActive('MAINLINE',$typeFilter)?>" href="<?=urlWith(['type'=>'MAINLINE'])?>">Mainline</a> <a class="<?=isActive('SME',$typeFilter)?>" href="<?=urlWith(['type'=>'SME'])?>">SME</a> </div> </div> </div> <!-- Stats --> <div class="stats-line"> Next 30 days — <span class="count"><?= count($dates) ?></span> day<?= count($dates) !== 1 ? 's' : '' ?> with events </div> <!-- Calendar Grid --> <div class="row g-3"> <?php if(empty($dates)): ?> <div class="col-12"> <div class="empty-state"> <div class="empty-icon">📭</div> <div class="empty-text">No IPO events found for selected filters in the next 30 days.</div> </div> </div> <?php endif; ?> <?php foreach($dates as $date=>$events): ?> <?php $cardClass = ''; if($date === $todayKey) $cardClass = 'cal-today'; elseif($date === $tomorrowKey) $cardClass = 'cal-tomorrow'; ?> <div class="col-xl-4 col-lg-6"> <div class="cal-card <?=$cardClass?>"> <div class="cal-head"> <div class="cal-head-left"> <span class="cal-day-name"><?=date('l',strtotime($date))?></span> <span class="cal-date"><?=$date?></span> </div> <?php if($date===$todayKey): ?> <span class="pill-today">TODAY</span> <?php elseif($date===$tomorrowKey): ?> <span class="pill-tomorrow">TOMORROW</span> <?php endif; ?> </div> <?php foreach($events as $e): ?> <?php // First word of company name, lowercase (e.g. "Advit Jewels IPO" -> "advit") $firstWord = strtolower(trim(strtok((string)$e['name'], ' '))); ?> <div class="event-row"> <div class="event-left"> <a href="viewipo.php?id=<?=$e['id']?>" class="event-name"><?=safe($e['name'])?></a> <div class="badge-line"> <span class="badge-type <?= $e['type'] === 'SME' ? 'badge-type-sme' : 'badge-type-mainline' ?>"><?=$e['type']?></span> <?php if($e['event']==='ALLOTMENT' && !empty($e['title']) && $e['title']!=='ALLOTMENT'): ?> <button type="button" class="badge-registrar" data-copy="<?=safe($firstWord)?>" data-label="<?=safe($e['title'])?>" onclick="copyFirstWord(this)"> <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"> <rect x="9" y="9" width="13" height="13" rx="2" ry="2"></rect> <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"></path> </svg> <span class="reg-text"><?=safe($e['title'])?></span> </button> <?php endif; ?> </div> </div> <span class="badge-event badge-<?=$e['event']?>"> <?=$e['event']?> </span> </div> <?php endforeach; ?> </div> </div> <?php endforeach; ?> </div> </div> <script> function copyFirstWord(btn){ var text = btn.getAttribute('data-copy') || ''; if(!text) return; var done = function(){ var label = btn.querySelector('.reg-text'); var original = btn.getAttribute('data-label'); btn.classList.add('copied'); if(label) label.textContent = 'Copied!'; clearTimeout(btn._copyTimer); btn._copyTimer = setTimeout(function(){ btn.classList.remove('copied'); if(label) label.textContent = original; }, 1200); }; if(navigator.clipboard && navigator.clipboard.writeText){ navigator.clipboard.writeText(text).then(done).catch(function(){ fallbackCopy(text, done); }); } else { fallbackCopy(text, done); } } function fallbackCopy(text, cb){ var ta = document.createElement('textarea'); ta.value = text; ta.style.position = 'fixed'; ta.style.left = '-9999px'; ta.setAttribute('readonly', ''); document.body.appendChild(ta); ta.select(); try { document.execCommand('copy'); } catch(e){} document.body.removeChild(ta); if(cb) cb(); } </script> </body> </html>
| ver. 1.4 |
Github
|
.
| PHP 8.2.9 | Generation time: 0.02 |
proxy
|
phpinfo
|
Settings