Skip to content

Página de edição de perfil no User panel (Filament) #255

@danielhe4rt

Description

@danielhe4rt

Parent

Parte da PRD #250 — Módulo Profile Fase 1.

Contexto

O backend do Profile já está pronto (#251 model, #253 actions). Esta issue plugra a experiência de edição no User panel (/app) via Filament.

O membro acessa a página de perfil dentro do painel pra editar seus dados profissionais, bio, links sociais e disponibilidade. Campos de conta (name, email, username, password) não aparecem aqui — eles vivem em uma página separada de Settings (escopo fora desta issue).

Onde vive o código

Decisão arquitetural: Filament forms/pages não vivem dentro do módulo de domínio (app-modules/profile/). Eles vivem na camada de painel. Verificar onde os outros recursos do User panel estão registrados e seguir o mesmo padrão.

Referência visual

A PRD #250 inclui um mockup React que mostra o layout do form. Os elementos-chave são:

  • Card "Perfil profissional" com: nickname, birthdate, headline, senioridade, anos de experiência, social links, bio
  • Seção de disponibilidade com toggle + pills de prazo
  • Preview de como recrutadores veem o perfil (opcional nesta fase)

O que construir

1. Página de Profile no User panel

Uma página Filament no User panel onde o membro edita seu perfil do tenant atual. O tenant é resolvido automaticamente pelo Filament (multi-tenancy).

2. Form schema

Campos organizados em seções:

Seção: Dados pessoais

  • nickname — TextInput, max 100, placeholder "Como você é conhecido"
  • birthdate — DatePicker

Seção: Dados profissionais

  • headline — TextInput, max 100, placeholder "Seu cargo ou título profissional", hint "Ex: Frontend Developer, Product Designer"
  • seniority_level — Select com opções do enum SeniorityLevel (labels pt-BR)
  • years_experience — TextInput numérico, min 0, max 50

Seção: Bio

  • about — Textarea (ou RichEditor se consistente com o resto do app), max 500, com contador de caracteres

Seção: Links sociais

  • Componente que permite adicionar pares plataforma/handle baseado no enum SocialPlatform
  • Pode ser um Repeater com Select (plataforma) + TextInput (handle/URL)
  • Ou um KeyValue com chaves restritas ao enum
  • Salva como JSONB em social_links

Seção: Disponibilidade

  • available_for_proposals — Toggle, label "Disponível para propostas", hint "Quando ativo, recrutadores verão um badge verde no seu perfil"
  • start_availability — Select ou Radio com opções do enum StartAvailability, visível somente quando available_for_proposals = true (usar ->visible(fn (Get $get) => $get('available_for_proposals')))

3. Save handler

O form deve chamar as actions de domínio:

  • UpsertProfile pra salvar dados pessoais/profissionais/bio/social links
  • ToggleAvailability pra salvar disponibilidade (ou incluir no UpsertProfile se mais prático)

Após salvar, exibir notificação de sucesso via Filament.

4. Tenant context

O form opera no Profile do tenant atual. O Profile é carregado via:

Profile::where('user_id', auth()->id())
       ->where('tenant_id', Filament::getTenant()->id)
       ->first()

Cenários BDD

Funcionalidade: Edição de perfil no User Panel

  Cenário: Form carrega dados existentes do profile
    Dado que estou logado como membro no User panel
    E meu Profile tem headline "Backend Dev" e seniority "pleno"
    Quando acesso a página de edição do perfil
    Então o campo headline exibe "Backend Dev"
    E o campo seniority exibe "Pleno"

  Cenário: Membro preenche e salva todos os campos
    Dado que estou logado como membro no User panel
    Quando preencho headline com "Backend Developer"
    E seleciono senioridade "Pleno"
    E preencho anos de experiência com 5
    E preencho apelido com "Dan"
    E preencho bio com "Dev PHP apaixonado por Laravel"
    E salvo o formulário
    Então o Profile é atualizado no banco com todos os campos
    E uma notificação de sucesso aparece

  Cenário: Validação de bio com mais de 500 caracteres
    Dado que estou logado como membro
    Quando preencho bio com texto de 501 caracteres
    E salvo o formulário
    Então o form exibe erro de validação no campo about
    E o Profile não é alterado

  Cenário: Toggle de disponibilidade mostra/esconde prazo
    Dado que estou logado e available_for_proposals é false
    Quando vejo o formulário
    Então o campo start_availability não está visível
    Quando ativo o toggle "Disponível para propostas"
    Então o campo start_availability aparece

  Cenário: Salvar disponibilidade ativa com prazo
    Dado que estou logado
    Quando ativo o toggle de disponibilidade
    E seleciono start_availability "immediate"
    E salvo
    Então available_for_proposals é true no banco
    E start_availability é "immediate"

  Cenário: Campos de conta NÃO aparecem no form
    Dado que estou logado no User panel
    Quando acesso a página de perfil
    Então não vejo campos para name, email, username ou password

  Cenário: Links sociais — adicionar e salvar
    Dado que estou logado no User panel
    Quando adiciono social link: plataforma "instagram", handle "@danielhe4rt"
    E adiciono social link: plataforma "website", handle "https://danielheart.dev"
    E salvo o formulário
    Então social_links no banco contém {"instagram": "@danielhe4rt", "website": "https://danielheart.dev"}

Acceptance Criteria

  • Página de Profile existe no User panel, acessível por membros logados
  • Form carrega dados do Profile do tenant atual
  • Todos os campos do Profile são editáveis (nickname, birthdate, headline, seniority, years_exp, about, social_links)
  • Toggle de disponibilidade mostra/esconde start_availability via ->live() + ->visible()
  • Validação client-side e server-side (max lengths, enum values, etc.)
  • Save chama as actions de domínio e exibe notificação de sucesso
  • Campos de conta (name, email, username, password) não aparecem nesta página
  • Testes Livewire cobrem: carregar dados, salvar, validação, toggle
  • Código Filament vive na camada de painel (não dentro de app-modules/profile/)
  • vendor/bin/pint --dirty --format agent passa sem erros

Blocked by

Metadata

Metadata

Assignees

No one assigned

    Labels

    presentationFilament/UI layerprofileProfile moduleready-for-agentFully specified, ready for an AFK agent

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions