Currency Api Dashboard

TypeScript

Modern currency exchange rate dashboard with real-time market data, conversion tools, analytics, historical trends, and responsive admin interface.

Stars
18
Forks
1
Downloads
N/A
Open Issues
0
Files main

Repository Files

Loading file structure...
app/Http/Controllers/DashboardController.php
<?php

namespace App\Http\Controllers;

use App\Models\ApiLog;
use App\Models\Currency;
use App\Models\Tokens;
use Illuminate\Http\Request;
use Illuminate\Support\Carbon;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Str;
use Inertia\Inertia;
use Inertia\Response;

class DashboardController extends Controller
{
    /**
     * Display the dashboard.
     */
    public function index(Request $request): Response
    {
        $userId = auth()->id();
        $tokenIds = Tokens::where('user_id', $userId)->pluck('id');

        // Usage statistics
        $logsQuery = ApiLog::whereIn('token_id', $tokenIds);

        $totalCalls = (clone $logsQuery)->count();
        $successCalls = (clone $logsQuery)->whereBetween('status_code', [200, 299])->count();
        $successRate = $totalCalls > 0 ? round(($successCalls / $totalCalls) * 100, 1) : 100.0;

        $totalCallsToday = (clone $logsQuery)->where('created_at', '>=', Carbon::today())->count();
        $totalCallsMonth = (clone $logsQuery)->where('created_at', '>=', Carbon::now()->startOfMonth())->count();

        // 14-day chart data
        $chartData = [];
        for ($i = 13; $i >= 0; $i--) {
            $date = Carbon::now()->subDays($i)->format('Y-m-d');
            $label = Carbon::now()->subDays($i)->format('M d');
            $chartData[$date] = [
                'date' => $label,
                'calls' => 0,
            ];
        }

        $dailyLogs = ApiLog::whereIn('token_id', $tokenIds)
            ->where('created_at', '>=', Carbon::now()->subDays(13)->startOfDay())
            ->selectRaw('DATE(created_at) as date, count(*) as count')
            ->groupByRaw('DATE(created_at)')
            ->get();

        foreach ($dailyLogs as $log) {
            $formattedDate = Carbon::parse($log->date)->format('Y-m-d');
            if (isset($chartData[$formattedDate])) {
                $chartData[$formattedDate]['calls'] = (int) $log->count;
            }
        }

        $chartData = array_values($chartData);
        $totalTokens = Tokens::where('user_id', $userId)->count();

        // Recent Logs
        $recentLogs = ApiLog::whereIn('token_id', $tokenIds)
            ->with('token')
            ->latest()
            ->limit(15)
            ->get()
            ->map(function ($log) {
                return [
                    'id' => $log->id,
                    'token_name' => $log->token ? $log->token->name : 'N/A',
                    'endpoint' => '/'.ltrim($log->endpoint, '/'),
                    'method' => $log->method,
                    'ip_address' => $log->ip_address,
                    'status_code' => $log->status_code,
                    'created_at' => $log->created_at->diffForHumans(),
                ];
            });

        return Inertia::render('dashboard', [
            'stats' => [
                'total_calls_today' => $totalCallsToday,
                'total_calls_month' => $totalCallsMonth,
                'success_rate' => $successRate,
                'total_tokens' => $totalTokens,
                'chart_data' => $chartData,
                'recent_logs' => $recentLogs,
            ],
        ]);
    }

    /**
     * Display the tokens page.
     */
    public function tokensPage(Request $request): Response
    {
        $userId = auth()->id();
        $tokens = Tokens::where('user_id', $userId)->latest()->get();
        $currencies = Currency::where('active', true)->orderBy('code')->get();

        return Inertia::render('dashboard/tokens', [
            'tokens' => $tokens,
            'currencies' => $currencies,
        ]);
    }

    /**
     * Display the currencies directory page.
     */
    public function currenciesPage(Request $request): Response
    {
        $currencies = Currency::where('active', true)->orderBy('code')->get();

        return Inertia::render('dashboard/currencies', [
            'currencies' => $currencies,
        ]);
    }

    /**
     * Display the converter playground page.
     */
    public function converterPage(Request $request): Response
    {
        $userId = auth()->id();
        $tokens = Tokens::where('user_id', $userId)->get();
        $currencies = Currency::where('active', true)->orderBy('code')->get();

        return Inertia::render('dashboard/converter', [
            'tokens' => $tokens,
            'currencies' => $currencies,
        ]);
    }

    /**
     * Store a newly created token.
     */
    public function storeToken(Request $request)
    {
        $request->validate([
            'name' => 'required|string|max:255',
            'default_currency' => 'nullable|string|size:3',
        ]);

        $tokenStr = 'oxr_'.Str::random(56);
        $defaultCurrency = strtoupper($request->input('default_currency') ?: 'INR');

        $token = Tokens::create([
            'user_id' => auth()->id(),
            'name' => $request->name,
            'token' => $tokenStr,
            'default_currency' => $defaultCurrency,
            'active' => true,
        ]);

        Cache::put('TOKEN:'.$tokenStr, $token, 60 * 60 * 24);

        return back()->with('success', 'Token generated successfully.');
    }

    /**
     * Regenerate an existing token key.
     */
    public function regenerateToken(Request $request, $id)
    {
        $token = Tokens::where('user_id', auth()->id())->findOrFail($id);

        // Remove old key from cache
        Cache::forget('TOKEN:'.$token->token);

        $newTokenStr = 'oxr_'.Str::random(56);

        $token->update([
            'token' => $newTokenStr,
        ]);

        // Add new key to cache
        Cache::put('TOKEN:'.$newTokenStr, $token, 60 * 60 * 24);

        return back()->with('success', 'Token regenerated successfully.');
    }

    /**
     * Toggle the active status of a token.
     */
    public function toggleTokenStatus(Request $request, $id)
    {
        $token = Tokens::where('user_id', auth()->id())->findOrFail($id);

        $token->update([
            'active' => ! $token->active,
        ]);

        // Remove/update in cache
        if ($token->active) {
            Cache::put('TOKEN:'.$token->token, $token, 60 * 60 * 24);
        } else {
            Cache::forget('TOKEN:'.$token->token);
        }

        return back()->with('success', 'Token status updated.');
    }

    /**
     * Remove the specified token.
     */
    public function destroyToken($id)
    {
        $token = Tokens::where('user_id', auth()->id())->findOrFail($id);

        // Clearing cache is handled automatically in Tokens model's booted static delete callback
        $token->delete();

        return back()->with('success', 'Token revoked and deleted.');
    }
}