Merge pull request #34 from rede5/Front-back-integracao-task12
feat(profissionais): melhorar a visualização de detalhes e persistência dos profissionais - Adiciona a coluna `email` ao banco de dados para corrigir a persistência do e-mail de contato. - Atualiza o `Team.tsx` para exibir todos os campos do profissional no modal de detalhes (Dados Financeiros, Detalhamento de Avaliações). - Corrige o cálculo e a persistência de `media` (ajuste para valor nulo). - Implementa integração com CEP para preenchimento automático de endereço. - Adiciona validações para valores negativos e corrige problemas de layout.
This commit is contained in:
commit
7fe7bd87fb
13 changed files with 997 additions and 1520 deletions
|
|
@ -2997,6 +2997,9 @@ const docTemplate = `{
|
|||
"educacao_simpatia": {
|
||||
"type": "integer"
|
||||
},
|
||||
"email": {
|
||||
"type": "string"
|
||||
},
|
||||
"endereco": {
|
||||
"type": "string"
|
||||
},
|
||||
|
|
@ -3047,6 +3050,9 @@ const docTemplate = `{
|
|||
"agencia": {
|
||||
"type": "string"
|
||||
},
|
||||
"avatar_url": {
|
||||
"type": "string"
|
||||
},
|
||||
"banco": {
|
||||
"type": "string"
|
||||
},
|
||||
|
|
@ -3161,6 +3167,9 @@ const docTemplate = `{
|
|||
"educacao_simpatia": {
|
||||
"type": "integer"
|
||||
},
|
||||
"email": {
|
||||
"type": "string"
|
||||
},
|
||||
"endereco": {
|
||||
"type": "string"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -2991,6 +2991,9 @@
|
|||
"educacao_simpatia": {
|
||||
"type": "integer"
|
||||
},
|
||||
"email": {
|
||||
"type": "string"
|
||||
},
|
||||
"endereco": {
|
||||
"type": "string"
|
||||
},
|
||||
|
|
@ -3041,6 +3044,9 @@
|
|||
"agencia": {
|
||||
"type": "string"
|
||||
},
|
||||
"avatar_url": {
|
||||
"type": "string"
|
||||
},
|
||||
"banco": {
|
||||
"type": "string"
|
||||
},
|
||||
|
|
@ -3155,6 +3161,9 @@
|
|||
"educacao_simpatia": {
|
||||
"type": "integer"
|
||||
},
|
||||
"email": {
|
||||
"type": "string"
|
||||
},
|
||||
"endereco": {
|
||||
"type": "string"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -274,6 +274,8 @@ definitions:
|
|||
type: integer
|
||||
educacao_simpatia:
|
||||
type: integer
|
||||
email:
|
||||
type: string
|
||||
endereco:
|
||||
type: string
|
||||
equipamentos:
|
||||
|
|
@ -307,6 +309,8 @@ definitions:
|
|||
properties:
|
||||
agencia:
|
||||
type: string
|
||||
avatar_url:
|
||||
type: string
|
||||
banco:
|
||||
type: string
|
||||
carro_disponivel:
|
||||
|
|
@ -383,6 +387,8 @@ definitions:
|
|||
type: integer
|
||||
educacao_simpatia:
|
||||
type: integer
|
||||
email:
|
||||
type: string
|
||||
endereco:
|
||||
type: string
|
||||
equipamentos:
|
||||
|
|
|
|||
|
|
@ -198,7 +198,7 @@ func (q *Queries) GetAgenda(ctx context.Context, id pgtype.UUID) (Agenda, error)
|
|||
}
|
||||
|
||||
const getAgendaProfessionals = `-- name: GetAgendaProfessionals :many
|
||||
SELECT p.id, p.usuario_id, p.nome, p.funcao_profissional_id, p.endereco, p.cidade, p.uf, p.whatsapp, p.cpf_cnpj_titular, p.banco, p.agencia, p.conta_pix, p.carro_disponivel, p.tem_estudio, p.qtd_estudio, p.tipo_cartao, p.observacao, p.qual_tec, p.educacao_simpatia, p.desempenho_evento, p.disp_horario, p.media, p.tabela_free, p.extra_por_equipamento, p.equipamentos, p.avatar_url, p.criado_em, p.atualizado_em, f.nome as funcao_nome, u.email
|
||||
SELECT p.id, p.usuario_id, p.nome, p.funcao_profissional_id, p.endereco, p.cidade, p.uf, p.whatsapp, p.cpf_cnpj_titular, p.banco, p.agencia, p.conta_pix, p.carro_disponivel, p.tem_estudio, p.qtd_estudio, p.tipo_cartao, p.observacao, p.qual_tec, p.educacao_simpatia, p.desempenho_evento, p.disp_horario, p.media, p.tabela_free, p.extra_por_equipamento, p.equipamentos, p.email, p.avatar_url, p.criado_em, p.atualizado_em, f.nome as funcao_nome, u.email
|
||||
FROM cadastro_profissionais p
|
||||
JOIN agenda_profissionais ap ON p.id = ap.profissional_id
|
||||
LEFT JOIN funcoes_profissionais f ON p.funcao_profissional_id = f.id
|
||||
|
|
@ -232,11 +232,12 @@ type GetAgendaProfessionalsRow struct {
|
|||
TabelaFree pgtype.Text `json:"tabela_free"`
|
||||
ExtraPorEquipamento pgtype.Bool `json:"extra_por_equipamento"`
|
||||
Equipamentos pgtype.Text `json:"equipamentos"`
|
||||
Email pgtype.Text `json:"email"`
|
||||
AvatarUrl pgtype.Text `json:"avatar_url"`
|
||||
CriadoEm pgtype.Timestamptz `json:"criado_em"`
|
||||
AtualizadoEm pgtype.Timestamptz `json:"atualizado_em"`
|
||||
FuncaoNome pgtype.Text `json:"funcao_nome"`
|
||||
Email pgtype.Text `json:"email"`
|
||||
Email_2 pgtype.Text `json:"email_2"`
|
||||
}
|
||||
|
||||
func (q *Queries) GetAgendaProfessionals(ctx context.Context, agendaID pgtype.UUID) ([]GetAgendaProfessionalsRow, error) {
|
||||
|
|
@ -274,11 +275,12 @@ func (q *Queries) GetAgendaProfessionals(ctx context.Context, agendaID pgtype.UU
|
|||
&i.TabelaFree,
|
||||
&i.ExtraPorEquipamento,
|
||||
&i.Equipamentos,
|
||||
&i.Email,
|
||||
&i.AvatarUrl,
|
||||
&i.CriadoEm,
|
||||
&i.AtualizadoEm,
|
||||
&i.FuncaoNome,
|
||||
&i.Email,
|
||||
&i.Email_2,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -543,7 +545,7 @@ func (q *Queries) ListAgendasByUser(ctx context.Context, userID pgtype.UUID) ([]
|
|||
|
||||
const listAvailableProfessionalsForDate = `-- name: ListAvailableProfessionalsForDate :many
|
||||
SELECT
|
||||
p.id, p.usuario_id, p.nome, p.funcao_profissional_id, p.endereco, p.cidade, p.uf, p.whatsapp, p.cpf_cnpj_titular, p.banco, p.agencia, p.conta_pix, p.carro_disponivel, p.tem_estudio, p.qtd_estudio, p.tipo_cartao, p.observacao, p.qual_tec, p.educacao_simpatia, p.desempenho_evento, p.disp_horario, p.media, p.tabela_free, p.extra_por_equipamento, p.equipamentos, p.avatar_url, p.criado_em, p.atualizado_em,
|
||||
p.id, p.usuario_id, p.nome, p.funcao_profissional_id, p.endereco, p.cidade, p.uf, p.whatsapp, p.cpf_cnpj_titular, p.banco, p.agencia, p.conta_pix, p.carro_disponivel, p.tem_estudio, p.qtd_estudio, p.tipo_cartao, p.observacao, p.qual_tec, p.educacao_simpatia, p.desempenho_evento, p.disp_horario, p.media, p.tabela_free, p.extra_por_equipamento, p.equipamentos, p.email, p.avatar_url, p.criado_em, p.atualizado_em,
|
||||
u.email,
|
||||
f.nome as funcao_nome,
|
||||
dp.status as status_disponibilidade
|
||||
|
|
@ -589,10 +591,11 @@ type ListAvailableProfessionalsForDateRow struct {
|
|||
TabelaFree pgtype.Text `json:"tabela_free"`
|
||||
ExtraPorEquipamento pgtype.Bool `json:"extra_por_equipamento"`
|
||||
Equipamentos pgtype.Text `json:"equipamentos"`
|
||||
Email pgtype.Text `json:"email"`
|
||||
AvatarUrl pgtype.Text `json:"avatar_url"`
|
||||
CriadoEm pgtype.Timestamptz `json:"criado_em"`
|
||||
AtualizadoEm pgtype.Timestamptz `json:"atualizado_em"`
|
||||
Email string `json:"email"`
|
||||
Email_2 string `json:"email_2"`
|
||||
FuncaoNome string `json:"funcao_nome"`
|
||||
StatusDisponibilidade string `json:"status_disponibilidade"`
|
||||
}
|
||||
|
|
@ -632,10 +635,11 @@ func (q *Queries) ListAvailableProfessionalsForDate(ctx context.Context, data pg
|
|||
&i.TabelaFree,
|
||||
&i.ExtraPorEquipamento,
|
||||
&i.Equipamentos,
|
||||
&i.Email,
|
||||
&i.AvatarUrl,
|
||||
&i.CriadoEm,
|
||||
&i.AtualizadoEm,
|
||||
&i.Email,
|
||||
&i.Email_2,
|
||||
&i.FuncaoNome,
|
||||
&i.StatusDisponibilidade,
|
||||
); err != nil {
|
||||
|
|
|
|||
|
|
@ -107,6 +107,7 @@ type CadastroProfissionai struct {
|
|||
TabelaFree pgtype.Text `json:"tabela_free"`
|
||||
ExtraPorEquipamento pgtype.Bool `json:"extra_por_equipamento"`
|
||||
Equipamentos pgtype.Text `json:"equipamentos"`
|
||||
Email pgtype.Text `json:"email"`
|
||||
AvatarUrl pgtype.Text `json:"avatar_url"`
|
||||
CriadoEm pgtype.Timestamptz `json:"criado_em"`
|
||||
AtualizadoEm pgtype.Timestamptz `json:"atualizado_em"`
|
||||
|
|
|
|||
|
|
@ -17,11 +17,11 @@ INSERT INTO cadastro_profissionais (
|
|||
cpf_cnpj_titular, banco, agencia, conta_pix, carro_disponivel,
|
||||
tem_estudio, qtd_estudio, tipo_cartao, observacao, qual_tec,
|
||||
educacao_simpatia, desempenho_evento, disp_horario, media,
|
||||
tabela_free, extra_por_equipamento, equipamentos, avatar_url
|
||||
tabela_free, extra_por_equipamento, equipamentos, email, avatar_url
|
||||
) VALUES (
|
||||
$1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15,
|
||||
$16, $17, $18, $19, $20, $21, $22, $23, $24, $25
|
||||
) RETURNING id, usuario_id, nome, funcao_profissional_id, endereco, cidade, uf, whatsapp, cpf_cnpj_titular, banco, agencia, conta_pix, carro_disponivel, tem_estudio, qtd_estudio, tipo_cartao, observacao, qual_tec, educacao_simpatia, desempenho_evento, disp_horario, media, tabela_free, extra_por_equipamento, equipamentos, avatar_url, criado_em, atualizado_em
|
||||
$16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26
|
||||
) RETURNING id, usuario_id, nome, funcao_profissional_id, endereco, cidade, uf, whatsapp, cpf_cnpj_titular, banco, agencia, conta_pix, carro_disponivel, tem_estudio, qtd_estudio, tipo_cartao, observacao, qual_tec, educacao_simpatia, desempenho_evento, disp_horario, media, tabela_free, extra_por_equipamento, equipamentos, email, avatar_url, criado_em, atualizado_em
|
||||
`
|
||||
|
||||
type CreateProfissionalParams struct {
|
||||
|
|
@ -49,6 +49,7 @@ type CreateProfissionalParams struct {
|
|||
TabelaFree pgtype.Text `json:"tabela_free"`
|
||||
ExtraPorEquipamento pgtype.Bool `json:"extra_por_equipamento"`
|
||||
Equipamentos pgtype.Text `json:"equipamentos"`
|
||||
Email pgtype.Text `json:"email"`
|
||||
AvatarUrl pgtype.Text `json:"avatar_url"`
|
||||
}
|
||||
|
||||
|
|
@ -78,6 +79,7 @@ func (q *Queries) CreateProfissional(ctx context.Context, arg CreateProfissional
|
|||
arg.TabelaFree,
|
||||
arg.ExtraPorEquipamento,
|
||||
arg.Equipamentos,
|
||||
arg.Email,
|
||||
arg.AvatarUrl,
|
||||
)
|
||||
var i CadastroProfissionai
|
||||
|
|
@ -107,6 +109,7 @@ func (q *Queries) CreateProfissional(ctx context.Context, arg CreateProfissional
|
|||
&i.TabelaFree,
|
||||
&i.ExtraPorEquipamento,
|
||||
&i.Equipamentos,
|
||||
&i.Email,
|
||||
&i.AvatarUrl,
|
||||
&i.CriadoEm,
|
||||
&i.AtualizadoEm,
|
||||
|
|
@ -125,7 +128,7 @@ func (q *Queries) DeleteProfissional(ctx context.Context, id pgtype.UUID) error
|
|||
}
|
||||
|
||||
const getProfissionalByID = `-- name: GetProfissionalByID :one
|
||||
SELECT p.id, p.usuario_id, p.nome, p.funcao_profissional_id, p.endereco, p.cidade, p.uf, p.whatsapp, p.cpf_cnpj_titular, p.banco, p.agencia, p.conta_pix, p.carro_disponivel, p.tem_estudio, p.qtd_estudio, p.tipo_cartao, p.observacao, p.qual_tec, p.educacao_simpatia, p.desempenho_evento, p.disp_horario, p.media, p.tabela_free, p.extra_por_equipamento, p.equipamentos, p.avatar_url, p.criado_em, p.atualizado_em, f.nome as funcao_nome
|
||||
SELECT p.id, p.usuario_id, p.nome, p.funcao_profissional_id, p.endereco, p.cidade, p.uf, p.whatsapp, p.cpf_cnpj_titular, p.banco, p.agencia, p.conta_pix, p.carro_disponivel, p.tem_estudio, p.qtd_estudio, p.tipo_cartao, p.observacao, p.qual_tec, p.educacao_simpatia, p.desempenho_evento, p.disp_horario, p.media, p.tabela_free, p.extra_por_equipamento, p.equipamentos, p.email, p.avatar_url, p.criado_em, p.atualizado_em, f.nome as funcao_nome
|
||||
FROM cadastro_profissionais p
|
||||
LEFT JOIN funcoes_profissionais f ON p.funcao_profissional_id = f.id
|
||||
WHERE p.id = $1 LIMIT 1
|
||||
|
|
@ -157,6 +160,7 @@ type GetProfissionalByIDRow struct {
|
|||
TabelaFree pgtype.Text `json:"tabela_free"`
|
||||
ExtraPorEquipamento pgtype.Bool `json:"extra_por_equipamento"`
|
||||
Equipamentos pgtype.Text `json:"equipamentos"`
|
||||
Email pgtype.Text `json:"email"`
|
||||
AvatarUrl pgtype.Text `json:"avatar_url"`
|
||||
CriadoEm pgtype.Timestamptz `json:"criado_em"`
|
||||
AtualizadoEm pgtype.Timestamptz `json:"atualizado_em"`
|
||||
|
|
@ -192,6 +196,7 @@ func (q *Queries) GetProfissionalByID(ctx context.Context, id pgtype.UUID) (GetP
|
|||
&i.TabelaFree,
|
||||
&i.ExtraPorEquipamento,
|
||||
&i.Equipamentos,
|
||||
&i.Email,
|
||||
&i.AvatarUrl,
|
||||
&i.CriadoEm,
|
||||
&i.AtualizadoEm,
|
||||
|
|
@ -201,7 +206,7 @@ func (q *Queries) GetProfissionalByID(ctx context.Context, id pgtype.UUID) (GetP
|
|||
}
|
||||
|
||||
const getProfissionalByUsuarioID = `-- name: GetProfissionalByUsuarioID :one
|
||||
SELECT p.id, p.usuario_id, p.nome, p.funcao_profissional_id, p.endereco, p.cidade, p.uf, p.whatsapp, p.cpf_cnpj_titular, p.banco, p.agencia, p.conta_pix, p.carro_disponivel, p.tem_estudio, p.qtd_estudio, p.tipo_cartao, p.observacao, p.qual_tec, p.educacao_simpatia, p.desempenho_evento, p.disp_horario, p.media, p.tabela_free, p.extra_por_equipamento, p.equipamentos, p.avatar_url, p.criado_em, p.atualizado_em, f.nome as funcao_nome
|
||||
SELECT p.id, p.usuario_id, p.nome, p.funcao_profissional_id, p.endereco, p.cidade, p.uf, p.whatsapp, p.cpf_cnpj_titular, p.banco, p.agencia, p.conta_pix, p.carro_disponivel, p.tem_estudio, p.qtd_estudio, p.tipo_cartao, p.observacao, p.qual_tec, p.educacao_simpatia, p.desempenho_evento, p.disp_horario, p.media, p.tabela_free, p.extra_por_equipamento, p.equipamentos, p.email, p.avatar_url, p.criado_em, p.atualizado_em, f.nome as funcao_nome
|
||||
FROM cadastro_profissionais p
|
||||
LEFT JOIN funcoes_profissionais f ON p.funcao_profissional_id = f.id
|
||||
WHERE p.usuario_id = $1 LIMIT 1
|
||||
|
|
@ -233,6 +238,7 @@ type GetProfissionalByUsuarioIDRow struct {
|
|||
TabelaFree pgtype.Text `json:"tabela_free"`
|
||||
ExtraPorEquipamento pgtype.Bool `json:"extra_por_equipamento"`
|
||||
Equipamentos pgtype.Text `json:"equipamentos"`
|
||||
Email pgtype.Text `json:"email"`
|
||||
AvatarUrl pgtype.Text `json:"avatar_url"`
|
||||
CriadoEm pgtype.Timestamptz `json:"criado_em"`
|
||||
AtualizadoEm pgtype.Timestamptz `json:"atualizado_em"`
|
||||
|
|
@ -268,6 +274,7 @@ func (q *Queries) GetProfissionalByUsuarioID(ctx context.Context, usuarioID pgty
|
|||
&i.TabelaFree,
|
||||
&i.ExtraPorEquipamento,
|
||||
&i.Equipamentos,
|
||||
&i.Email,
|
||||
&i.AvatarUrl,
|
||||
&i.CriadoEm,
|
||||
&i.AtualizadoEm,
|
||||
|
|
@ -277,7 +284,7 @@ func (q *Queries) GetProfissionalByUsuarioID(ctx context.Context, usuarioID pgty
|
|||
}
|
||||
|
||||
const listProfissionais = `-- name: ListProfissionais :many
|
||||
SELECT p.id, p.usuario_id, p.nome, p.funcao_profissional_id, p.endereco, p.cidade, p.uf, p.whatsapp, p.cpf_cnpj_titular, p.banco, p.agencia, p.conta_pix, p.carro_disponivel, p.tem_estudio, p.qtd_estudio, p.tipo_cartao, p.observacao, p.qual_tec, p.educacao_simpatia, p.desempenho_evento, p.disp_horario, p.media, p.tabela_free, p.extra_por_equipamento, p.equipamentos, p.avatar_url, p.criado_em, p.atualizado_em, f.nome as funcao_nome, u.email
|
||||
SELECT p.id, p.usuario_id, p.nome, p.funcao_profissional_id, p.endereco, p.cidade, p.uf, p.whatsapp, p.cpf_cnpj_titular, p.banco, p.agencia, p.conta_pix, p.carro_disponivel, p.tem_estudio, p.qtd_estudio, p.tipo_cartao, p.observacao, p.qual_tec, p.educacao_simpatia, p.desempenho_evento, p.disp_horario, p.media, p.tabela_free, p.extra_por_equipamento, p.equipamentos, p.email, p.avatar_url, p.criado_em, p.atualizado_em, f.nome as funcao_nome, u.email as usuario_email
|
||||
FROM cadastro_profissionais p
|
||||
LEFT JOIN funcoes_profissionais f ON p.funcao_profissional_id = f.id
|
||||
LEFT JOIN usuarios u ON p.usuario_id = u.id
|
||||
|
|
@ -310,11 +317,12 @@ type ListProfissionaisRow struct {
|
|||
TabelaFree pgtype.Text `json:"tabela_free"`
|
||||
ExtraPorEquipamento pgtype.Bool `json:"extra_por_equipamento"`
|
||||
Equipamentos pgtype.Text `json:"equipamentos"`
|
||||
Email pgtype.Text `json:"email"`
|
||||
AvatarUrl pgtype.Text `json:"avatar_url"`
|
||||
CriadoEm pgtype.Timestamptz `json:"criado_em"`
|
||||
AtualizadoEm pgtype.Timestamptz `json:"atualizado_em"`
|
||||
FuncaoNome pgtype.Text `json:"funcao_nome"`
|
||||
Email pgtype.Text `json:"email"`
|
||||
UsuarioEmail pgtype.Text `json:"usuario_email"`
|
||||
}
|
||||
|
||||
func (q *Queries) ListProfissionais(ctx context.Context) ([]ListProfissionaisRow, error) {
|
||||
|
|
@ -352,11 +360,12 @@ func (q *Queries) ListProfissionais(ctx context.Context) ([]ListProfissionaisRow
|
|||
&i.TabelaFree,
|
||||
&i.ExtraPorEquipamento,
|
||||
&i.Equipamentos,
|
||||
&i.Email,
|
||||
&i.AvatarUrl,
|
||||
&i.CriadoEm,
|
||||
&i.AtualizadoEm,
|
||||
&i.FuncaoNome,
|
||||
&i.Email,
|
||||
&i.UsuarioEmail,
|
||||
); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
@ -395,9 +404,10 @@ SET
|
|||
extra_por_equipamento = $23,
|
||||
equipamentos = $24,
|
||||
avatar_url = $25,
|
||||
email = $26,
|
||||
atualizado_em = NOW()
|
||||
WHERE id = $1
|
||||
RETURNING id, usuario_id, nome, funcao_profissional_id, endereco, cidade, uf, whatsapp, cpf_cnpj_titular, banco, agencia, conta_pix, carro_disponivel, tem_estudio, qtd_estudio, tipo_cartao, observacao, qual_tec, educacao_simpatia, desempenho_evento, disp_horario, media, tabela_free, extra_por_equipamento, equipamentos, avatar_url, criado_em, atualizado_em
|
||||
RETURNING id, usuario_id, nome, funcao_profissional_id, endereco, cidade, uf, whatsapp, cpf_cnpj_titular, banco, agencia, conta_pix, carro_disponivel, tem_estudio, qtd_estudio, tipo_cartao, observacao, qual_tec, educacao_simpatia, desempenho_evento, disp_horario, media, tabela_free, extra_por_equipamento, equipamentos, email, avatar_url, criado_em, atualizado_em
|
||||
`
|
||||
|
||||
type UpdateProfissionalParams struct {
|
||||
|
|
@ -426,6 +436,7 @@ type UpdateProfissionalParams struct {
|
|||
ExtraPorEquipamento pgtype.Bool `json:"extra_por_equipamento"`
|
||||
Equipamentos pgtype.Text `json:"equipamentos"`
|
||||
AvatarUrl pgtype.Text `json:"avatar_url"`
|
||||
Email pgtype.Text `json:"email"`
|
||||
}
|
||||
|
||||
func (q *Queries) UpdateProfissional(ctx context.Context, arg UpdateProfissionalParams) (CadastroProfissionai, error) {
|
||||
|
|
@ -455,6 +466,7 @@ func (q *Queries) UpdateProfissional(ctx context.Context, arg UpdateProfissional
|
|||
arg.ExtraPorEquipamento,
|
||||
arg.Equipamentos,
|
||||
arg.AvatarUrl,
|
||||
arg.Email,
|
||||
)
|
||||
var i CadastroProfissionai
|
||||
err := row.Scan(
|
||||
|
|
@ -483,6 +495,7 @@ func (q *Queries) UpdateProfissional(ctx context.Context, arg UpdateProfissional
|
|||
&i.TabelaFree,
|
||||
&i.ExtraPorEquipamento,
|
||||
&i.Equipamentos,
|
||||
&i.Email,
|
||||
&i.AvatarUrl,
|
||||
&i.CriadoEm,
|
||||
&i.AtualizadoEm,
|
||||
|
|
|
|||
|
|
@ -4,10 +4,10 @@ INSERT INTO cadastro_profissionais (
|
|||
cpf_cnpj_titular, banco, agencia, conta_pix, carro_disponivel,
|
||||
tem_estudio, qtd_estudio, tipo_cartao, observacao, qual_tec,
|
||||
educacao_simpatia, desempenho_evento, disp_horario, media,
|
||||
tabela_free, extra_por_equipamento, equipamentos, avatar_url
|
||||
tabela_free, extra_por_equipamento, equipamentos, email, avatar_url
|
||||
) VALUES (
|
||||
$1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15,
|
||||
$16, $17, $18, $19, $20, $21, $22, $23, $24, $25
|
||||
$16, $17, $18, $19, $20, $21, $22, $23, $24, $25, $26
|
||||
) RETURNING *;
|
||||
|
||||
-- name: GetProfissionalByUsuarioID :one
|
||||
|
|
@ -23,7 +23,7 @@ LEFT JOIN funcoes_profissionais f ON p.funcao_profissional_id = f.id
|
|||
WHERE p.id = $1 LIMIT 1;
|
||||
|
||||
-- name: ListProfissionais :many
|
||||
SELECT p.*, f.nome as funcao_nome, u.email
|
||||
SELECT p.*, f.nome as funcao_nome, u.email as usuario_email
|
||||
FROM cadastro_profissionais p
|
||||
LEFT JOIN funcoes_profissionais f ON p.funcao_profissional_id = f.id
|
||||
LEFT JOIN usuarios u ON p.usuario_id = u.id
|
||||
|
|
@ -56,6 +56,7 @@ SET
|
|||
extra_por_equipamento = $23,
|
||||
equipamentos = $24,
|
||||
avatar_url = $25,
|
||||
email = $26,
|
||||
atualizado_em = NOW()
|
||||
WHERE id = $1
|
||||
RETURNING *;
|
||||
|
|
|
|||
|
|
@ -52,6 +52,7 @@ CREATE TABLE IF NOT EXISTS cadastro_profissionais (
|
|||
tabela_free VARCHAR(50),
|
||||
extra_por_equipamento BOOLEAN DEFAULT FALSE,
|
||||
equipamentos TEXT,
|
||||
email VARCHAR(255),
|
||||
avatar_url VARCHAR(255),
|
||||
criado_em TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
atualizado_em TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
||||
|
|
|
|||
|
|
@ -46,7 +46,8 @@ type ProfissionalResponse struct {
|
|||
TabelaFree *string `json:"tabela_free"`
|
||||
ExtraPorEquipamento *bool `json:"extra_por_equipamento"`
|
||||
Equipamentos *string `json:"equipamentos"`
|
||||
Email string `json:"email"`
|
||||
Email *string `json:"email"`
|
||||
AvatarURL *string `json:"avatar_url"`
|
||||
}
|
||||
|
||||
func toResponse(p interface{}) ProfissionalResponse {
|
||||
|
|
@ -84,6 +85,8 @@ func toResponse(p interface{}) ProfissionalResponse {
|
|||
TabelaFree: fromPgText(v.TabelaFree),
|
||||
ExtraPorEquipamento: fromPgBool(v.ExtraPorEquipamento),
|
||||
Equipamentos: fromPgText(v.Equipamentos),
|
||||
Email: fromPgText(v.Email),
|
||||
AvatarURL: fromPgText(v.AvatarUrl),
|
||||
}
|
||||
case generated.ListProfissionaisRow:
|
||||
return ProfissionalResponse{
|
||||
|
|
@ -113,7 +116,8 @@ func toResponse(p interface{}) ProfissionalResponse {
|
|||
TabelaFree: fromPgText(v.TabelaFree),
|
||||
ExtraPorEquipamento: fromPgBool(v.ExtraPorEquipamento),
|
||||
Equipamentos: fromPgText(v.Equipamentos),
|
||||
Email: v.Email.String,
|
||||
Email: fromPgText(v.Email),
|
||||
AvatarURL: fromPgText(v.AvatarUrl),
|
||||
}
|
||||
case generated.GetProfissionalByIDRow:
|
||||
return ProfissionalResponse{
|
||||
|
|
@ -143,6 +147,7 @@ func toResponse(p interface{}) ProfissionalResponse {
|
|||
TabelaFree: fromPgText(v.TabelaFree),
|
||||
ExtraPorEquipamento: fromPgBool(v.ExtraPorEquipamento),
|
||||
Equipamentos: fromPgText(v.Equipamentos),
|
||||
AvatarURL: fromPgText(v.AvatarUrl),
|
||||
}
|
||||
default:
|
||||
return ProfissionalResponse{}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package profissionais
|
|||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"photum-backend/internal/db/generated"
|
||||
|
||||
|
|
@ -42,6 +43,7 @@ type CreateProfissionalInput struct {
|
|||
TabelaFree *string `json:"tabela_free"`
|
||||
ExtraPorEquipamento *bool `json:"extra_por_equipamento"`
|
||||
Equipamentos *string `json:"equipamentos"`
|
||||
Email *string `json:"email"`
|
||||
AvatarURL *string `json:"avatar_url"`
|
||||
}
|
||||
|
||||
|
|
@ -89,6 +91,7 @@ func (s *Service) Create(ctx context.Context, userID string, input CreateProfiss
|
|||
TabelaFree: toPgText(input.TabelaFree),
|
||||
ExtraPorEquipamento: toPgBool(input.ExtraPorEquipamento),
|
||||
Equipamentos: toPgText(input.Equipamentos),
|
||||
Email: toPgText(input.Email),
|
||||
AvatarUrl: toPgText(input.AvatarURL),
|
||||
}
|
||||
|
||||
|
|
@ -139,6 +142,7 @@ type UpdateProfissionalInput struct {
|
|||
TabelaFree *string `json:"tabela_free"`
|
||||
ExtraPorEquipamento *bool `json:"extra_por_equipamento"`
|
||||
Equipamentos *string `json:"equipamentos"`
|
||||
Email *string `json:"email"`
|
||||
AvatarURL *string `json:"avatar_url"`
|
||||
}
|
||||
|
||||
|
|
@ -178,6 +182,7 @@ func (s *Service) Update(ctx context.Context, id string, input UpdateProfissiona
|
|||
TabelaFree: toPgText(input.TabelaFree),
|
||||
ExtraPorEquipamento: toPgBool(input.ExtraPorEquipamento),
|
||||
Equipamentos: toPgText(input.Equipamentos),
|
||||
Email: toPgText(input.Email),
|
||||
AvatarUrl: toPgText(input.AvatarURL),
|
||||
}
|
||||
|
||||
|
|
@ -224,6 +229,8 @@ func toPgNumeric(f *float64) pgtype.Numeric {
|
|||
return pgtype.Numeric{Valid: false}
|
||||
}
|
||||
var n pgtype.Numeric
|
||||
n.Scan(f)
|
||||
if err := n.Scan(fmt.Sprintf("%f", *f)); err != nil {
|
||||
return pgtype.Numeric{Valid: false}
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -115,6 +115,108 @@ export async function createProfessional(data: any, token?: string): Promise<Api
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Atualiza um profissional existente
|
||||
*/
|
||||
export async function updateProfessional(id: string, data: any, token: string): Promise<ApiResponse<any>> {
|
||||
try {
|
||||
const response = await fetch(`${API_BASE_URL}/api/profissionais/${id}`, {
|
||||
method: "PUT",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": `Bearer ${token}`
|
||||
},
|
||||
body: JSON.stringify(data),
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}));
|
||||
throw new Error(errorData.error || `HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
const responseData = await response.json();
|
||||
return {
|
||||
data: responseData,
|
||||
error: null,
|
||||
isBackendDown: false,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error("Error updating professional:", error);
|
||||
return {
|
||||
data: null,
|
||||
error: error instanceof Error ? error.message : "Erro desconhecido",
|
||||
isBackendDown: true,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove um profissional
|
||||
*/
|
||||
export async function deleteProfessional(id: string, token: string): Promise<ApiResponse<void>> {
|
||||
try {
|
||||
const response = await fetch(`${API_BASE_URL}/api/profissionais/${id}`, {
|
||||
method: "DELETE",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": `Bearer ${token}`
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
const errorData = await response.json().catch(() => ({}));
|
||||
throw new Error(errorData.error || `HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
return {
|
||||
data: null,
|
||||
error: null,
|
||||
isBackendDown: false,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error("Error deleting professional:", error);
|
||||
return {
|
||||
data: null,
|
||||
error: error instanceof Error ? error.message : "Erro desconhecido",
|
||||
isBackendDown: true,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Busca um profissional pelo ID
|
||||
*/
|
||||
export async function getProfessionalById(id: string, token: string): Promise<ApiResponse<any>> {
|
||||
try {
|
||||
const response = await fetch(`${API_BASE_URL}/api/profissionais/${id}`, {
|
||||
method: "GET",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
"Authorization": `Bearer ${token}`
|
||||
},
|
||||
});
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
return {
|
||||
data,
|
||||
error: null,
|
||||
isBackendDown: false,
|
||||
};
|
||||
} catch (error) {
|
||||
console.error("Error fetching professional by id:", error);
|
||||
return {
|
||||
data: null,
|
||||
error: error instanceof Error ? error.message : "Erro desconhecido",
|
||||
isBackendDown: true,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Busca a lista de profissionais
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -144,13 +144,75 @@ export interface EventData {
|
|||
assignments?: Assignment[]; // Lista de status de atribuições
|
||||
}
|
||||
|
||||
|
||||
export interface Professional {
|
||||
id: string;
|
||||
usuarioId: string;
|
||||
name: string;
|
||||
email: string; // Added via JOIN
|
||||
role: string; // Funcao nome
|
||||
avatar?: string;
|
||||
usuario_id?: string;
|
||||
nome: string;
|
||||
email?: string;
|
||||
funcao_profissional_id: string;
|
||||
role?: string; // Optional, for UI display if needed (e.g. from join)
|
||||
avatar?: string; // Legacy/UI
|
||||
avatar_url?: string; // Backend field
|
||||
phone?: string;
|
||||
availability: { [date: string]: boolean }; // Mocked or fetched? For now let's keep compatibility with mock structure
|
||||
|
||||
// Detailed fields matching backend
|
||||
endereco?: string;
|
||||
cidade?: string;
|
||||
uf?: string;
|
||||
cep?: string;
|
||||
whatsapp?: string;
|
||||
cpf_cnpj_titular?: string;
|
||||
banco?: string;
|
||||
agencia?: string;
|
||||
conta_pix?: string;
|
||||
carro_disponivel?: boolean;
|
||||
tem_estudio?: boolean;
|
||||
qtd_estudio?: number;
|
||||
tipo_cartao?: string;
|
||||
observacao?: string;
|
||||
|
||||
// Ratings
|
||||
qual_tec?: number;
|
||||
educacao_simpatia?: number;
|
||||
desempenho_evento?: number;
|
||||
disp_horario?: number;
|
||||
media?: number;
|
||||
|
||||
tabela_free?: string;
|
||||
extra_por_equipamento?: boolean;
|
||||
equipamentos?: string;
|
||||
|
||||
// Availability (kept for compatibility, though might not be in main payload)
|
||||
availability?: { [date: string]: boolean };
|
||||
}
|
||||
|
||||
export interface CreateProfessionalDTO {
|
||||
nome: string;
|
||||
funcao_profissional_id: string;
|
||||
email?: string;
|
||||
endereco?: string;
|
||||
cidade?: string;
|
||||
uf?: string;
|
||||
cep?: string;
|
||||
whatsapp?: string;
|
||||
cpf_cnpj_titular?: string;
|
||||
banco?: string;
|
||||
agencia?: string;
|
||||
conta_pix?: string;
|
||||
carro_disponivel?: boolean;
|
||||
tem_estudio?: boolean;
|
||||
qtd_estudio?: number;
|
||||
tipo_cartao?: string;
|
||||
observacao?: string;
|
||||
qual_tec?: number;
|
||||
educacao_simpatia?: number;
|
||||
desempenho_evento?: number;
|
||||
disp_horario?: number;
|
||||
media?: number;
|
||||
tabela_free?: string;
|
||||
extra_por_equipamento?: boolean;
|
||||
equipamentos?: string;
|
||||
avatar_url?: string;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue