- Add TokenCard and CexAnalysisCard components for displaying token data - Implement real-time Redis event streaming for token updates - Add environment-based configuration system for dev/prod Redis servers - Create comprehensive hunting ground dashboard with card management - Add individual and bulk card removal functionality - Implement browser integration for token details viewing - Add timestamp utilities and proper type handling for Redis events - Create production-ready configuration with 154.38.185.112 Redis server - Add comprehensive documentation in README.md and CONTRIBUTORS.md - Restructure project architecture with proper Electron-Vue integration BREAKING CHANGE: Redis configuration now uses environment-based settings
166 lines
5.3 KiB
Vue
166 lines
5.3 KiB
Vue
<template>
|
||
<div class="desktop-container">
|
||
<!-- Top bar with user info -->
|
||
<div class="navbar bg-base-300 px-4">
|
||
<div class="navbar-start">
|
||
<div class="text-xl font-bold">Ziya Dashboard</div>
|
||
</div>
|
||
<div class="navbar-end">
|
||
<div class="dropdown dropdown-end">
|
||
<div tabindex="0" role="button" class="btn btn-ghost btn-circle avatar">
|
||
<div class="w-10 rounded-full bg-primary flex items-center justify-center">
|
||
<span class="text-primary-content font-bold text-sm">
|
||
{{ appStore.userInitials }}
|
||
</span>
|
||
</div>
|
||
</div>
|
||
<ul tabindex="0" class="menu menu-sm dropdown-content mt-3 z-[1] p-2 shadow bg-base-100 rounded-box w-52">
|
||
<li><a @click="navigateToProfile">Profile</a></li>
|
||
<li><a>Settings</a></li>
|
||
<li><a @click="handleLogout">Logout</a></li>
|
||
</ul>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Main content area -->
|
||
<div class="flex-1 flex overflow-hidden">
|
||
<!-- Sidebar -->
|
||
<div class="w-64 bg-base-200 p-4">
|
||
<ul class="menu">
|
||
<li><a class="active">Dashboard</a></li>
|
||
<li><a @click="navigateToProfile">Profile</a></li>
|
||
<li><a>Trading</a></li>
|
||
<li><a>Portfolio</a></li>
|
||
<li><a>Markets</a></li>
|
||
<li><a @click="navigateToHuntingGround">Hunting Ground</a></li>
|
||
<li><a>Analytics</a></li>
|
||
</ul>
|
||
</div>
|
||
|
||
<!-- Main content -->
|
||
<div class="flex-1 p-6 overflow-y-auto">
|
||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6 mb-6">
|
||
<!-- Stats cards -->
|
||
<div class="stats shadow">
|
||
<div class="stat">
|
||
<div class="stat-title">Total Balance</div>
|
||
<div class="stat-value text-primary">$25,600</div>
|
||
<div class="stat-desc">↗︎ 12% (30d)</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="stats shadow">
|
||
<div class="stat">
|
||
<div class="stat-title">Active Positions</div>
|
||
<div class="stat-value text-secondary">8</div>
|
||
<div class="stat-desc">↗︎ 2 new today</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="stats shadow">
|
||
<div class="stat">
|
||
<div class="stat-title">P&L Today</div>
|
||
<div class="stat-value text-accent">+$450</div>
|
||
<div class="stat-desc">↗︎ +2.1%</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Trading interface -->
|
||
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
||
<div class="card bg-base-100 shadow-xl">
|
||
<div class="card-body">
|
||
<h2 class="card-title">Quick Trade</h2>
|
||
<div class="form-control">
|
||
<label class="label">
|
||
<span class="label-text">Asset</span>
|
||
</label>
|
||
<select class="select select-bordered">
|
||
<option>BTC/USD</option>
|
||
<option>ETH/USD</option>
|
||
<option>SOL/USD</option>
|
||
</select>
|
||
</div>
|
||
<div class="form-control">
|
||
<label class="label">
|
||
<span class="label-text">Amount</span>
|
||
</label>
|
||
<input type="number" class="input input-bordered" placeholder="0.00">
|
||
</div>
|
||
<div class="card-actions justify-end">
|
||
<button class="btn btn-success">Buy</button>
|
||
<button class="btn btn-error">Sell</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="card bg-base-100 shadow-xl">
|
||
<div class="card-body">
|
||
<h2 class="card-title">Recent Trades</h2>
|
||
<div class="overflow-x-auto">
|
||
<table class="table table-sm">
|
||
<thead>
|
||
<tr>
|
||
<th>Asset</th>
|
||
<th>Type</th>
|
||
<th>Amount</th>
|
||
<th>Price</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>BTC</td>
|
||
<td><span class="badge badge-success">Buy</span></td>
|
||
<td>0.025</td>
|
||
<td>$42,500</td>
|
||
</tr>
|
||
<tr>
|
||
<td>ETH</td>
|
||
<td><span class="badge badge-error">Sell</span></td>
|
||
<td>2.5</td>
|
||
<td>$2,650</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup lang="ts">
|
||
import { onMounted } from 'vue';
|
||
import { useRouter } from 'vue-router';
|
||
import { useAppStore } from '../stores/app';
|
||
|
||
const appStore = useAppStore();
|
||
const router = useRouter();
|
||
|
||
// Redirect if not authenticated
|
||
onMounted(() => {
|
||
if (!appStore.isAuthenticated) {
|
||
router.push('/login');
|
||
}
|
||
});
|
||
|
||
const handleLogout = async () => {
|
||
await appStore.logout();
|
||
router.push('/login');
|
||
};
|
||
|
||
const navigateToProfile = () => {
|
||
router.push('/profile');
|
||
};
|
||
|
||
const navigateToHuntingGround = () => {
|
||
router.push('/hunting-ground');
|
||
};
|
||
</script>
|
||
|
||
<style scoped>
|
||
/* Page-specific styles if needed */
|
||
</style>
|