<?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);
if (!function_exists('x2_base64url_encode')) {
function x2_base64url_encode($data)
{
return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}
}
if (!function_exists('x2_jwt_hs256')) {
function x2_jwt_hs256(array $payload, $secret)
{
$header = ['alg' => 'HS256', 'typ' => 'JWT'];
$h = x2_base64url_encode(json_encode($header));
$p = x2_base64url_encode(json_encode($payload));
$s = hash_hmac('sha256', $h.'.'.$p, $secret, true);
return $h.'.'.$p.'.'.x2_base64url_encode($s);
}
}
if (!function_exists('x2_http_get_json')) {
function x2_http_get_json($url, array $headers = [])
{
if (!function_exists('curl_init')) {
return null;
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 3);
curl_setopt($ch, CURLOPT_TIMEOUT, 8);
if (!empty($headers)) {
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
}
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($response === false || $http_code < 200 || $http_code >= 300) {
return null;
}
$decoded = json_decode($response, true);
return is_array($decoded) ? $decoded : null;
}
}
if (!function_exists('x2_to_float')) {
function x2_to_float($value)
{
$clean = preg_replace('/[^0-9.\-]/', '', (string)$value);
return ($clean === '' || $clean === '-' || $clean === '.') ? 0.0 : (float)$clean;
}
}
if (!function_exists('x2_fetch_upbit_current_asset')) {
function x2_fetch_upbit_current_asset()
{
$key_candidates = [
'/home/www/DB/key_upbit_trade.php',
isset($_SERVER['DOCUMENT_ROOT']) ? $_SERVER['DOCUMENT_ROOT'].'/DB/key_upbit_trade.php' : ''
];
$UPBIT_ACCESS_KEY = '';
$UPBIT_SECRET_KEY = '';
foreach ($key_candidates as $key_path) {
if ($key_path && file_exists($key_path)) {
include $key_path;
if (!empty($UPBIT_ACCESS_KEY) && !empty($UPBIT_SECRET_KEY)) {
break;
}
}
}
if (empty($UPBIT_ACCESS_KEY) || empty($UPBIT_SECRET_KEY)) {
return null;
}
$payload = [
'access_key' => $UPBIT_ACCESS_KEY,
'nonce' => md5(uniqid('', true))
];
$jwt = x2_jwt_hs256($payload, $UPBIT_SECRET_KEY);
$accounts = x2_http_get_json('https://api.upbit.com/v1/accounts', ['Authorization: Bearer '.$jwt]);
if (!is_array($accounts)) {
return null;
}
$total = 0.0;
$need_markets = [];
$holding_map = [];
$avg_map = [];
foreach ($accounts as $account) {
$currency = strtoupper($account['currency'] ?? '');
$balance = (float)($account['balance'] ?? 0);
$locked = (float)($account['locked'] ?? 0);
$amount = $balance + $locked;
if ($amount <= 0) {
continue;
}
if ($currency === 'KRW') {
$total += $amount;
continue;
}
$market = 'KRW-'.$currency;
$holding_map[$market] = $amount;
$avg_map[$market] = (float)($account['avg_buy_price'] ?? 0);
$need_markets[] = $market;
}
if (!empty($need_markets)) {
$price_map = [];
$need_markets = array_values(array_unique($need_markets));
$chunks = array_chunk($need_markets, 100);
foreach ($chunks as $markets) {
$url = 'https://api.upbit.com/v1/ticker?markets='.urlencode(implode(',', $markets));
$ticker_rows = x2_http_get_json($url);
if (!is_array($ticker_rows)) {
continue;
}
foreach ($ticker_rows as $ticker_row) {
$market = $ticker_row['market'] ?? '';
$trade_price = (float)($ticker_row['trade_price'] ?? 0);
if ($market !== '' && $trade_price > 0) {
$price_map[$market] = $trade_price;
}
}
}
foreach ($holding_map as $market => $quantity) {
$market_price = isset($price_map[$market]) ? (float)$price_map[$market] : 0;
if ($market_price <= 0 && isset($avg_map[$market])) {
$market_price = (float)$avg_map[$market];
}
$total += $quantity * $market_price;
}
}
return $total;
}
}
if (!empty($list) && is_array($list)) {
foreach ($list as $idx => $row) {
$list[$idx]['_origin_idx'] = $idx;
}
usort($list, function($a, $b) {
$a_top = !empty($a['x2_top']) ? 1 : 0;
$b_top = !empty($b['x2_top']) ? 1 : 0;
if ($a_top !== $b_top) {
return $b_top - $a_top;
}
$a_notice = !empty($a['is_notice']) ? 1 : 0;
$b_notice = !empty($b['is_notice']) ? 1 : 0;
if ($a_notice !== $b_notice) {
return $b_notice - $a_notice;
}
return ($a['_origin_idx'] ?? 0) - ($b['_origin_idx'] ?? 0);
});
}
$memo_cards = array();
$memo_sql = "SELECT wr_id, wr_subject, wr_datetime, x2_memo, x2_memo_clean
FROM {$write_table}
WHERE wr_is_comment = '0' AND wr_parent = wr_id
AND TRIM(IFNULL(x2_memo, '')) <> ''
ORDER BY wr_id DESC
LIMIT 40";
$memo_res = sql_query($memo_sql);
while($memo_row = sql_fetch_array($memo_res)) {
if (!empty($memo_row['x2_memo_clean'])) continue;
$memo_plain = trim(preg_replace('/\s+/', ' ', strip_tags($memo_row['x2_memo'])));
if ($memo_plain === '') continue;
$memo_plain_len = function_exists('mb_strlen') ? mb_strlen($memo_plain, 'UTF-8') : strlen($memo_plain);
if (function_exists('mb_substr')) {
$memo_preview = mb_substr($memo_plain, 0, 80, 'UTF-8');
if ($memo_plain_len > 80) $memo_preview .= '...';
} else {
$memo_preview = substr($memo_plain, 0, 80);
if ($memo_plain_len > 80) $memo_preview .= '...';
}
$memo_cards[] = array(
'wr_id' => $memo_row['wr_id'],
'subject' => $memo_row['wr_subject'],
'datetime' => $memo_row['wr_datetime'],
'preview' => $memo_preview,
'preview_len' => $memo_plain_len,
'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);
$upbit_current_asset_num = x2_fetch_upbit_current_asset();
$upbit_live_available = ($upbit_current_asset_num !== null);
$format_thousand = function($value) {
$raw = trim((string)$value);
if ($raw === '') return '-';
$num = x2_to_float($raw);
$has_decimal = strpos((string)$raw, '.') !== false;
if ($has_decimal) {
return number_format($num, 2, '.', ',');
}
return number_format($num, 0, '.', ',');
};
$format_rate = function($value) {
return number_format((float)$value, 2, '.', '').'%';
};
?>
<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>
<button type="button" class="btn" id="btnOpenMemo"><i class="fa-solid fa-note-sticky"></i> 메모(<?php echo count($memo_cards); ?>)</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; ?>">
<table class="List-Table">
<thead>
<tr class="List-Header">
<th class="Num">번호</th>
<th class="Run">상태</th>
<th class="Subject"> 제목</th>
<th class="BaseAmt"><i class="fa-solid fa-sack-dollar"></i> 기본금액</th>
<th class="CurrentAmt"><i class="fa-solid fa-wallet"></i> 현재자산</th>
<th class="TargetAmt"><i class="fa-solid fa-bullseye"></i> 목표금액</th>
<th class="ProfitAmt"><i class="fa-solid fa-coins"></i> 수익금</th>
<th class="ProfitRate"><i class="fa-solid fa-percent"></i> 수익률</th>
<th class="ReachRate"><i class="fa-solid fa-chart-simple"></i> 도달률</th>
<th class="UnitBase"><i class="fa-solid fa-cube"></i> 기본단위</th>
<th class="UnitAdd"><i class="fa-solid fa-plus"></i> 추가단위</th>
<th class="TradeItem"><i class="fa-solid fa-chart-line"></i> 매매종목</th>
<th class="Day"><i class="fa-regular fa-calendar"></i> 날짜</th>
<th class="CompleteDay"><i class="fa-regular fa-clock"></i> 완료일</th>
</tr>
</thead>
<tbody>
<?php
for ($i=0; $i<count($list); $i++) {
$is_notice = $list[$i]['is_notice'];
$run_val = $list[$i]['x2_run'];
$run_text = ($run_val == '1') ? '완료' : '진행';
$run_class = ($run_val == '1') ? 'run_on' : 'run_off';
$coin_symbol = trim(strip_tags($list[$i]['subject']));
$is_top = !empty($list[$i]['x2_top']);
$is_label = !empty($list[$i]['x2_label']);
$is_core = !empty($list[$i]['x2_core']);
$date_text = '-';
if (!empty($list[$i]['wr_datetime']) && $list[$i]['wr_datetime'] !== '0000-00-00 00:00:00') {
$ts = strtotime($list[$i]['wr_datetime']);
if ($ts !== false) {
$date_text = date('Y-m-d', $ts);
}
}
$complete_text = '진행중';
if (!empty($list[$i]['x2_datetime']) && $list[$i]['x2_datetime'] !== '0000-00-00 00:00:00') {
$ts = strtotime($list[$i]['x2_datetime']);
if ($ts !== false) {
$complete_text = date('Y-m-d', $ts);
}
}
$base_raw = isset($list[$i]['x2_base_amount']) ? trim($list[$i]['x2_base_amount']) : '';
$target_raw = isset($list[$i]['x2_target_amount']) ? trim($list[$i]['x2_target_amount']) : '';
$current_raw = isset($list[$i]['x2_current_asset']) ? trim($list[$i]['x2_current_asset']) : '';
$profit_raw = isset($list[$i]['x2_profit_amount']) ? trim($list[$i]['x2_profit_amount']) : '';
$profit_rate_raw = isset($list[$i]['x2_profit_rate']) ? trim($list[$i]['x2_profit_rate']) : '';
$reach_rate_raw = isset($list[$i]['x2_reach_rate']) ? trim($list[$i]['x2_reach_rate']) : '';
$base_num = x2_to_float($base_raw);
$target_num = x2_to_float($target_raw);
$current_num = ($current_raw !== '') ? x2_to_float($current_raw) : ($upbit_live_available ? $upbit_current_asset_num : null);
$profit_num = ($profit_raw !== '') ? x2_to_float($profit_raw) : (($current_num !== null) ? ($current_num - $base_num) : null);
$profit_rate_num = ($profit_rate_raw !== '') ? x2_to_float($profit_rate_raw) : (($profit_num !== null && $base_num != 0.0) ? (($profit_num / $base_num) * 100) : null);
$reach_rate_num = null;
if ($reach_rate_raw !== '') {
$reach_rate_num = x2_to_float($reach_rate_raw);
} else if ($current_num !== null && ($target_num - $base_num) != 0.0) {
$reach_rate_num = (($current_num - $base_num) / ($target_num - $base_num)) * 100;
}
$unit_base_raw = isset($list[$i]['x2_unit_base']) ? trim($list[$i]['x2_unit_base']) : '';
$unit_add_raw = isset($list[$i]['x2_unit_add']) ? trim($list[$i]['x2_unit_add']) : '';
$unit_base_view = $unit_base_raw !== '' ? $format_thousand($unit_base_raw) : '-';
$unit_add_view = $unit_add_raw !== '' ? $format_thousand($unit_add_raw) : '-';
$trade_item_raw = isset($list[$i]['x2_trade_item']) ? trim($list[$i]['x2_trade_item']) : '';
$trade_items = array_values(array_filter(array_map('trim', explode(',', $trade_item_raw))));
$trade_item_view = '-';
if (!empty($trade_items)) {
$first_item = $trade_items[0];
$extra_count = count($trade_items) - 1;
$trade_item_view = $extra_count > 0 ? ($first_item.' 외 '.$extra_count.'종') : $first_item;
}
$base_view = $base_raw !== '' ? $format_thousand($base_raw) : '-';
$target_view = $target_raw !== '' ? $format_thousand($target_raw) : '-';
$current_view = ($current_raw !== '') ? $format_thousand($current_raw) : (($upbit_live_available && $current_num !== null) ? $format_thousand($current_num) : '-');
$profit_view = $profit_raw !== '' ? $format_thousand($profit_raw) : (($profit_num !== null) ? $format_thousand($profit_num) : '-');
$profit_rate_view = $profit_rate_raw !== '' ? $format_rate(x2_to_float($profit_rate_raw)) : (($profit_rate_num !== null) ? $format_rate($profit_rate_num) : '-');
$reach_rate_view = $reach_rate_raw !== '' ? $format_rate(x2_to_float($reach_rate_raw)) : (($reach_rate_num !== null) ? $format_rate($reach_rate_num) : '-');
$current_class = ($current_num === null) ? '' : (($current_num >= $base_num) ? 'val-up-bright' : 'val-down-bright');
$profit_class = ($profit_num === null) ? '' : (($profit_num >= 0) ? 'val-up-deep' : 'val-down-deep');
$profit_rate_class = ($profit_rate_num === null) ? '' : (($profit_rate_num >= 0) ? 'val-up-deep' : 'val-down-deep');
$reach_rate_class = ($reach_rate_num === null) ? '' : (($reach_rate_num < 0) ? 'val-down-bright' : 'val-up-blue');
$current_arrow = ($current_num === null) ? '' : (($current_num >= $base_num) ? '▲' : '▼');
$profit_rate_arrow = ($profit_rate_num === null) ? '' : (($profit_rate_num >= 0) ? '▲' : '▼');
$current_arrow_class = ($current_num === null) ? '' : (($current_num >= $base_num) ? 'arrow-up-bright' : 'arrow-down-bright');
$profit_rate_arrow_class = ($profit_rate_num === null) ? '' : (($profit_rate_num >= 0) ? 'arrow-up-deep' : 'arrow-down-deep');
$live_current = ($current_raw === '');
$live_profit = ($profit_raw === '');
$live_profit_rate = ($profit_rate_raw === '');
$live_reach_rate = ($reach_rate_raw === '');
$has_detail_desc = isset($list[$i]['wr_content']) && trim(strip_tags((string)$list[$i]['wr_content'])) !== '';
$has_extra_text = isset($list[$i]['x2_text']) && trim((string)$list[$i]['x2_text']) !== '';
$has_attach = !empty($list[$i]['icon_file']);
$has_link = !empty($list[$i]['icon_link']) || !empty($list[$i]['wr_link1']) || !empty($list[$i]['wr_link2']);
?>
<tr class="list-row <?php echo $is_core ? 'is-core' : ''; ?>"
onclick="location.href='<?php echo $list[$i]['href']; ?>'"
data-symbol="<?php echo htmlspecialchars(mb_strtolower($coin_symbol, 'UTF-8'), ENT_QUOTES); ?>"
data-base-num="<?php echo $base_num; ?>"
data-target-num="<?php echo $target_num; ?>"
data-live-current="<?php echo $live_current ? '1' : '0'; ?>"
data-live-profit="<?php echo $live_profit ? '1' : '0'; ?>"
data-live-profit-rate="<?php echo $live_profit_rate ? '1' : '0'; ?>"
data-live-reach-rate="<?php echo $live_reach_rate ? '1' : '0'; ?>">
<td class="Num">
<?php if ($is_notice) echo '<i class="fa-solid fa-thumbtack row-pin"></i>'; else echo $list[$i]['num']; ?>
</td>
<td class="Run">
<span class="run_btn <?php echo $run_class; ?>"><?php echo $run_text; ?></span>
</td>
<td class="Subject">
<div class="coin-line">
<?php echo $list[$i]['icon_reply']; ?>
<?php if ($is_notice) { ?>
<strong class="coin-symbol"><?php echo $coin_symbol; ?></strong>
<?php } else { ?>
<span class="coin-symbol"><?php echo $coin_symbol; ?></span>
<?php } ?>
<?php if ($is_top) { ?><i class="fa-solid fa-circle-up coin-badge-top" title="우선"></i><?php } ?>
<?php if ($is_label) { ?><i class="fa-solid fa-star coin-badge-label" title="라벨"></i><?php } ?>
<?php if ($is_core) { ?><i class="fa-solid fa-gem coin-badge-core" title="핵심"></i><?php } ?>
<?php if ($has_detail_desc) { ?><i class="fa-solid fa-file-lines coin-badge-meta" title="상세설명"></i><?php } ?>
<?php if ($has_extra_text) { ?><i class="fa-solid fa-code coin-badge-meta" title="추가내용"></i><?php } ?>
<?php if ($has_attach) { ?><i class="fa-solid fa-paperclip coin-badge-meta" title="첨부파일"></i><?php } ?>
<?php if ($has_link) { ?><i class="fa-solid fa-link coin-badge-meta" title="링크"></i><?php } ?>
<?php if ($list[$i]['comment_cnt']) { ?>
<span class="comment-badge"><?php echo $list[$i]['comment_cnt']; ?></span>
<?php } ?>
</div>
</td>
<td class="BaseAmt"><?php echo $base_view; ?></td>
<td class="CurrentAmt js-current-cell <?php echo $current_class; ?>"><span class="metric-value js-current-value"><?php echo $current_view; ?></span><span class="metric-arrow js-current-arrow <?php echo $current_arrow_class; ?>"><?php echo $current_arrow; ?></span></td>
<td class="TargetAmt"><?php echo $target_view; ?></td>
<td class="ProfitAmt js-profit-cell <?php echo $profit_class; ?>"><span class="js-profit-value"><?php echo $profit_view; ?></span></td>
<td class="ProfitRate js-profit-rate-cell <?php echo $profit_rate_class; ?>"><span class="metric-value js-profit-rate-value"><?php echo $profit_rate_view; ?></span><span class="metric-arrow js-profit-rate-arrow <?php echo $profit_rate_arrow_class; ?>"><?php echo $profit_rate_arrow; ?></span></td>
<td class="ReachRate js-reach-rate-cell <?php echo $reach_rate_class; ?>"><span class="js-reach-rate-value"><?php echo $reach_rate_view; ?></span></td>
<td class="UnitBase"><?php echo $unit_base_view; ?></td>
<td class="UnitAdd"><?php echo $unit_add_view; ?></td>
<td class="TradeItem"><?php echo get_text($trade_item_view); ?></td>
<td class="Day"><?php echo $date_text; ?></td>
<td class="CompleteDay"><?php echo $complete_text; ?></td>
</tr>
<?php } ?>
<?php if (count($list) == 0) { ?>
<tr class="empty-row"><td colspan="14">출력할 데이터가 없습니다.</td></tr>
<?php } ?>
<tr id="RealtimeNoResult" class="empty-row" style="display:none;"><td colspan="14">실시간 검색 결과가 없습니다.</td></tr>
</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 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-subject"><?php echo get_text($memo_card['subject']); ?></span>
<span class="memo-date"><?php echo date('Y-m-d H:i', strtotime($memo_card['datetime'])); ?></span>
</div>
<div class="memo-preview">
<?php echo get_text($memo_card['preview']); ?>
</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'); ?>