auction_list.php

main 238 lines · 11.4 KB Raw
Alex Alex Commit Initial commit 01/10/2026 09:20
1<?php
2?>
3<style>
4.auc2-filters { display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-end; margin-bottom: 15px; }
5.auc2-filters .auc2-field { display: flex; flex-direction: column; gap: 3px; font-size: 12px; }
6.auc2-filters input, .auc2-filters select { padding: 4px 6px; }
7.auc2-results-bar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; font-size: 13px; }
8.auc2-pagination { display: flex; gap: 4px; flex-wrap: wrap; }
9.auc2-pagination a, .auc2-pagination span { padding: 3px 8px; border: 1px solid #999; text-decoration: none; }
10.auc2-pagination .is-current { font-weight: bold; }
11.auc2-card { border: 1px solid #999; margin-bottom: 12px; padding: 8px 10px; }
12.auc2-card-header { margin-bottom: 6px; }
13.auc2-card-header .auc2-name { font-weight: bold; }
14.auc2-card-row { display: flex; gap: 14px; align-items: flex-start; flex-wrap: wrap; }
15.auc2-col-outfit { width: 64px; flex: 0 0 auto; text-align: center; }
16.auc2-col-items { flex: 0 0 auto; display: grid; grid-template-columns: repeat(2, 34px); grid-template-rows: repeat(2, 34px); gap: 4px; }
17.auc2-item-tile { position: relative; width: 34px; height: 34px; border: 1px solid #ccc; display: flex; align-items: center; justify-content: center; }
18.auc2-item-tile img { max-width: 28px; max-height: 28px; }
19.auc2-item-count { position: absolute; bottom: 0; right: 1px; font-size: 9px; background: rgba(0,0,0,.6); color: #fff; padding: 0 2px; }
20.auc2-col-data { flex: 1 1 220px; font-size: 12px; line-height: 1.5; }
21.auc2-col-data .auc2-label { color: #666; }
22.auc2-coin { width: 14px; height: 14px; vertical-align: middle; margin-left: 2px; }
23.auc2-amount { white-space: nowrap; }
24.auc2-col-bid { flex: 0 0 180px; border-left: 1px solid #ccc; padding-left: 12px; }
25.auc2-col-bid form { display: flex; flex-direction: column; gap: 4px; }
26</style>
27
28<?php if ($pending !== false && $pending): ?>
29 <h2><?= t('common.congrats') ?></h2>
30 <p><?= t('common.you_have') ?> <?php echo (COUNT($pending) > 1) ? 'characters' : 'a character'; ?> ready to claim!</p>
31 <?php foreach($pending as $character): ?>
32 <table class="auction_char">
33 <tr class="yellow">
34 <td>Level</td>
35 <td><?= t('common.vocation') ?></td>
36 <td><?= t('auc.details') ?></td>
37 <td>Price</td>
38 </tr>
39 <tr>
40 <td><?php echo $character['level']; ?></td>
41 <td><?php echo vocation_id_to_name($character['vocation']); ?></td>
42 <td><a href="/auctionChar.php?action=view&zaid=<?php echo $character['zaid']; ?>">VIEW</a></td>
43 <td><?php echo $character['price']; ?></td>
44 </tr>
45 <tr>
46 <?php if ($loadOutfits): ?>
47 <td class="outfitColumn">
48 <img src="<?php echo $config['show_outfits']['imageServer']; ?>?id=<?php echo $character['type']; ?>&addons=<?php echo $character['addons']; ?>&head=<?php echo $character['head']; ?>&body=<?php echo $character['body']; ?>&legs=<?php echo $character['legs']; ?>&feet=<?php echo $character['feet']; ?>" alt="img">
49 </td>
50 <?php endif; ?>
51 <td colspan="3">
52 <p><?= t('auc.claim_name') ?></p>
53 <form action="/auctionChar.php" method="POST">
54 <input type="hidden" name="action" value="claim">
55 <input type="hidden" name="zaid" value="<?php echo $character['zaid']; ?>">
56 <input type="text" name="name">
57 <input type="submit" value="<?= t('auc.claim_btn') ?>">
58 </form>
59 </td>
60 </tr>
61 </table>
62 <?php endforeach; ?>
63 <h2><?= t('auc.ongoing') ?></h2>
64<?php endif; ?>
65
66<?php if ($is_admin): ?>
67 <p>Admin: <a href="/admin/index.php?p=auction"><?= t('auc.history') ?></a></p>
68<?php endif; ?>
69
70<?php
71if (!function_exists('auc2_url')) {
72 function auc2_url(array $overrides = array()) {
73 global $filterVoc, $filterLevelMin, $filterLevelMax, $search, $sort, $page;
74 $params = array_merge(array(
75 'voc' => $filterVoc ?: '',
76 'level_min' => $filterLevelMin ?: '',
77 'level_max' => $filterLevelMax ?: '',
78 'q' => $search,
79 'sort' => $sort,
80 'page' => $page,
81 ), $overrides);
82 $params = array_filter($params, static fn($v) => $v !== '' && $v !== 0 && $v !== null);
83 return 'auctionChar.php?' . http_build_query($params);
84 }
85}
86?>
87
88<form action="auctionChar.php" method="get" class="auc2-filters">
89 <div class="auc2-field">
90 <label for="auc2_voc"><?= t('common.vocation') ?></label>
91 <select id="auc2_voc" name="voc">
92 <option value="0"><?= t('vocation.any') ?></option>
93 <?php foreach ($config['vocations'] as $id => $vocation): if ((int)$id === 0) continue; ?>
94 <option value="<?= (int)$id ?>" <?= $filterVoc === (int)$id ? 'selected' : '' ?>><?= h($vocation['name']) ?></option>
95 <?php endforeach; ?>
96 </select>
97 </div>
98 <div class="auc2-field">
99 <label for="auc2_level_min"><?= t('auc.min_level') ?></label>
100 <input type="number" id="auc2_level_min" name="level_min" min="0" value="<?= $filterLevelMin ?: '' ?>" style="width:80px;">
101 </div>
102 <div class="auc2-field">
103 <label for="auc2_level_max">&mdash;</label>
104 <input type="number" id="auc2_level_max" name="level_max" min="0" value="<?= $filterLevelMax ?: '' ?>" style="width:80px;">
105 </div>
106 <div class="auc2-field">
107 <label for="auc2_sort"><?= t_default('auc.sort_by', 'Sort by') ?></label>
108 <select id="auc2_sort" name="sort">
109 <option value="level_desc" <?= $sort === 'level_desc' ? 'selected' : '' ?>><?= t_default('auc.sort_level_desc', 'Level (high to low)') ?></option>
110 <option value="level_asc" <?= $sort === 'level_asc' ? 'selected' : '' ?>><?= t_default('auc.sort_level_asc', 'Level (low to high)') ?></option>
111 <option value="price_desc" <?= $sort === 'price_desc' ? 'selected' : '' ?>><?= t_default('auc.sort_price_desc', 'Price (high to low)') ?></option>
112 <option value="price_asc" <?= $sort === 'price_asc' ? 'selected' : '' ?>><?= t_default('auc.sort_price_asc', 'Price (low to high)') ?></option>
113 <option value="ending_soon" <?= $sort === 'ending_soon' ? 'selected' : '' ?>><?= t_default('auc.sort_ending_soon', 'Ending soon') ?></option>
114 </select>
115 </div>
116 <div class="auc2-field" style="flex:1 1 200px;">
117 <label for="auc2_q"><?= t('common.search') ?></label>
118 <input type="text" id="auc2_q" name="q" value="<?= h($search) ?>" placeholder="<?= h(t_default('auc.search_placeholder', 'Character or item name')) ?>">
119 </div>
120 <div class="auc2-field">
121 <input type="submit" value="<?= t('common.search') ?>">
122 </div>
123</form>
124
125<div class="auc2-results-bar">
126 <?php if ($pageCount > 1): ?>
127 <div class="auc2-pagination">
128 <?php for ($p = 1; $p <= $pageCount; $p++): ?>
129 <?php if ($p === $page): ?>
130 <span class="is-current"><?= $p ?></span>
131 <?php else: ?>
132 <a href="<?= h(auc2_url(['page' => $p])) ?>"><?= $p ?></a>
133 <?php endif; ?>
134 <?php endfor; ?>
135 </div>
136 <?php endif; ?>
137</div>
138
139<?php if (is_array($characters) && !empty($characters)): ?>
140 <?php foreach ($characters as $character): ?>
141 <article class="auc2-card">
142 <div class="auc2-card-header">
143 <div class="auc2-name"><a href="/auctionChar.php?action=view&zaid=<?= (int)$character['zaid'] ?>"><?= h(t('common.level')) ?> <?= (int)$character['level'] ?> <?= h(vocation_id_to_name($character['vocation'])) ?></a></div>
144 <div>
145 <?= t('common.level') ?>: <?= (int)$character['level'] ?>
146 | <?= t('common.vocation') ?>: <?= h(vocation_id_to_name($character['vocation'])) ?>
147 | <?= ((int)$character['sex'] === 1) ? t('common.male') : t('common.female') ?>
148 | <a href="/auctionChar.php?action=view&zaid=<?= (int)$character['zaid'] ?>"><?= t('auc.details') ?></a>
149 </div>
150 </div>
151 <div class="auc2-card-row">
152 <div class="auc2-col-outfit">
153 <?php if ($loadOutfits): ?>
154 <img src="<?php echo $config['show_outfits']['imageServer']; ?>?id=<?php echo $character['type']; ?>&addons=<?php echo $character['addons']; ?>&head=<?php echo $character['head']; ?>&body=<?php echo $character['body']; ?>&legs=<?php echo $character['legs']; ?>&feet=<?php echo $character['feet']; ?>" alt="">
155 <?php endif; ?>
156 </div>
157 <div class="auc2-col-items">
158 <?php $highlights = $highlightItems[(int)$character['player_id']] ?? array(); ?>
159 <?php foreach ($highlights as $hi): ?>
160 <div class="auc2-item-tile" title="<?= h($items[$hi['itemtype']] ?? ('#' . $hi['itemtype'])) ?>">
161 <img src="<?= h(znote_item_image_url((int)$hi['itemtype'])) ?>" alt="">
162 <?php if ($hi['count'] > 1): ?><span class="auc2-item-count"><?= (int)$hi['count'] ?></span><?php endif; ?>
163 </div>
164 <?php endforeach; ?>
165 </div>
166 <div class="auc2-col-data">
167 <div><span class="auc2-label"><?= t_default('auc.start', 'Auction Start:') ?></span> <?= h(getClock($character['time_begin'], true)) ?></div>
168 <div><span class="auc2-label"><?= t_default('auc.end', 'Auction End:') ?></span> <?= h(getClock($character['time_end'], true)) ?></div>
169 <div>
170 <?php $ended = (time() > $character['time_end']); ?>
171 <span class="auc2-label"><?= t_default('auc.type_label', 'Type:') ?></span>
172 <?php if ($ended): ?>
173 <?= t_default('auc.instant', 'Instant') ?>
174 <?php else: ?>
175 <?= t_default('auc.bidding', 'Bidding') ?> (<span data-auc2-countdown="<?= (int)$character['time_end'] ?>" data-auc2-ended-text="<?= h(t_default('auc.instant', 'Instant')) ?>"><?= h(toDuration($character['time_end'] - time())) ?></span>)
176 <?php endif; ?>
177 </div>
178 <div><span class="auc2-label"><?= t_default('auc.min_bid', 'Minimum Bid:') ?></span> <span class="auc2-amount"><?= (int)$character['price'] ?><img class="auc2-coin" src="<?= theme_asset('icon-tibiacoin.png') ?>" alt=""></span></div>
179 </div>
180 <div class="auc2-col-bid">
181 <form action="/auctionChar.php" method="POST">
182 <input type="hidden" name="action" value="bid">
183 <input type="hidden" name="zaid" value="<?= (int)$character['zaid'] ?>">
184 <label><?= t_default('auc.my_bid_limit', 'My Bid Limit') ?></label>
185 <input type="number" name="price" min="<?= (int)$character['price'] ?>" step="1" value="<?= (int)$character['price'] ?>">
186 <input type="submit" value="<?= t('auc.bid_btn') ?>">
187 </form>
188 </div>
189 </div>
190 </article>
191 <?php endforeach; ?>
192
193 <?php if ($pageCount > 1): ?>
194 <div class="auc2-pagination">
195 <?php for ($p = 1; $p <= $pageCount; $p++): ?>
196 <?php if ($p === $page): ?>
197 <span class="is-current"><?= $p ?></span>
198 <?php else: ?>
199 <a href="<?= h(auc2_url(['page' => $p])) ?>"><?= $p ?></a>
200 <?php endif; ?>
201 <?php endfor; ?>
202 </div>
203 <?php endif; ?>
204<?php else: ?>
205 <p><?= t_default('auc.no_auctions', 'No characters are currently up for auction.') ?></p>
206<?php endif; ?>
207
208<p><a href="/auctionChar.php?action=create"><?= t('auc.add') ?></a>.</p>
209
210<script>
211document.addEventListener('DOMContentLoaded', function () {
212 // Auction timers tick down live client-side instead of only updating on
213 // the next full page reload.
214 document.querySelectorAll('[data-auc2-countdown]').forEach(function (el) {
215 var end = parseInt(el.getAttribute('data-auc2-countdown'), 10);
216 function tick() {
217 var remaining = end - Math.floor(Date.now() / 1000);
218 if (remaining <= 0) {
219 el.textContent = el.getAttribute('data-auc2-ended-text') || '';
220 return;
221 }
222 var d = Math.floor(remaining / 86400);
223 var h = Math.floor((remaining % 86400) / 3600);
224 var m = Math.floor((remaining % 3600) / 60);
225 var s = remaining % 60;
226 var parts = [];
227 if (d > 0) parts.push(d + (d === 1 ? ' day' : ' days'));
228 if (d > 0 || h > 0) parts.push(h + (h === 1 ? ' hour' : ' hours'));
229 if (m > 0) parts.push(m + (m === 1 ? ' minute' : ' minutes'));
230 if (s > 0) parts.push(s + (s === 1 ? ' second' : ' seconds'));
231 el.textContent = parts.join(', ');
232 setTimeout(tick, 1000);
233 }
234 tick();
235 });
236});
237</script>
238
Top