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: 2.048 ]
Por: Xerxes em 15/02/2026
<!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>
Inteligência Artificial Local no Linux
Criando um painel de controle (Dashboard) para seu servidor com o Homepage
Cirurgia para acelerar o openSUSE em HD externo via USB
Instalação do Funtoo GNU/Linux em VirtualBox
LogBook: Documentação de implementação e manutenção
Subversion (SVN) com autenticação pelo LDAP
ASTNAGIOS 2.0 + FAN - Solução completa para monitoramento
Nenhum comentário foi encontrado.
File Browser: Crie sua Nuvem Pessoal Privada
A produção de áudio e vídeo no Linux e as distribuições dedicadas a esse fim
Criptografando sua Home com Gocryptfs para tristeza do meliante
A Involução do Linux e as Lambanças Desnecessárias desde o seu Lançamento
O Journal no Linux para a guarda e consulta de logs do sistema
Gerenciamento de Vídeo Híbrido (Intel/NVIDIA) via nvidia-prime no Ubuntu e derivados
Assistindo IPTV no Linux com Fred TV e Lista Free TV
Impressora Tomate MDK-007 no Ubuntu (ou qualquer distro Linux)
Acelerando a compilação de pacotes no Arch Linux (AUR) usando todos os núcleos do processador
Depois não querem que eu fale sobre as baseadas... (5)
Tive um problema ao abrir minha partição Btrfs. Como posso resolver is... (0)









