<?php
if (!defined('_GNUBOARD_')) exit;
// 상단 아이콘 및 폰트 추가
add_stylesheet('<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">', 0);
add_stylesheet('<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700&family=Noto+Sans+KR:wght@300;500&display=swap">', 0);
add_stylesheet('<link rel="stylesheet" href="'.$board_skin_url.'/style.list.css">', 0);
add_stylesheet('<link rel="stylesheet" href="'.$board_skin_url.'/style.css">', 0);
error_reporting(E_ALL & ~E_NOTICE);
ini_set('display_errors', '0');
// 데이터 로드
$new_board = sql_query("select * from $write_table order by wr_datetime desc limit 1");
$lat_board = sql_fetch_array($new_board);
?>
<style>
/* 1. 애니메이션 & 배경 */
@keyframes fadeInUp { from { opacity: 0; transform: translateY(30px); } to { opacity: 1; transform: translateY(0); } }
#LIST { position: relative; min-height: 100vh; background: radial-gradient(circle at center, #1b2735 0%, #090a0f 100%); padding: 60px 0; font-family: 'Pretendard', sans-serif; }
:root {
--bg-color: #0f172a;
--card-bg: rgba(30, 41, 59, 0.5);
--accent-blue: #38bdf8;
--accent-purple: #818cf8;
--text-main: #f1f5f9;
--text-dim: #94a3b8;
--glass-border: rgba(255, 255, 255, 0.08);
}
#LIST { background: var(--bg-color); color: var(--text-main); font-family: 'Noto Sans KR', sans-serif; padding: 20px 0; width: 100%; margin: 0 auto; min-height: 100vh; }
@keyframes listFadeUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } }
.List-Table tr { opacity: 0; animation: listFadeUp 0.6s ease forwards; border-bottom: 1px solid var(--glass-border); transition: 0.2s; cursor: pointer; }
.TopTitle { padding: 20px; border-bottom: 1px solid var(--glass-border); margin-bottom: 20px; animation: listFadeUp 0.8s ease forwards; }
.TopTitle p { font-family: 'Orbitron', sans-serif; font-size: 1.8rem; font-weight: 700; margin: 0; color: var(--accent-blue); letter-spacing: 2px; }
.TopTitle span { font-size: 0.85rem; color: var(--text-dim); }
/* 컨트롤 바 버튼 공통 효과 */
.Control-Bar { display: flex; justify-content: space-between; align-items: center; padding: 10px 15px; background: var(--card-bg); border-radius: 8px; margin: 0 10px 15px 10px; border: 1px solid var(--glass-border); animation: listFadeUp 0.8s ease 0.2s forwards; opacity: 0; position: relative; z-index: 10; }
button, select { background: #1e293b; border: 1px solid var(--glass-border); color: var(--text-main); padding: 6px 12px; border-radius: 5px; cursor: pointer; font-size: 0.8rem; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); outline: none; }
/* ★ 마우스 오버 효과 ★ */
/* 일반 버튼 (NOTICE, SEARCH 등) */
.Control-Bar button:hover {
border-color: var(--accent-blue);
box-shadow: 0 0 15px rgba(56, 189, 248, 0.4);
color: #fff;
transform: translateY(-2px);
}
/* 관리자 버튼 전용 */
.btn-admin { background:#475569; color:#fff; }
.btn-admin:hover {
background: var(--accent-purple) !important;
border-color: var(--accent-purple) !important;
box-shadow: 0 0 20px rgba(129, 140, 248, 0.5) !important;
}
/* 글쓰기 버튼 전용 (색상 틀어짐 수정) */
.btn-write { background: var(--accent-blue); color: #000; font-weight: 700; }
.btn-write:hover {
background: var(--accent-blue) !important;
color: #000 !important;
box-shadow: 0 0 25px var(--accent-blue) !important;
filter: brightness(1.2);
transform: translateY(-3px);
}
select { appearance: none; -webkit-appearance: none; padding-right: 30px; background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%2394a3b8' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'%3E%3C/polyline%3E%3C/svg%3E"); background-repeat: no-repeat; background-position: right 10px center; }
select option { background: #1e293b; color: #fff; padding: 10px; }
select:hover { border-color: var(--accent-blue); box-shadow: 0 0 10px rgba(56, 189, 248, 0.2); }
/* 리스트 디자인 */
.List-Table { width: 100%; border-collapse: collapse; table-layout: fixed; }
.List-Table tr:hover { background: rgba(255,255,255,0.03); }
.List-Table td { padding: 15px 10px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.Num { width: 60px; text-align: center; color: var(--text-dim); font-size: 0.8rem; font-family: 'Orbitron'; }
.Subject { font-size: 0.95rem; }
.Data-Status { display: flex; align-items: center; justify-content: flex-end; gap: 12px; font-size: 0.75rem; }
.Icon-Code { color: var(--accent-purple); font-size: 1.1rem; filter: drop-shadow(0 0 3px rgba(129, 140, 248, 0.5)); }
.Icon-Link { color: var(--accent-blue); font-size: 1.1rem; filter: drop-shadow(0 0 3px rgba(56, 189, 248, 0.5)); }
.Icon-File { color: #facc15; font-size: 1.1rem; filter: drop-shadow(0 0 3px rgba(250, 204, 21, 0.5)); }
.Day { width: 100px; text-align: right; color: var(--text-dim); font-size: 0.8rem; padding-right: 20px !important; }
/* ★ 페이지네이션 스타일 유지 ★ */
#TERM_PAGING_DIRECT { display: flex; justify-content: center; align-items: center; gap: 6px; padding: 5px 0 50px 0; animation: listFadeUp 1s ease 0.5s forwards; opacity: 0; }
.trm-btn { display: inline-flex; align-items: center; justify-content: center; width: 38px; height: 38px; border-radius: 8px; background: rgba(30, 41, 59, 0.6); border: 1px solid rgba(255, 255, 255, 0.1); color: #94a3b8; text-decoration: none; font-family: 'Orbitron'; transition: 0.2s; }
.trm-current { background: rgba(56, 189, 248, 0.15) !important; border-color: var(--accent-blue) !important; color: var(--accent-blue) !important; box-shadow: 0 0 15px rgba(56, 189, 248, 0.3); }
.trm-btn:hover { border-color: var(--accent-blue); background: rgba(56, 189, 248, 0.1); transform: translateY(-3px); }
.trm-ico-start::before { content: "\f100"; font-family: "Font Awesome 6 Free"; font-weight: 900; color: var(--accent-blue); }
.trm-ico-prev::before { content: "\f104"; font-family: "Font Awesome 6 Free"; font-weight: 900; color: var(--accent-blue); }
.trm-ico-next::before { content: "\f105"; font-family: "Font Awesome 6 Free"; font-weight: 900; color: var(--accent-blue); }
.trm-ico-end::before { content: "\f101"; font-family: "Font Awesome 6 Free"; font-weight: 900; color: var(--accent-blue); }
.NoticeLayer { display:none; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 90%; max-width: 900px; background: #0f172a; padding: 40px; border-radius: 20px; border: 2px solid var(--accent-blue); z-index: 10001; box-shadow: 0 0 100px rgba(0,0,0,0.8); }
.Notice-Content-Area { font-size: 1.05rem; line-height: 1.8; color: #e2e8f0; max-height: 400px; overflow-y: auto; background: rgba(0,0,0,0.4); padding: 30px; border-radius: 12px; border: 1px solid var(--glass-border); margin-bottom: 30px; }
section#SCH { display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(15, 23, 42, 0.9); z-index: 9999; align-items: center; justify-content: center; }
.Live-Search-Wrap { position: relative; display: flex; align-items: center; }
.Live-Search-Input { background: rgba(0,0,0,0.3); border: 1px solid var(--glass-border); color: #fff; padding: 6px 35px 6px 12px; border-radius: 20px; font-size: 0.8rem; width: 120px; transition: 0.3s; }
.Live-Search-Input:focus { width: 180px; border-color: var(--accent-blue); outline: none; box-shadow: 0 0 15px rgba(56, 189, 248, 0.3); }
.Live-Search-Wrap i { position: absolute; right: 12px; color: var(--text-dim); font-size: 0.8rem; }
</style>
<article id='LIST'>
<section class="TopTitle">
<p><?php echo strtoupper($bo_table); ?></p>
<span><i class="fa-solid fa-layer-group"></i> <?php echo $board["bo_subject"]; ?></span>
</section>
<div class="Control-Bar">
<div class="Left" style="display:flex; gap:8px; align-items:center;">
<button type="button" onclick="$('#NoticeLayer').fadeIn();"><i class="fa-solid fa-bullhorn"></i> 공지사항</button>
<?php if ($is_category) { ?>
<select onchange="location.href=this.value;">
<option value="<?php echo get_pretty_url($bo_table); ?>">분류</option>
<?php
$categories = explode('|', $board['bo_category_list']);
foreach($categories as $ca) {
if(!$ca) continue;
$selected = ($sca == $ca) ? "selected" : "";
echo "<option value='".get_pretty_url($bo_table, '', 'sca='.urlencode($ca))."' $selected>$ca</option>";
}
?>
</select>
<select onchange="location.href=this.value;">
<option value="">종류</option>
<?php
$bo_1_opts = explode("|", $board['bo_1']);
foreach($bo_1_opts as $val) {
$val = trim($val); if(!$val) continue;
$selected = ($stx == $val && $sfl == 'x2_ca2') ? "selected" : "";
echo "<option value='".get_pretty_url($bo_table, '', 'sfl=x2_ca2&stx='.urlencode($val))."' $selected>$val</option>";
}
?>
</select>
<select onchange="location.href=this.value;">
<option value="">형태</option>
<?php
$bo_2_opts = explode("|", $board['bo_2']);
foreach($bo_2_opts as $val) {
$val = trim($val); if(!$val) continue;
$selected = ($stx == $val && $sfl == 'x2_ca3') ? "selected" : "";
echo "<option value='".get_pretty_url($bo_table, '', 'sfl=x2_ca3&stx='.urlencode($val))."' $selected>$val</option>";
}
?>
</select>
<?php if ($sca || $stx) { ?>
<button type="button" onclick="location.href='<?php echo get_pretty_url($bo_table); ?>';" style="background:rgba(255,255,255,0.1); color:var(--accent-blue); border-color:var(--accent-blue);"><i class="fa-solid fa-rotate-left"></i> TOTAL</button>
<?php } ?>
<?php } ?>
</div>
<div class="Right" style="display:flex; gap:10px; align-items:center;">
<div class="Live-Search-Wrap">
<input type="text" id="live-search" class="Live-Search-Input" placeholder="Filter...">
<i class="fa-solid fa-filter"></i>
</div>
<button type="button" onclick="$('#SCH').css('display','flex').hide().fadeIn();"><i class="fa-solid fa-magnifying-glass"></i> SEARCH</button>
<?php if ($is_admin) { ?>
<button type="button" onclick="location.href='<?php echo G5_ADMIN_URL; ?>/board_form.php?w=u&bo_table=<?php echo $bo_table; ?>'" class="btn-admin"><i class="fa-solid fa-gear"></i> ADMIN</button>
<?php } ?>
<?php if ($write_href) { ?>
<button type="button" onclick="location.href='<?php echo $write_href; ?>'" class="btn-write"><i class="fa-solid fa-pen"></i> WRITE</button>
<?php } ?>
</div>
</div>
<form name="fboardlist" id="fboardlist" action="./board_list_update.php" method="post">
<input type="hidden" name="bo_table" value="<?php echo $bo_table; ?>">
<table class="List-Table">
<tbody id="board-list-body">
<?php
for ($i=0; $i<count($list); $i++) {
$is_notice = $list[$i]['is_notice'];
$delay = ($i * 0.05) + 0.3;
$has_code = ($list[$i]['x2_txt']) ? true : false;
$has_link = ($list[$i]['wr_link1'] || $list[$i]['wr_link2']) ? true : false;
$has_file = ($list[$i]['icon_file']) ? true : false;
$clean_subject = preg_replace('/^\[[^\]]+\]\s*/', '', $list[$i]['subject']);
?>
<tr onclick="location.href='<?php echo $list[$i]['href']; ?>'" style="animation-delay: <?php echo $delay; ?>s;">
<td class="Num"><?php if ($is_notice) echo '<i class="fa-solid fa-thumbtack" style="color:var(--accent-blue)"></i>'; else echo $list[$i]['num']; ?></td>
<td class="Subject"><?php echo $clean_subject; ?></td>
<td class="Data-Status">
<?php if($has_link) echo '<i class="fa-solid fa-link Icon-Link" title="Link Available"></i>'; ?>
<?php if($has_file) echo '<i class="fa-solid fa-file-import Icon-File" title="File Attached"></i>'; ?>
<?php if($has_code) echo '<i class="fa-solid fa-code Icon-Code" title="Code Included"></i>'; ?>
</td>
<td class="Day"><?php echo substr($list[$i]['wr_datetime'], 2, 8); ?></td>
</tr>
<?php } ?>
</tbody>
</table>
</form>
<?php if ($total_page > 1) { ?>
<div id="TERM_PAGING_DIRECT">
<?php
$pg_count = $config['cf_write_pages'];
$start_pg = ( ( (int)( ($page - 1 ) / $pg_count ) ) * $pg_count ) + 1;
$end_pg = $start_pg + $pg_count - 1;
if ($end_pg >= $total_page) $end_pg = $total_page;
if ($page > 1) { echo '<a href="'.get_pretty_url($bo_table, '', $qstr.'&page=1').'" class="trm-btn"><i class="trm-ico-start"></i></a>'; }
if ($start_pg > 1) { echo '<a href="'.get_pretty_url($bo_table, '', $qstr.'&page='.($start_pg-1)).'" class="trm-btn"><i class="trm-ico-prev"></i></a>'; }
for ($k=$start_pg; $k<=$end_pg; $k++) {
if ($page != $k) { echo '<a href="'.get_pretty_url($bo_table, '', $qstr.'&page='.$k).'" class="trm-btn">'.$k.'</a>'; }
else { echo '<strong class="trm-btn trm-current">'.$k.'</strong>'; }
}
if ($total_page > $end_pg) { echo '<a href="'.get_pretty_url($bo_table, '', $qstr.'&page='.($end_pg+1)).'" class="trm-btn"><i class="trm-ico-next"></i></a>'; }
if ($page < $total_page) { echo '<a href="'.get_pretty_url($bo_table, '', $qstr.'&page='.$total_page).'" class="trm-btn"><i class="trm-ico-end"></i></a>'; }
?>
</div>
<?php } ?>
<div id="NoticeLayer" class="NoticeLayer">
<div style="display:flex; justify-content:space-between; align-items:center; margin-bottom:25px;">
<h3 style="margin:0; color:var(--accent-blue); font-family:'Orbitron'; font-size:1.5rem;"><i class="fa-solid fa-terminal"></i> BOARD NOTICE</h3>
<button type="button" onclick="$('#NoticeLayer').fadeOut();" style="background:none; border:none; color:var(--text-dim); font-size:1.5rem;"><i class="fa-solid fa-xmark"></i></button>
</div>
<div class="Notice-Content-Area">
<?php echo nl2br(stripslashes($board['notice'])); ?>
</div>
<div style="display:flex; justify-content:space-between; align-items:center; gap:20px;">
<?php if($is_admin) { ?>
<button type="button" onclick="open_notice_writer();" style="background:var(--accent-purple); color:#fff; border:none; padding:15px 30px; font-weight:800; flex:1; font-size:1rem;">
<i class="fa-solid fa-pen-nib"></i> WRITE NOTICE
</button>
<?php } ?>
<button type="button" onclick="$('#NoticeLayer').fadeOut();" style="background:rgba(255,255,255,0.1); color:#fff; border:none; padding:15px 30px; font-weight:800; flex:1; font-size:1rem;">
CLOSE TERMINAL
</button>
</div>
</div>
<section id="SCH" class="Search">
<div style="background:#1e293b; padding:30px; border-radius:15px; width:90%; max-width:800px; border:1px solid var(--glass-border); box-shadow: 0 0 30px rgba(0,0,0,0.5);">
<form name="fsearch" method="get">
<input type="hidden" name="bo_table" value="<?php echo $bo_table; ?>">
<h3 style="margin:0 0 20px 0; color:var(--accent-blue); font-size:1rem; font-family:'Orbitron';">TERMINAL SEARCH</h3>
<input type="text" name="stx" value="<?php echo stripslashes($stx); ?>" required placeholder="Keyword..." style="width:100%; background:rgba(0,0,0,0.2); border:none; border-bottom:2px solid var(--accent-blue); color:#fff; font-size:1.1rem; outline:none; padding:20px 20px;">
<div style="margin-top:25px; display:flex; gap:10px;">
<button type="submit" style="flex:1; background:var(--accent-blue); color:#000; font-weight:bold; padding:15px;">EXECUTE</button>
<button type="button" onclick="$('#SCH').fadeOut();" style="flex:1; background:none; border:1px solid var(--text-dim); color:var(--text-dim);">CANCEL</button>
</div>
</form>
</div>
</section>
</article>
<script>
function open_notice_writer() {
const w = 850; const h = 750;
const left = (window.screen.width / 2) - (w / 2);
const top = (window.screen.height / 2) - (h / 2);
const url = "<?php echo $board_skin_url; ?>/notice.php?bo_table=<?php echo $bo_table; ?>";
window.open(url, "notice_win", `width=${w}, height=${h}, left=${left}, top=${top}, scrollbars=yes, resizable=yes`);
}
$(function() {
$('#SCH').click(function(e) { if(e.target == this) $(this).fadeOut(); });
$("#live-search").on("keyup", function() {
var value = $(this).val().toLowerCase();
$("#board-list-body tr").filter(function() {
$(this).toggle($(this).find(".Subject").text().toLowerCase().indexOf(value) > -1)
});
});
});
</script>