4242 :title =" githubActionTitle"
4343 @click =" canLinkGitHub && startGitHubWalletLink()"
4444 >
45- <GitPullRequest :size =" 16 " />
45+ <GitPullRequest :size =" 17 " />
4646 <span >
4747 <small >GitHub</small >
4848 <strong >{{ githubAccountLabel }}</strong >
4949 </span >
5050 </button >
51+ <button
52+ v-if =" githubLinked"
53+ class =" icon-mini github-copy-button"
54+ type =" button"
55+ title =" Copy GitHub account"
56+ @click =" copyValue(githubAccountLabel)"
57+ >
58+ <Copy :size =" 15" />
59+ </button >
5160 </div >
5261 <button
5362 :class =" ['api-nav-link', route.name === 'api' ? 'active' : '']"
5463 type =" button"
5564 title =" Open API docs"
5665 @click =" openApiDocs"
5766 >
58- <FileJson :size =" 17 " />
67+ <Braces :size =" 18 " />
5968 <span >API</span >
6069 </button >
6170 <button class =" icon-button" type =" button" title =" Refresh" @click =" loadExplorerData" >
172181 </div >
173182
174183 <TransactionTable
175- :entries =" visibleEntries "
184+ :entries =" displayedEntries "
176185 :token-symbol =" tokenSymbol"
177186 @go-tx =" openTx"
178187 @go-block =" openBlock"
179188 @go-address =" openAddress"
180189 />
190+ <div v-if =" hasMoreTransactions || showAllTransactions" class =" table-more" >
191+ <button type =" button" @click =" showAllTransactions = !showAllTransactions" >
192+ {{ showAllTransactions ? 'Show fewer transactions' : 'View more transactions ->' }}
193+ </button >
194+ </div >
181195 </div >
182196
183197 <aside class =" side-rail" >
209223 </dl >
210224 </section >
211225
212- <section class =" rail-panel" >
226+ <section class =" rail-panel about-panel " >
213227 <div class =" panel-head compact" >
214228 <div >
215- <p >Hash Chain</p >
216- <h2 >Verification</h2 >
229+ <p >About MergeOS</p >
217230 </div >
218- <span :class =" ['pill', chain.ok ? 'good' : 'bad']" >{{ chain.ok ? 'Valid' : 'Check' }}</span >
219231 </div >
220- <div class =" chain-proof" >
221- <ShieldCheck :size =" 28" />
222- <strong >{{ chain.ok ? 'All links match' : `${chain.issues.length} issues found` }}</strong >
223- <small >{{ shortHash(chain.latestHash, 12, 10) }}</small >
224- </div >
225- </section >
226-
227- <section class =" rail-panel" >
228- <div class =" panel-head compact" >
229- <div >
230- <p >Addresses</p >
231- <h2 >Top accounts</h2 >
232- </div >
233- </div >
234- <div class =" account-list" >
235- <button v-for =" account in topAccounts" :key =" account.account" type =" button" @click =" openAddress(account.account)" >
236- <span >
237- <strong >{{ shortHash(account.account, 16, 8) }}</strong >
238- <small >{{ accountRole(account.account) }}</small >
239- </span >
240- <b >{{ account.tx_count }}</b >
241- </button >
232+ <div class =" about-copy" >
233+ <span class =" about-icon" aria-hidden =" true" >
234+ <Keyboard :size =" 42" />
235+ </span >
236+ <p >MergeOS is a decentralized ledger system for verifying contributions and rewarding real work onchain.</p >
242237 </div >
243238 </section >
244239 </aside >
258253<script setup>
259254import { computed , defineAsyncComponent , defineComponent , h , onBeforeUnmount , onMounted , ref } from ' vue' ;
260255import {
261- Activity ,
262256 AlertTriangle ,
263257 ArrowDownLeft ,
264258 ArrowUpRight ,
265- Blocks ,
266- CheckCircle2 ,
259+ Braces ,
260+ Coins ,
267261 Copy ,
268262 ExternalLink ,
269- FileJson ,
263+ FileText ,
270264 Fingerprint ,
271265 GitPullRequest ,
266+ Keyboard ,
272267 LoaderCircle ,
273268 RefreshCw ,
274269 RotateCcw ,
275270 Search ,
276271 ShieldCheck ,
272+ Trophy ,
277273 WalletCards ,
278274} from ' @lucide/vue' ;
279275import {
@@ -293,7 +289,6 @@ import {
293289 shortHash ,
294290 sortLedgerEntries ,
295291 tokenAmountFromCents ,
296- verifyLedgerChain ,
297292} from ' ./explorer.js' ;
298293
299294const ApiDocs = defineAsyncComponent (() => import (' ./ApiDocs.vue' ));
@@ -316,6 +311,7 @@ const lastSyncAt = ref(null);
316311const searchInput = ref (' ' );
317312const queryFilter = ref (' ' );
318313const typeFilter = ref (' all' );
314+ const showAllTransactions = ref (false );
319315const route = ref (parseRoute ());
320316
321317const tokenSymbol = computed (() => config .value ? .token_symbol || marketplace .value ? .stats ? .token_symbol || ' MRG' );
@@ -337,11 +333,11 @@ const githubActionTitle = computed(() => {
337333const entries = computed (() => sortLedgerEntries (rawEntries .value ));
338334const newestEntries = computed (() => entries .value .slice ().reverse ());
339335const accounts = computed (() => aggregateAccounts (entries .value ));
340- const chain = computed (() => verifyLedgerChain (entries .value ));
341336const stats = computed (() => buildExplorerStats (entries .value , marketplace .value , tokenSymbol .value ));
342337const ledgerTypes = computed (() => Array .from (new Set (entries .value .map ((entry ) => entry .type ))).sort ());
343338const visibleEntries = computed (() => filterEntries (newestEntries .value , { query: queryFilter .value , type: typeFilter .value }));
344- const topAccounts = computed (() => accounts .value .slice (0 , 6 ));
339+ const displayedEntries = computed (() => (showAllTransactions .value ? visibleEntries .value : visibleEntries .value .slice (0 , 5 )));
340+ const hasMoreTransactions = computed (() => visibleEntries .value .length > displayedEntries .value .length );
345341const lastSyncLabel = computed (() => {
346342 if (! lastSyncAt .value ) return ' pending' ;
347343 return lastSyncAt .value .toLocaleTimeString (' en-US' , { hour: ' 2-digit' , minute: ' 2-digit' , second: ' 2-digit' });
@@ -367,10 +363,10 @@ const selectedBlockEntry = computed(() => {
367363 return entries .value .find ((entry ) => entry .sequence === sequence);
368364});
369365const statCards = computed (() => [
370- { label: ' Ledger Entries' , value: formatCompact (stats .value .totalTransactions ), icon: Activity , tone: ' blue ' },
371- { label: ' MRG Minted' , value: ` ${ formatCompact (stats .value .mintedTokens )} ${ tokenSymbol .value } ` , icon: WalletCards , tone: ' green' },
372- { label: ' Verified Funding' , value: formatLedgerAmount (stats .value .fundingCents ), icon: CheckCircle2 , tone: ' teal ' },
373- { label: ' Ledger Height' , value: ` #${ formatCompact (stats .value .chainHeight )} ` , icon: Blocks , tone: ' amber ' },
366+ { label: ' Ledger Entries' , value: formatCompact (stats .value .totalTransactions ), icon: FileText , tone: ' green ' },
367+ { label: ' MRG Minted' , value: ` ${ formatCompact (stats .value .mintedTokens )} ${ tokenSymbol .value } ` , icon: Coins , tone: ' green' },
368+ { label: ' Verified Funding' , value: formatLedgerAmount (stats .value .fundingCents ), icon: ShieldCheck , tone: ' green ' },
369+ { label: ' Ledger Height' , value: ` #${ formatCompact (stats .value .chainHeight )} ` , icon: Trophy , tone: ' gold ' },
374370]);
375371
376372onMounted (() => {
@@ -621,6 +617,7 @@ function normalizeMarketplace(payload = {}) {
621617function submitSearch () {
622618 const query = searchInput .value .trim ();
623619 queryFilter .value = query;
620+ showAllTransactions .value = false ;
624621 if (! query) {
625622 goHome ();
626623 return ;
@@ -640,6 +637,7 @@ function resetFilters() {
640637 searchInput .value = ' ' ;
641638 queryFilter .value = ' ' ;
642639 typeFilter .value = ' all' ;
640+ showAllTransactions .value = false ;
643641}
644642
645643function openTx (hash ) {
0 commit comments