<?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;400;500;700&display=swap">', 0);
add_stylesheet('<link rel="stylesheet" href="'.$board_skin_url.'/style.list.css">', 0);
$memo_cards = array();
// [트리플 필터 적용 - 체크박스 전용 최적화]
// 1. x2_pin 필드가 '1'인 것만 (체크박스 체크된 데이터)
// 2. x2_end가 완료되지 않은 것만 (미결 사항)
// 3. wr_subject를 가져와서 화면에 출력
$memo_sql = "SELECT wr_id, wr_subject, wr_datetime, x2_end, x2_pin
FROM {$write_table}
WHERE wr_is_comment = '0'
AND x2_pin = '1' -- [조건 1] 핀 체크(1)된 데이터만 확실하게!
AND (x2_end = '0' OR x2_end = '' OR x2_end IS NULL) -- [조건 2] 미완료 상태만
ORDER BY wr_id DESC
LIMIT 1000";
$memo_res = sql_query($memo_sql);
while($memo_row = sql_fetch_array($memo_res)) {
// 제목(wr_subject) 정리
// [수정] 문자열 시작 부분의 모든 공백 및 특수 제어 문자를 싹 다 박멸!
$display_text = preg_replace('/^\s+/u', '', strip_tags($memo_row['wr_subject']));
if ($display_text === '') continue;
// UI 가독성을 위한 글자수 제한 (80자)
$preview = mb_strimwidth($display_text, 0, 80, "...", "UTF-8");
$memo_cards[] = array(
'wr_id' => $memo_row['wr_id'],
'subject' => $memo_row['wr_subject'], // 원본 제목
'datetime' => $memo_row['wr_datetime'],
'preview' => $preview, // 화면 출력용 제목
'href' => get_pretty_url($bo_table, $memo_row['wr_id'])
);
}
$notice_text = stripslashes((string)$board['notice']);
$notice_lines = preg_split('/\r\n|\r|\n/', $notice_text);
$notice_lines = array_map(function($line) {
return trim($line);
}, $notice_lines);
$notice_clean = implode("\n", $notice_lines);
?>
<article id="LIST">
<section class="TopTitle">
<p><?php echo strtoupper($bo_table); ?></p>
<span><i class="fa-solid fa-satellite"></i> <?php echo $board['bo_subject']; ?></span>
</section>
<div class="Control-Bar">
<div class="Left">
<button type="button" class="btn" id="btnOpenNotice"><i class="fa-solid fa-bullhorn"></i> 공지사항</button>
<?php if ($is_category) { ?>
<select class="control-select" onchange="location.href=this.value;">
<option value="<?php echo get_pretty_url($bo_table); ?>">실행상태</option>
<option value="<?php echo get_pretty_url($bo_table, '', 'sfl=x2_run&stx=1'); ?>" <?php echo $stx=='1'?'selected':''; ?>>실행</option>
<option value="<?php echo get_pretty_url($bo_table, '', 'sfl=x2_run&stx=0'); ?>" <?php echo ($stx=='0' && $stx!='')?'selected':''; ?>>중지</option>
</select>
<select class="control-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 class="control-select" onchange="location.href=this.value;">
<option value="">중분류</option>
<?php
$sql2 = "select distinct x2_ca2 from $write_table where x2_ca2 <> '' order by x2_ca2";
$res2 = sql_query($sql2);
while($row2 = sql_fetch_array($res2)) {
echo "<option value='".get_pretty_url($bo_table, '', 'sfl=x2_ca2&stx='.urlencode($row2['x2_ca2']))."'>".$row2['x2_ca2']."</option>";
}
?>
</select>
<select class="control-select" onchange="location.href=this.value;">
<option value="">소분류</option>
<?php
$sql3 = "select distinct x2_ca3 from $write_table where x2_ca3 <> '' order by x2_ca3";
$res3 = sql_query($sql3);
while($row3 = sql_fetch_array($res3)) {
echo "<option value='".get_pretty_url($bo_table, '', 'sfl=x2_ca3&stx='.urlencode($row3['x2_ca3']))."'>".$row3['x2_ca3']."</option>";
}
?>
</select>
<div class="filter-group" style="display:inline-block;">
<button type="button" class="btn btn-filter" id="btnFilterPending">
<i class="fa-solid fa-hourglass-half"></i> <span>미완료</span>
</button>
<button type="button" class="btn btn-filter" id="btnFilterCompleted">
<i class="fa-solid fa-check-double"></i> <span>완료만</span>
</button>
<button type="button" class="btn" id="btnFilterAll" style="color: #ff4444; display: none;">
<i class="fa-solid fa-list"></i> <span>전체</span>
</button>
</div>
<button type="button" class="btn" id="btnOpenMemo"><i class="fa-solid fa-note-sticky"></i> 메모</button>
<?php } ?>
</div>
<div class="Right">
<div class="realtime-search-wrap">
<i class="fa-solid fa-filter"></i>
<input type="text" id="realtimeSearch" placeholder="실시간 검색 (심볼/한글명)">
</div>
<button type="button" class="btn" id="btnOpenSearch"><i class="fa-solid fa-magnifying-glass"></i> 검색</button>
<?php if ($is_admin) { ?>
<button type="button" class="btn btn-admin" onclick="location.href='<?php echo G5_ADMIN_URL; ?>/board_form.php?w=u&bo_table=<?php echo $bo_table; ?>'"><i class="fa-solid fa-gear"></i> 관리</button>
<?php } ?>
<?php if ($write_href) { ?>
<button type="button" class="btn btn-write" onclick="location.href='<?php echo $write_href; ?>'"><i class="fa-solid fa-pen"></i> 글쓰기</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; ?>">
<input type="hidden" name="sfl" value="<?php echo $sfl; ?>">
<input type="hidden" name="stx" value="<?php echo $stx; ?>">
<div id="memo_layer_popup" onclick="close_memo_popup();">
<div class="Pop">
<div class="Title">
<span onclick="close_memo_popup();">닫기</span>
</div>
<iframe id="memo_iframe" frameborder="0"></iframe>
</div>
</div>
<div class="memo-masonry-wrapper">
<?php
for ($i=0; $i<count($list); $i++) {
$full_memo = get_text($list[$i]['wr_subject'], 0);
$date_info = date('y-m-d H:i', strtotime($list[$i]['wr_datetime']));
$view_url = "./board.php?bo_table=$bo_table&wr_id={$list[$i]['wr_id']}";
$update_url = "./write.php?w=u&bo_table=$bo_table&wr_id={$list[$i]['wr_id']}";
$lines = explode("\n", $full_memo);
$numbered_lines = array();
for ($j = 0; $j < count($lines) && $j < 15; $j++) {
$numbered_lines[] = ($j + 1) . ". " . $lines[$j];
}
$cut_memo = implode("\n", $numbered_lines);
if (count($lines) > 15) {
$cut_memo .= "\n...";
}
?>
<div class="memo-card-item">
<div class="memo-card-header"><?php echo $date_info; ?></div>
<div class="memo-card-body" onclick="open_memo_popup('<?php echo $view_url; ?>');" style="<?php if ($list[$i]['x2_end']) echo 'opacity: 0.3; text-decoration: line-through;'; ?>">
<?php echo nl2br($cut_memo); ?>
</div>
<div class="memo-card-footer">
<a href="<?php echo $update_url; ?>">수정</a>
</div>
</div>
<?php } ?>
</div>
</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 class="notice-head">
<h3><i class="fa-solid fa-circle-info"></i> 공지사항</h3>
<button type="button" class="btn-icon" id="btnCloseNoticeTop"><i class="fa-solid fa-xmark"></i></button>
</div>
<div class="notice-body">
<?php echo nl2br(get_text($notice_clean, 0)); ?>
</div>
<div class="notice-foot">
<?php if ($is_admin) { ?>
<button type="button" class="btn btn-admin" onclick="window.open('<?php echo $board_skin_url;?>/notice.php?bo_table=<?php echo $bo_table;?>', 'notice_win', 'width=800,height=700,left='+(screen.availWidth-800)/2+',top='+(screen.availHeight-600)/2);">공지 수정</button>
<?php } ?>
<button type="button" class="btn" id="btnCloseNoticeBottom">닫기</button>
</div>
</div>
<div id="MemoLayer" class="MemoLayer">
<div class="memo-head">
<h3><i class="fa-solid fa-note-sticky"></i> 메모</h3>
<div class="memo-head-actions">
<div class="memo-view-toggle" role="group" aria-label="메모 출력 방식">
<button type="button" class="memo-view-btn" data-view="1x1">1X1</button>
<button type="button" class="memo-view-btn" data-view="1x2">1X2</button>
</div>
<button type="button" class="btn-icon" id="btnCloseMemoTop"><i class="fa-solid fa-xmark"></i></button>
</div>
</div>
<div class="memo-body">
<?php if (!empty($memo_cards)) { ?>
<?php foreach ($memo_cards as $memo_card) { ?>
<a href="<?php echo $memo_card['href']; ?>" class="memo-item">
<div class="memo-item-head">
<span class="memo-date"><?php echo date('Y-m-d H:i', strtotime($memo_card['datetime'])); ?></span>
</div>
<div class="memo-preview">
<?php echo nl2br(get_text($memo_card['preview'], 0)); ?>
</div>
</a>
<?php } ?>
<?php } else { ?>
<div class="memo-empty">표시할 메모가 없습니다.</div>
<?php } ?>
</div>
<div class="memo-foot">
<button type="button" class="btn" id="btnCloseMemoBottom">닫기</button>
</div>
</div>
<section id="SCH" class="Search">
<div class="search-panel">
<form name="fsearch" method="get" class="search-form">
<input type="hidden" name="bo_table" value="<?php echo $bo_table; ?>">
<input type="hidden" name="sfl" value="<?php echo $sfl; ?>">
<h3>검색</h3>
<input type="text" name="stx" value="<?php echo stripslashes($stx); ?>" required placeholder="검색어 입력" class="search-input">
<div class="search-actions">
<button type="submit" class="btn btn-write">검색</button>
<button type="button" class="btn" id="btnCloseSearch">취소</button>
</div>
</form>
</div>
</section>
</article>
<?php include_once($board_skin_path.'/list/list.script.php'); ?>