Portal TransformaΓ§Γ£o Digital
MODULO 4.9

πŸ–₯️ Frontend e UX

Interface de usuario com Jinja2 templates e interacao com a API.

6
Topicos
~35
Minutos
Avanc.
Nivel
Pratico
Tipo
1

πŸ“ Arquitetura do Frontend

Stack simples com Jinja2, HTMX e Tailwind CSS.

app/
β”œβ”€β”€ templates/
β”‚   β”œβ”€β”€ base.html           # Layout base
β”‚   β”œβ”€β”€ components/
β”‚   β”‚   β”œβ”€β”€ navbar.html
β”‚   β”‚   β”œβ”€β”€ chat_message.html
β”‚   β”‚   └── source_card.html
β”‚   β”œβ”€β”€ pages/
β”‚   β”‚   β”œβ”€β”€ home.html
β”‚   β”‚   β”œβ”€β”€ notebook.html
β”‚   β”‚   └── chat.html
β”‚   └── partials/           # Fragments HTMX
β”‚       β”œβ”€β”€ message_list.html
β”‚       └── source_list.html
β”œβ”€β”€ static/
β”‚   β”œβ”€β”€ css/
β”‚   β”‚   └── styles.css      # Tailwind compilado
β”‚   └── js/
β”‚       └── app.js          # JavaScript minimo
2

🎨 Template Base

Layout compartilhado por todas as paginas.

<!-- templates/base.html -->
<!DOCTYPE html>
<html lang="pt-BR" class="dark">
<head>
    <meta charset="UTF-8">
    <title>{% block title %}NotebookLMX{% endblock %}</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <script src="https://unpkg.com/htmx.org@1.9.10"></script>
</head>
<body class="bg-gray-900 text-white min-h-screen">
    {% include "components/navbar.html" %}

    <main class="max-w-6xl mx-auto px-4 py-8">
        {% block content %}{% endblock %}
    </main>

    {% block scripts %}{% endblock %}
</body>
</html>
3

πŸ’¬ Interface de Chat

Componente de chat com HTMX para atualizacoes em tempo real.

<!-- templates/pages/chat.html -->
{% extends "base.html" %}
{% block content %}
<div class="flex flex-col h-[calc(100vh-200px)]">
    <!-- Mensagens -->
    <div id="messages" class="flex-1 overflow-y-auto space-y-4 p-4">
        {% for msg in messages %}
            {% include "components/chat_message.html" %}
        {% endfor %}
    </div>

    <!-- Input -->
    <form hx-post="/api/notebooks/{{ notebook.id }}/chat"
          hx-target="#messages"
          hx-swap="beforeend"
          class="p-4 border-t border-gray-700">
        <div class="flex space-x-4">
            <input type="text" name="message"
                   class="flex-1 bg-gray-800 rounded-lg px-4 py-2"
                   placeholder="Digite sua mensagem...">
            <button type="submit" class="bg-amber-600 px-6 py-2 rounded-lg">
                Enviar
            </button>
        </div>
    </form>
</div>
{% endblock %}
4

πŸ“€ Upload de Fontes

Componente para upload de PDFs e arquivos de texto.

<!-- Componente de upload com drag-and-drop -->
<div id="upload-zone"
     class="border-2 border-dashed border-gray-600 rounded-xl p-8
            hover:border-amber-500 transition-colors"
     hx-post="/api/notebooks/{{ notebook.id }}/sources"
     hx-encoding="multipart/form-data"
     hx-target="#source-list"
     hx-swap="beforeend">

    <input type="file" name="file" accept=".pdf,.txt,.md"
           class="hidden" id="file-input">

    <div class="text-center">
        <p class="text-gray-400">Arraste arquivos aqui ou</p>
        <label for="file-input" class="text-amber-400 cursor-pointer">
            clique para selecionar
        </label>
    </div>
</div>

<!-- Lista de fontes -->
<div id="source-list" class="mt-6 space-y-3">
    {% for source in sources %}
        {% include "components/source_card.html" %}
    {% endfor %}
</div>
5

🎯 Selecao de Persona

Interface para escolher o estilo de resposta da IA.

<!-- Seletor de persona -->
<div class="flex space-x-2 mb-4">
    {% for persona in personas %}
    <button type="button"
            class="persona-btn px-4 py-2 rounded-lg
                   {% if persona.id == current_persona %}
                   bg-amber-600 text-white
                   {% else %}
                   bg-gray-700 text-gray-300
                   {% endif %}"
            hx-post="/api/notebooks/{{ notebook.id }}/persona"
            hx-vals='{"persona": "{{ persona.id }}"}'
            hx-swap="none">
        {{ persona.icon }} {{ persona.name }}
    </button>
    {% endfor %}
</div>

<!-- Personas disponiveis -->
<!-- πŸŽ“ Academico - Tom formal, citacoes -->
<!-- πŸ’Ό Profissional - Direto, objetivo -->
<!-- 🎨 Criativo - Analogias, exemplos -->
6

πŸ“Š Dashboard de Metricas

Visualizacao de uso e custos para transparencia.

<!-- Dashboard de metricas GIPM -->
<div class="grid grid-cols-4 gap-4 mb-8">
    <div class="bg-gray-800 rounded-xl p-4">
        <p class="text-gray-400 text-sm">Mensagens</p>
        <p class="text-2xl font-bold text-white">{{ stats.total_messages }}</p>
    </div>
    <div class="bg-gray-800 rounded-xl p-4">
        <p class="text-gray-400 text-sm">Tokens Usados</p>
        <p class="text-2xl font-bold text-white">{{ stats.total_tokens | format_number }}</p>
    </div>
    <div class="bg-gray-800 rounded-xl p-4">
        <p class="text-gray-400 text-sm">Custo Total</p>
        <p class="text-2xl font-bold text-amber-400">${{ stats.total_cost | round(4) }}</p>
    </div>
    <div class="bg-gray-800 rounded-xl p-4">
        <p class="text-gray-400 text-sm">Artefatos</p>
        <p class="text-2xl font-bold text-white">{{ stats.total_artifacts }}</p>
    </div>
</div>

πŸ“ Resumo do Modulo

βœ“Jinja2 - Templates server-side
βœ“HTMX - Interatividade sem SPA
βœ“Tailwind - Estilizacao rapida
βœ“Metricas - Transparencia para o usuario