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.684 ]

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

Como criar um make.conf no Gentoo (para iniciantes)

Estratégia para Shadow Era (Supernova Boring)

DOOM clássico (quase) vanilla e um pouco melhorado

Como jogar a versão para PC de "The Legend of Zelda: Ocarina of Time" no sistema operacional GNU/Linux com melhorias gráficas

Apresentando Cinnamon

Leitura recomendada

Programando um mundo livre

Apresentando o CentOS - The Community Enterprise Operating System

Compartilhando o Terminal

O que é GNU Social? Porquê usar?

Clustering em Casa

  
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