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