Berry Bank: Criando um Banco Digital Gamificado para seus Filhos com Gentoo, Flask e Tailscale

Berry é a moeda do anime One Piece, um anime que meus filhos gostam. Aproveitando isso, resolvi criar um "banco virtual" para gerenciar os Berries deles.

[ Hits: 1.682 ]

Por: Xerxes em 15/02/2026


A Página Administrativa (templates/admin.html)



Aqui o HTML da página administrativa:

<!DOCTYPE html>
<html>
<head>
    <title>Painel do Pai</title>
    <style>
        body { font-family: sans-serif; max-width: 900px; margin: auto; padding: 20px; background-color: #f8f9fa; }
        .header { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; }
        .logout { color: #dc3545; text-decoration: none; font-weight: bold; }
        
        /* Estilos dos Cards de Saldo */
        .saldo-container { display: flex; gap: 20px; margin-bottom: 30px; }
        .saldo-card { background: #fff; border-radius: 10px; overflow: hidden; box-shadow: 0 4px 6px rgba(0,0,0,0.1); flex: 1; text-align: center; }
        .saldo-card img { width: 100%; height: 200px; object-fit: cover; }
        .saldo-info { padding: 15px; }
        .saldo-info h3 { margin: 0; font-size: 1.2em; }
        .saldo-valor { font-size: 1.5em; font-weight: bold; color: #28a745; margin-top: 10px; }

        /* Estilos da Área de Transação */
        .box { background: #fff; padding: 25px; border-radius: 10px; box-shadow: 0 4px 6px rgba(0,0,0,0.1); margin-bottom: 30px; }
        
        /* Estilos dos Radio Cards (Seleção) */
        .radio-group { display: flex; gap: 20px; margin-bottom: 20px; }
        .radio-label { flex: 1; cursor: pointer; position: relative; }
        .radio-label input[type="radio"] { position: absolute; opacity: 0; cursor: pointer; }
        .radio-card { 
            background: #f1f3f5; 
            border: 2px solid transparent; 
            border-radius: 10px; 
            padding: 15px; 
            text-align: center; 
            transition: all 0.3s ease;
            display: flex;
            flex-direction: column;
            align-items: center;
        }
        .radio-card img { width: 80px; height: 80px; border-radius: 50%; object-fit: cover; margin-bottom: 10px; border: 2px solid #fff; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }
        
        /* Efeito quando selecionado */
        .radio-label input[type="radio"]:checked + .radio-card { 
            border-color: #28a745; 
            background: #e9f7ef; 
            box-shadow: 0 0 10px rgba(40, 167, 69, 0.3);
        }
        .radio-label input[type="radio"]:hover + .radio-card { background: #e2e6ea; }

        /* Formulário e Tabela */
        input[type="number"], input[type="text"] { width: 100%; padding: 12px; margin: 10px 0 20px; border: 1px solid #ced4da; border-radius: 5px; box-sizing: border-box; }
        button { background-color: #28a745; color: white; padding: 15px; border: none; border-radius: 5px; width: 100%; font-size: 1.1em; cursor: pointer; transition: background 0.3s; }
        button:hover { background-color: #218838; }
        
        table { width: 100%; border-collapse: collapse; }
        th, td { padding: 12px; text-align: left; border-bottom: 1px solid #dee2e6; }
        th { background-color: #e9ecef; }
    </style>
</head>
<body>
    <div class="header">
        <h1>Painel de Controle</h1>
        <a href="/" class="logout">Sair</a>
    </div>

    <div class="saldo-container">
        {% for kid in kids %}
        <div class="saldo-card">
            {% if kid['name'] == 'filho2' %}
                <img src="{{ url_for('static', filename='luffy.png') }}" alt="Luffy">
            {% elif kid['name'] == 'filho1' %}
                <img src="{{ url_for('static', filename='zoro.png') }}" alt="Zoro">
            {% endif %}
            <div class="saldo-info">
                <h3>{{ kid['name'] }}</h3>
                <div class="saldo-valor">{{ kid['balance'] }} $B</div>
            </div>
        </div>
        {% endfor %}
    </div>

    <div class="box">
        <h3>⚡ Realizar Transação</h3>
        <form action="/update" method="post">
            <p style="margin-bottom: 10px; font-weight: bold;">Quem?</p>
            <div class="radio-group">
                {% for kid in kids %}
                <label class="radio-label">
                    <input type="radio" name="kid_id" value="{{ kid['id'] }}" required>
                    <div class="radio-card">
                        {% if kid['name'] == 'filho2' %}
                            <img src="{{ url_for('static', filename='luffy.png') }}" alt="Luffy">
                        {% elif kid['name'] == 'filho1' %}
                            <img src="{{ url_for('static', filename='zoro.png') }}" alt="Zoro">
                        {% endif %}
                        <span>{{ kid['name'] }}</span>
                    </div>
                </label>
                {% endfor %}
            </div>

            <label style="font-weight: bold;">Valor (Use negativo para retirar, ex: -50)</label>
            <input type="number" name="amount" placeholder="Ex: 100 ou -50" required>

            <label style="font-weight: bold;">Motivo</label>
            <input type="text" name="reason" placeholder="Ex: Lavou a louça, Comprou jogo..." required>

            <button type="submit">Atualizar Saldo</button>
        </form>
    </div>

    <div class="box" style="padding: 0; overflow: hidden;">
        <h3 style="padding: 20px; margin: 0; background: #f1f3f5; border-bottom: 1px solid #dee2e6;">📜 Histórico Recente</h3>
        <table>
            <tr>
                <th>Nome</th>
                <th>Valor ($B)</th>
                <th>Motivo</th>
                <th>Data</th>
            </tr>
            {% for item in history %}
            <tr>
                <td>{{ item['name'] }}</td>
                <td style="color: {{ 'green' if item['amount'] > 0 else 'red' }}; font-weight: bold;">
                    {{ '+' if item['amount'] > 0 }}{{ item['amount'] }}
                </td>
                <td>{{ item['reason'] }}</td>
                <td>{{ item['timestamp'] }}</td>
            </tr>
            {% endfor %}
        </table>
    </div>
</body>
</html>
Página anterior     Próxima página

Páginas do artigo
   1. Introdução
   2. O Backend: Python e Flask
   3. O Frontend (estilo One Piece)
   4. A Página Administrativa (templates/admin.html)
   5. A Página do Login (templates/login.html)
   6. Automatizando com Systemd e conclusão
Outros artigos deste autor

Configure o Linux para sua avó!

Três distros inspiradas no Mac OS

Fedora Desktop completo com i3 WM

Gentoo Linux vale a pena?

Com vocês, Larry, a vaca

Leitura recomendada

Fazendo backup de DVDs

Docker + Cluster DRBD + SQL Server - Database as a Service Utilizando Volumes Replicados

SIMH: Recriando um pouco da história

LiveCDs versus D.Q.R.E.Cs

Guia de preparação para LPI

  
Comentários

Nenhum comentário foi encontrado.


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts