PHP WebShell

Текущая директория: /var/www/bitcardoApp/user/dashboard

Просмотр файла: index.php

<?php 
//user/dashboard/index.php
include '../common/header.php';
include '../../models/dashboard/index.php';
include_once '../../models/crypto/create_address_helper.php';
include_once '../../models/crypto/create_btc_user_address.php';
include_once '../../models/crypto/create_sol_user_address.php';
include_once '../../models/crypto/create_tron_wallet.php';
include '../../models/dashboard/wallets.php';
?>
<style>
   .bc-actionbar-wrap{ width:100%; }
    .bc-actionbar{
    display:flex;
    flex-wrap:wrap;
    gap:14px;
    align-items:center;
    }

    /* Default (desktop/tablet): 4 on a row */
    .bc-actionbtn{
    min-width: 100px;  /* keeps them stable on most desktops */
    display:flex;
    align-items:center;
    justify-content:center;
    gap:10px;
    height:54px;
    padding:0 18px;
    border-radius:14px;
    text-decoration:none;
    color:#fff;
    font-weight:800;
    letter-spacing:.2px;

    /* very little shadow */
    box-shadow: 0 2px 6px rgba(0,0,0,.10);

    border: 1px solid rgba(255,255,255,.22);
    position:relative;
    overflow:hidden;
    user-select:none;
    }

    .bc-actionbtn:active{ transform: translateY(1px); }
    .bc-actionbtn:hover{ color:#fff; filter: brightness(1.01); }

    .bc-ico{
    width:34px;
    height:34px;
    border-radius:10px;
    display:grid;
    place-items:center;
    background: rgba(255,255,255,.16);
    border: 1px solid rgba(255,255,255,.18);
    backdrop-filter: blur(4px);
    }

    .bc-text{ font-size:16px; line-height:1; }

    /* subtle sheen band */
    .bc-actionbtn::after{
    content:"";
    position:absolute;
    inset:-40% -20%;
    background: linear-gradient(115deg,
        rgba(255,255,255,0) 20%,
        rgba(255,255,255,.10) 38%,
        rgba(255,255,255,0) 55%);
    transform: rotate(10deg);
    pointer-events:none;
    opacity:.55;
    }

    /* Mobile: 2 per row */
    @media (max-width: 576px){
    .bc-actionbar{ gap:10px; }
    .bc-actionbtn{
        flex: 0 0 calc(50% - 5px);
        min-width: 0;
        height:50px;
        padding:0 12px;
        border-radius:14px;
    }
    .bc-text{ font-size:14px; }
    .bc-ico{ width:32px; height:32px; border-radius:10px; }
    }


    /* BUY: slightly more vibrant than #248ee2 */
    /* BUY: main color #0473aa (less white sheen, more color presence) */
    .bc-buy{
    background:
        radial-gradient(120px 80px at 18% 20%,
        rgba(255,255,255,.18) 0%,
        rgba(255,255,255,.07) 38%,
        rgba(255,255,255,0) 72%),
        linear-gradient(135deg, rgba(255,255,255,.06) 0%, rgba(255,255,255,0) 60%),
        linear-gradient(135deg,
        #0a8ac7 0%,
        #0473aa 52%,
        #035b88 100%);
    }

    /* SELL: main color #de1342 */
    .bc-sell{
    background:
        radial-gradient(140px 90px at 78% 35%,
        rgba(255,255,255,.16) 0%,
        rgba(255,255,255,.06) 40%,
        rgba(255,255,255,0) 74%),
        linear-gradient(135deg, rgba(255,255,255,.06) 0%, rgba(255,255,255,0) 60%),
        linear-gradient(135deg,
        #ff2a5b 0%,
        #de1342 52%,
        #b80f36 100%);
    }

    /* BUY GIFTCARD: main color #f3a117 */
    .bc-gc-buy{
    background:
        radial-gradient(160px 100px at 22% 45%,
        rgba(255,255,255,.18) 0%,
        rgba(255,255,255,.07) 40%,
        rgba(255,255,255,0) 78%),
        radial-gradient(220px 140px at 85% 25%,
        rgba(255,255,255,.08) 0%,
        rgba(255,255,255,0) 62%),
        linear-gradient(135deg,
        #ffbe3a 0%,
        #f3a117 52%,
        #cf8208 100%);
    }

    /* SELL GIFTCARD: main color #00a4e1 */
    .bc-gc-sell{
    background:
        radial-gradient(170px 105px at 78% 22%,
        rgba(255,255,255,.16) 0%,
        rgba(255,255,255,.06) 42%,
        rgba(255,255,255,0) 80%),
        radial-gradient(240px 150px at 18% 85%,
        rgba(255,255,255,.07) 0%,
        rgba(255,255,255,0) 64%),
        linear-gradient(135deg,
        #27c6ff 0%,
        #00a4e1 52%,
        #007bb3 100%);
    }

    .owl-carousel .item a:hover .card{
    box-shadow: 0 6px 18px rgba(0,0,0,.08);
    transform: translateY(-1px);
    transition: all .15s ease;
    }
    .owl-carousel .item a .card{
    transition: all .15s ease;
    }

    /* Balance toggle button */
    #toggleBalancesBtn{
      display:inline;
      width:40px;
      height:32px;
    }

    .bc-wallet-actions{
        background: linear-gradient(90deg, #0473aa 0%, #f3a117 90%);
        border-radius: 16px;
        padding: 12px 12px;
        display: inline-flex;
        flex-wrap: wrap;
        gap: 10px;
        align-items: center;
        box-shadow: 0 2px 8px rgba(0,0,0,.08);
        border: 1px solid rgba(255,255,255,.22);
    }
</style>
<!-- Main Container -->
<div class="container mt-3">
  <div class="row">

    <?php include '../common/nav.php'; ?>
   
    <main class="col-md-9 col-lg-10 px-md-5 mb-5">
        
        <?php include '../common/page-header.php'; ?>

        <?php if (!empty($_SESSION['flash_success'])): ?>
        <div class="alert alert-success text-break">
            <?= htmlspecialchars($_SESSION['flash_success']) ?>
        </div>
        <?php unset($_SESSION['flash_success']); ?>
        <?php endif; ?>


        <?php if (!empty($_SESSION['flash_error'])): ?>
        <div class="alert alert-danger text-break">
            <?= htmlspecialchars($_SESSION['flash_error']) ?>
        </div>
        <?php unset($_SESSION['flash_error']); ?>
        <?php endif; ?>


        <!-- WALLETS CARD-->
        <section class="px-md-5">
            <!-- Available balance header + right toggle -->
            <div class="d-flex align-items-center justify-content-between">
                <h6 class="mb-0">&nbsp;Available Balance</h6>
            </div>
            
            <div class="py-3">
                <div class="mb-2 ms-1">
                    <span class="fs-4 fw-bold" id="totalNgnText">
                        ₦<?= number_format($totalNgn, 2); ?>
                    </span> &nbsp; | &nbsp;  
                    <span class="fs-4 fw-bold" id="totalUsdText">
                        $<?= number_format($totalUsd, 2); ?>
                    </span>
                    &nbsp;
                    <button type="button"
                            id="toggleBalancesBtn"
                            class="btn btn-light btn-sm rounded-5 border text-dark"
                            aria-pressed="false"
                            title="Hide balances">
                        <i class="bi bi-eye"></i>
                    </button>
                </div>
                <?php if (!empty($wallets)) : ?>
                <div class="align-content-start">
                
                    <!-- Deposit Dropdown -->
                    <div class="btn-group me-1">
                        <button type="button" class="btn btn-primary btn-sm rounded-5 px-3 dropdown-toggle" data-bs-toggle="dropdown" aria-expanded="false">
                            Deposit
                        </button>
                        <ul class="dropdown-menu">
                            <?php foreach ($wallets as $coin => $wallet): ?>
                            <li>
                                <a class="dropdown-item d-flex align-items-center" href="../wallets/single-wallet.php?ussgwt=<?php echo $wallet['wallet_id']; ?>&coin=<?php echo $wallet['coin']; ?>">
                                <span><?php echo htmlspecialchars($wallet['label'] ?: $coin); ?></span>
                                </a>
                            </li>
                            <?php endforeach; ?>
                        </ul>
                    </div>

                    <!-- Transfer Dropdown -->
                    <div class="btn-group me-1">
                        <button type="button" class="btn btn-outline-secondary btn-sm rounded-5 px-3 dropdown-toggle my-1" data-bs-toggle="dropdown" aria-expanded="false">
                            Withdraw
                        </button>
                        <ul class="dropdown-menu">
                        <?php foreach ($wallets as $coin => $wallet): 
                            // Decide link based on wallet type
                            $link = ($wallet['type'] === 'fiat') 
                                ? "../fiat/send_fiat.php?wallet_id=" . urlencode($wallet['wallet_id']) 
                                : "../crypto/send_crypto.php?coin=" . urlencode($wallet['coin']);
                        ?>
                            <li>
                                <a class="dropdown-item d-flex align-items-center" href="<?php echo $link; ?>">
                                    <span><?php echo htmlspecialchars($wallet['label'] ?: $wallet['coin']); ?></span>
                                </a>
                            </li>
                        <?php endforeach; ?>
                        </ul>
                    </div>

                    <?php if (!empty($walletOptions)): ?>
                    <form method="post" class="d-inline">
                        <div class="btn-group">
                            <button type="button" class="btn btn-primary rounded-5 dropdown-toggle py-1 my-1" data-bs-toggle="dropdown" aria-expanded="false">
                                Create Wallet
                            </button>
                            <ul class="dropdown-menu">
                                <?php foreach ($walletOptions as $symbol => $opt): ?>
                                <li>
                                    <button type="submit"
                                            class="dropdown-item"
                                            id="<?php echo htmlspecialchars($symbol); ?>"
                                            name="<?php echo htmlspecialchars($opt['name']); ?>"
                                            value="1">
                                        <?php echo htmlspecialchars($opt['label']); ?>
                                    </button>
                                </li>
                                <?php endforeach; ?>
                            </ul>
                        </div>
                    </form>
                    <?php endif; ?>

                </div>
                <?php endif; ?>
                 
            </div>

            <!-- Owl Carousel -->
            <div class="owl-carousel owl-theme">

                <!-- Card -->
                <?php foreach ($wallets as $wallet) { 
                    $coin = strtoupper($wallet['coin']);

                    // Single wallet URL (same as your Deposit dropdown)
                    $walletUrl = "../wallets/single-wallet.php?ussgwt=" . urlencode($wallet['wallet_id'])
                            . "&coin=" . urlencode($wallet['coin']);
                ?>
                <div class="item shadow-sm">

                    <a href="<?= htmlspecialchars($walletUrl) ?>"
                    class="text-decoration-none text-dark d-block"
                    style="outline: none;">

                        <div class="card rounded-1 bg-white">
                            <!-- Card Header with icon and coin text aligned to the left -->
                            <div class="card-header bg-white d-flex d-flex">
                                <img src="../../assets/icons/<?= htmlspecialchars($wallet['icon']) ?>" class="bg-white flag" />
                                <div class="ngn-text"><?= htmlspecialchars($wallet['coin']); ?></div>
                            </div>

                            <!-- Card Body -->
                            <div class="card-body">
                                <!-- Wallet Info -->
                                <div class="wallet-info">
                                    <i class="fas fa-wallet"></i>
                                    <span>
                                        <?= '...' . htmlspecialchars(substr($wallet['wallet_add'], -10)); ?>
                                    </span>
                                </div>

                                <!-- Primary Amount -->
                                <div class="amount text-end" style="line-height:1.2;" data-coin-primary="<?= htmlspecialchars($coin) ?>">
                                    <?php if ($coin === 'NGN'): ?>
                                        ₦<?= number_format((float)$wallet['balance'], 2, '.', ','); ?>
                                    <?php elseif (!empty($wallet['usd_equiv'])): ?>
                                        $<?= number_format((float)$wallet['usd_equiv'], 2, '.', ','); ?>
                                    <?php endif; ?>
                                </div>

                                <!-- Raw Amount -->
                                <div class="text-muted text-end" style="font-size:14px; margin-top:-5px;" data-coin-raw="<?= htmlspecialchars($coin) ?>">
                                    <?php if ($coin === 'NGN'): ?>
                                        ₦<?= number_format((float)$wallet['balance'], 2, '.', ','); ?>
                                    <?php else: ?>
                                        <?= fmt_coin_amount($wallet['balance'], $wallet['coin']); ?>
                                    <?php endif; ?>
                                </div>
                            </div>
                        </div>

                    </a>

                </div>
                <?php } ?>


            </div>
            <!-- Owl Carousel -->

        </section>

        <section class="pt-1 container">
            <!-- Buy / Sell / Giftcards buttons (no Swap) -->
            <div class="bc-actionbar-wrap mt-3 px-1 px-md-5">
                <div class="row">
                    
                    <div class="col-6 col-md-3 mb-3">
                        <a href="../crypto/buy.php" class="bc-actionbtn bc-buy" role="button">
                        <span class="bc-ico" aria-hidden="true">
                            <!-- up-right arrow -->
                            <svg viewBox="0 0 24 24" width="22" height="22" fill="none">
                            <path d="M7 17L17 7" stroke="white" stroke-width="2.6" stroke-linecap="round"/>
                            <path d="M10 7H17V14" stroke="white" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"/>
                            </svg>
                        </span>
                        <span class="bc-text">Buy Crypto</span>
                        </a>
                    </div>
                    
                    <div class="col-6 col-md-3 mb-3">
                        <a href="../crypto/sell.php" class="bc-actionbtn bc-sell" role="button">
                        <span class="bc-ico" aria-hidden="true">
                            <!-- down arrow -->
                            <svg viewBox="0 0 24 24" width="22" height="22" fill="none">
                            <path d="M12 5V19" stroke="white" stroke-width="2.6" stroke-linecap="round"/>
                            <path d="M7.5 14.5L12 19l4.5-4.5" stroke="white" stroke-width="2.6" stroke-linecap="round" stroke-linejoin="round"/>
                            </svg>
                        </span>
                        <span class="bc-text">Sell Crypto</span>
                        </a>
                    </div>

                    <div class="col-6 col-md-3 mb-3">
                        <a href="../giftcards/buy_giftcard.php" class="bc-actionbtn bc-gc-buy" role="button">
                        <span class="bc-ico" aria-hidden="true">
                            <!-- gift icon -->
                            <svg viewBox="0 0 24 24" width="22" height="22" fill="none">
                            <path d="M20 12v8a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-8" stroke="white" stroke-width="2.4" stroke-linecap="round"/>
                            <path d="M2 8h20v4H2z" stroke="white" stroke-width="2.4" stroke-linejoin="round"/>
                            <path d="M12 8v14" stroke="white" stroke-width="2.4" stroke-linecap="round"/>
                            <path d="M12 8H8.5a2.5 2.5 0 1 1 0-5c2 0 3.2 2.2 3.5 5Z" stroke="white" stroke-width="2.4" stroke-linejoin="round"/>
                            <path d="M12 8h3.5a2.5 2.5 0 1 0 0-5c-2 0-3.2 2.2-3.5 5Z" stroke="white" stroke-width="2.4" stroke-linejoin="round"/>
                            </svg>
                        </span>
                        <span class="bc-text">Buy Giftcard</span>
                        </a>
                    </div>

                    <div class="col-6 col-md-3 mb-3">
                        <a href="../giftcards/submit_card.php" class="bc-actionbtn bc-gc-sell" role="button">
                        <span class="bc-ico" aria-hidden="true">
                            <!-- tag icon -->
                            <svg viewBox="0 0 24 24" width="22" height="22" fill="none">
                            <path d="M20 13l-7 7a2 2 0 0 1-2.83 0L3 12.83V3h9.83L20 10.17a2 2 0 0 1 0 2.83Z" stroke="white" stroke-width="2.4" stroke-linejoin="round"/>
                            <path d="M7.5 7.5h.01" stroke="white" stroke-width="4" stroke-linecap="round"/>
                            </svg>
                        </span>
                        <span class="bc-text">Sell Giftcard</span>
                        </a>
                    </div>

                </div>
            </div>


        </section>

        <!-- EXCHANGE -->
        <section class="px-md-5 mt-1" id="">
            
            <div class="bg-white currency-box  p-4 shadow-none border-0 row">
                <div class="col-md-6 d-none d-md-block">
                    <h5 class="mb-3">Market Watch</h5>
                    <ul class="nav nav-tabs" id="cryptoTabs" role="tablist">
                        <li class="nav-item" role="presentation">
                        <button class="nav-link active text-dark" id="btc-tab" data-bs-toggle="tab" data-bs-target="#btc" type="button" role="tab" aria-controls="btc" aria-selected="true">BTC</button>
                        </li>
                        <!-- <li class="nav-item" role="presentation">
                        <button class="nav-link text-dark" id="eth-tab" data-bs-toggle="tab" data-bs-target="#eth" type="button" role="tab" aria-controls="eth" aria-selected="false">ETH</button>
                        </li> -->
                        <li class="nav-item" role="presentation">
                        <button class="nav-link text-dark" id="sol-tab" data-bs-toggle="tab" data-bs-target="#sol" type="button" role="tab" aria-controls="sol" aria-selected="false">SOL</button>
                        </li>
                        <li class="nav-item" role="presentation">
                        <button class="nav-link text-dark" id="trx-tab" data-bs-toggle="tab" data-bs-target="#trx" type="button" role="tab" aria-controls="trx" aria-selected="false">TRX</button>
                        </li>
                    </ul>

                    <div class="tab-content">
                        <div class="tab-pane fade show active" id="btc" role="tabpanel" aria-labelledby="btc-tab">
                            <div id="tradingview_btcusdt"></div>
                        </div>
                        <div class="tab-pane fade" id="eth" role="tabpanel" aria-labelledby="eth-tab">
                            <div id="tradingview_ethusdt"></div>
                        </div>
                        <div class="tab-pane fade" id="sol" role="tabpanel" aria-labelledby="sol-tab">
                            <div id="tradingview_solusdt"></div>
                        </div>
                        <div class="tab-pane fade" id="trx" role="tabpanel" aria-labelledby="trx-tab">
                            <div id="tradingview_trxusdt"></div>
                        </div>
                    </div>
                </div>
                <div id="convert" class="d-md-none" style="height: 50px"></div>
                <div class="col-md-6" id="">
                    <h5 class="mb-3">Asset Swap</h5>
                    <div class="currency-box bg-white border shadow-sm">
                        <?php include '../crypto/swap.php'; ?>
                    </div>
                </div>
            </div>

            <div>
                <a class="" href="https://wallet.bitcardo.com/chat/sso/">
                    <img src="../../assets/images/crypto-banner.png" class="w-100" alt="">
                </a>
            </div>

            <div class="d-flex align-items-center mb-4 justify-content-center mt-4">
                <a href="../security/notifications.php" class="btn btn-outline-primary rounded-5 text-decoration-none">
                <span class="me-2"><i class="bi bi-bell"></i></span>
                <span class="fw-bold">Get exchange rate updates</span>
                </a>
            </div>

        </section>
        
        <!-- TRANSACTIONS -->
        <section class="px-md-4 mt-5">
            <div class="bg-white p-4 currency-box shadow-none border-0">
                <div class="d-flex justify-content-between align-items-center mb-3">
                    <h5 class="mb-0">Transactions</h5>
                    <a href="../data/transactions.php" class="text-decoration-none text-primary fw-semibold">See all</a>
                </div>
                <?php if (empty($recent_transactions)): ?>
                    <div class="text-center text-muted py-4">No recent transactions</div>
                <?php else: ?>
                    <?php foreach ($recent_transactions as $t):
                        $coin = htmlspecialchars($t['coin']);
                        $amount_val = ($coin === 'NGN')
                            ? number_format((float)$t['amount'], 2, '.', '')
                            : fmt_coin_amount($t['amount'], $coin);
                        $amount = $amount_val . ' ' . $coin;

                        $type = $t['type']; // send, receive, swap, deposit, withdrawal
                        $amountShow = $amount;
                        $amountClass = 'text-secondary';
                        $icon = '<i class="bi bi-question-circle"></i>';
                        $counterparty = '';

                        switch ($type) {
                            case 'send':
                                $amountShow = '-' . $amount;
                                $amountClass = 'text-danger';
                                $icon = '<i class="text-danger bi bi-box-arrow-in-up-right"></i>';
                                $counterparty = trim($t['receiver_first'] . ' ' . $t['receiver_last'])
                                    ?: truncate_left($t['receiver_address']);
                                break;

                            case 'receive':
                                $amountShow = '+' . $amount;
                                $amountClass = 'text-success';
                                $icon = '<i class="text-success bi bi-box-arrow-in-down-right"></i>';
                                $counterparty = trim($t['sender_first'] . ' ' . $t['sender_last'])
                                    ?: truncate_left($t['sender_address']);
                                break;

                            case 'swap':
                                $amountClass = 'text-info';
                                $icon = '<i class="text-info bi bi-shuffle"></i>';
                                $address = $t['receiver_address'] ?: $t['sender_address'];
                                $counterparty = truncate_left($address, 15);
                                break;

                            case 'deposit':
                                $amountShow = '+' . $amount;
                                $amountClass = 'text-success';
                                $icon = '<i class="text-success bi bi-box-arrow-in-down-right"></i>';
                                $counterparty = 'Deposit Wallet';
                                break;

                            case 'withdrawal':
                                $amountShow = '-' . $amount;
                                $amountClass = 'text-danger';
                                $icon = '<i class="text-danger bi bi-box-arrow-in-up-right"></i>';
                                $counterparty = 'Withdrawal Wallet';
                                break;

                            case 'buy':
                                $amountShow  = '+' . $amount;
                                $amountClass = 'text-success';
                                $icon        = '<i class="text-success bi bi-bag-check"></i>';
                                $counterparty = 'Buy Crypto';
                                break;
                                

                            case 'fee':
                                $isDebit = ((int)$t['sender_uid'] === (int)$user_id);
                                if ($isDebit) {
                                    $amountShow = '-' . $amount;
                                    $amountClass = 'text-danger';
                                    $icon = '<i class="text-warning bi bi-receipt"></i>';
                                    $counterparty = 'Fee';
                                } else {
                                    $amountShow = '+' . $amount;
                                    $amountClass = 'text-success';
                                    $icon = '<i class="text-success bi bi-receipt"></i>';
                                    $counterparty = 'Fee Rebate';
                                }
                                break;
                            
                            case 'giftcard_payout':
                                $amountShow = '+' . $amount;
                                $amountClass = 'text-success';
                                $icon = '<i class="text-success bi bi-gift"></i>';
                                $counterparty = 'Giftcard Payout';
                                break;
                        }

                        $typeText = match ($type) {
                            'giftcard_payout' => 'Giftcard Payout',
                            'buy'             => 'Buy Crypto',
                            default           => ucfirst($type),
                        };
                        $dateText = date('D, M j', strtotime($t['created_at']));
                    ?>
                    <a href="../data/transaction_detail.php?id=<?= $t['trans_id'] ?>" class="text-decoration-none text-dark">
                        <div class="transaction-item d-flex justify-content-between align-items-center py-2 border-0 border-bottom">
                            <div class="d-flex align-items-start gap-3">
                                <div class="transaction-icon">
                                    <?= $icon ?>
                                </div>
                                <div>
                                    <div class="fw-semibold"><?= htmlspecialchars($counterparty) ?></div>
                                    <small class="text-muted"><?= $typeText ?> &middot; <?= $dateText ?></small>
                                </div>
                            </div>
                            <?php
                            $coinText = $coin;
                            $amountOnly = trim(str_ireplace($coinText, '', $amountShow)); // keeps + / - sign
                            ?>
                            <div class="text-end">
                                <div class="amount-lg <?= $amountClass ?>"><?= htmlspecialchars($amountOnly) ?></div>
                                <div class="small text-muted lh-1"><?= htmlspecialchars($coinText) ?></div>
                            </div>

                        </div>
                    </a>
                    <?php endforeach; ?>
                <?php endif; ?>
            </div>
        </section>

    </main>
  </div>
</div>

<?php include '../common/footer.php'; ?>
<script type="text/javascript" src="https://s3.tradingview.com/tv.js"></script>

<script type="text/javascript">
    new TradingView.widget({
    "container_id": "tradingview_btcusdt",
    "symbol": "BINANCE:BTCUSDT",
    "interval": "H",
    "width": "100%",
    "height": 330,
    "theme": "light",
    "style": "1",
    "locale": "en",
    "toolbar_bg": "#f1f3f6",
    "enable_publishing": false,
    "hide_top_toolbar": false,
    "save_image": false,
    "studies": [],
    "withdateranges": true
    });

    new TradingView.widget({
    "container_id": "tradingview_ethusdt",
    "symbol": "BINANCE:ETHUSDT",
    "interval": "H",
    "width": "100%",
    "height": 330,
    "theme": "light",
    "style": "1",
    "locale": "en",
    "toolbar_bg": "#f1f3f6",
    "enable_publishing": false,
    "hide_top_toolbar": false,
    "save_image": false,
    "studies": [],
    "withdateranges": true
    });

    new TradingView.widget({
    "container_id": "tradingview_solusdt",
    "symbol": "BINANCE:SOLUSDT",
    "interval": "H",
    "width": "100%",
    "height": 330,
    "theme": "light",
    "style": "1",
    "locale": "en",
    "toolbar_bg": "#f1f3f6",
    "enable_publishing": false,
    "hide_top_toolbar": false,
    "save_image": false,
    "studies": [],
    "withdateranges": true
    });

    new TradingView.widget({
    "container_id": "tradingview_trxusdt",
    "symbol": "BINANCE:TRXUSDT",
    "interval": "H",
    "width": "100%",
    "height": 330,
    "theme": "light",
    "style": "1",
    "locale": "en",
    "toolbar_bg": "#f1f3f6",
    "enable_publishing": false,
    "hide_top_toolbar": false,
    "save_image": false,
    "studies": [],
    "withdateranges": true
    });
</script>

<!-- Live wallet balance updates (no refresh) + chime on change (single poller only) -->
<script>
(function () {

  // ---------------------------
  // BALANCE HIDE/SHOW (persisted)
  // ---------------------------
  const BAL_MASK_KEY = "bc_hide_balances";

  function isHidden() {
    return localStorage.getItem(BAL_MASK_KEY) === "1";
  }
  function setHidden(val) {
    localStorage.setItem(BAL_MASK_KEY, val ? "1" : "0");
  }
  function maskValue(real) {
    if (!real) return "••••";
    const s = String(real).trim();
    const first = s.charAt(0);
    if (first === "₦" || first === "$") return first + "••••";
    return "••••";
  }

  function applyBalanceMask() {
    const hidden = isHidden();

    // totals
    const tn = document.getElementById("totalNgnText");
    const tu = document.getElementById("totalUsdText");

    if (tn) {
      if (!tn.dataset.real) tn.dataset.real = tn.textContent;
      tn.textContent = hidden ? maskValue(tn.dataset.real) : tn.dataset.real;
    }
    if (tu) {
      if (!tu.dataset.real) tu.dataset.real = tu.textContent;
      tu.textContent = hidden ? maskValue(tu.dataset.real) : tu.dataset.real;
    }

    // wallet amounts (primary + raw)
    document.querySelectorAll("[data-coin-primary], [data-coin-raw]").forEach((el) => {
      if (!el.dataset.real) el.dataset.real = el.textContent;
      el.textContent = hidden ? maskValue(el.dataset.real) : el.dataset.real;
    });

    // button UI
    const btn = document.getElementById("toggleBalancesBtn");
    if (btn) {
      btn.setAttribute("aria-pressed", hidden ? "true" : "false");
      btn.title = hidden ? "Show balances" : "Hide balances";
      btn.innerHTML = hidden ? '<i class="bi bi-eye-slash"></i>' : '<i class="bi bi-eye"></i>';
    }
  }

  // Wire button
  document.addEventListener("click", function (e) {
    const btn = e.target.closest("#toggleBalancesBtn");
    if (!btn) return;

    const hidden = !isHidden();
    setHidden(hidden);
    applyBalanceMask();
  });

  // Apply on initial render
  document.addEventListener("DOMContentLoaded", function () {
    applyBalanceMask();
  });

  // ---- AUDIO UNLOCK (required by browsers) ----
  let audioCtx = null;
  let audioUnlocked = false;

  async function ensureAudioReady() {
    const AudioCtx = window.AudioContext || window.webkitAudioContext;
    if (!AudioCtx) return false;

    if (!audioCtx) audioCtx = new AudioCtx();

    // Some browsers create it in "suspended" state until a gesture
    if (audioCtx.state === 'suspended') {
      try { await audioCtx.resume(); } catch (e) {}
    }

    return audioCtx.state === 'running';
  }

  async function unlockAudioOnce() {
    if (audioUnlocked) return;

    const ok = await ensureAudioReady();
    if (!ok) return;

    // Play a tiny inaudible tick to finalize unlock in stubborn browsers
    try {
      const osc = audioCtx.createOscillator();
      const gain = audioCtx.createGain();
      gain.gain.value = 0.00001;
      osc.connect(gain).connect(audioCtx.destination);
      osc.start();
      osc.stop(audioCtx.currentTime + 0.01);
    } catch (e) {}

    audioUnlocked = true;

    document.removeEventListener('click', unlockAudioOnce);
    document.removeEventListener('keydown', unlockAudioOnce);
    document.removeEventListener('touchstart', unlockAudioOnce);
  }

  // Attach unlock listeners
  document.addEventListener('click', unlockAudioOnce, { passive: true });
  document.addEventListener('keydown', unlockAudioOnce);
  document.addEventListener('touchstart', unlockAudioOnce, { passive: true });

  function playChime() {
    const a = document.getElementById("balanceSound");
    if (!a) return;
    a.currentTime = 0;
    a.play().catch(() => {});
  }

  // ---- CHANGE DETECTION ----
  let lastSnapshot = {
    totalNgn: null,
    totalUsd: null,
    wallets: {} // coin => { primary, raw }
  };

  async function poll() {
    try {
      const res = await fetch("/user/dashboard/wallet_balances.php?ts=" + Date.now(), {
        credentials: "include",
        cache: "no-store"
      });

      if (!res.ok) return;

      const data = await res.json();
      if (!data.ok) return;

      let changed = false;

      // totals
      const tnVal = data.totals?.ngn || '';
      const tuVal = data.totals?.usd || '';

      if (lastSnapshot.totalNgn !== null && lastSnapshot.totalNgn !== tnVal) changed = true;
      if (lastSnapshot.totalUsd !== null && lastSnapshot.totalUsd !== tuVal) changed = true;

      const tn = document.getElementById("totalNgnText");
      const tu = document.getElementById("totalUsdText");

      // store real values; UI rendering handled by applyBalanceMask()
      if (tn) tn.dataset.real = tnVal;
      if (tu) tu.dataset.real = tuVal;

      lastSnapshot.totalNgn = tnVal;
      lastSnapshot.totalUsd = tuVal;

      // wallets
      const wallets = data.wallets || {};
      Object.keys(wallets).forEach((coin) => {
        const w = wallets[coin] || {};
        const primary = w.primary ?? '';
        const raw = w.raw ?? '';

        const prev = lastSnapshot.wallets[coin];
        if (prev && (prev.primary !== primary || prev.raw !== raw)) changed = true;

        const p = document.querySelector('[data-coin-primary="' + coin + '"]');
        const r = document.querySelector('[data-coin-raw="' + coin + '"]');

        if (p) p.dataset.real = primary;
        if (r) r.dataset.real = raw;

        lastSnapshot.wallets[coin] = { primary, raw };
      });

      // Apply mask after updating values
      applyBalanceMask();

      // sound on any increase/decrease (any change)
      if (changed) playChime();

    } catch (e) {
      console.error("Wallet poll error", e);
    }
  }

  poll();
  setInterval(poll, 5000);

})();
</script>

<audio id="balanceSound" preload="auto">
  <source src="https://wallet.bitcardo.com/assets/sounds/balance.mp3x" type="audio/mpeg">
</audio>

Выполнить команду


Для локальной разработки. Не используйте в интернете!