fix:(equipe) ajustado cadastro por regiao no acesso master
This commit is contained in:
parent
82b597bda3
commit
c5f1c40243
4 changed files with 37 additions and 12 deletions
|
|
@ -282,21 +282,24 @@ func (h *Handler) Create(c *gin.Context) {
|
|||
}
|
||||
|
||||
// Security: Only allow TargetUserID if user is ADMIN or OWNER
|
||||
// Also handle Region override
|
||||
userRole, _ := c.Get("role")
|
||||
roleStr, _ := userRole.(string)
|
||||
|
||||
if input.TargetUserID != nil && *input.TargetUserID != "" {
|
||||
userRole, exists := c.Get("role")
|
||||
if !exists {
|
||||
// Should validation fail? Or just ignore target?
|
||||
// Safer to ignore target user ID if role not found
|
||||
if roleStr != "SUPERADMIN" && roleStr != "BUSINESS_OWNER" {
|
||||
input.TargetUserID = nil
|
||||
} else {
|
||||
roleStr, ok := userRole.(string)
|
||||
if !ok || (roleStr != "SUPERADMIN" && roleStr != "BUSINESS_OWNER") {
|
||||
input.TargetUserID = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
regiao := c.GetString("regiao")
|
||||
// If input has regiao and user is admin, use it
|
||||
if input.Regiao != nil && *input.Regiao != "" {
|
||||
if roleStr == "SUPERADMIN" || roleStr == "BUSINESS_OWNER" {
|
||||
regiao = *input.Regiao
|
||||
}
|
||||
}
|
||||
|
||||
prof, err := h.service.Create(c.Request.Context(), userIDStr, input, regiao)
|
||||
if err != nil {
|
||||
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ type CreateProfissionalInput struct {
|
|||
Email *string `json:"email"`
|
||||
AvatarURL *string `json:"avatar_url"`
|
||||
TargetUserID *string `json:"target_user_id"` // Optional: For admin creation
|
||||
Regiao *string `json:"regiao"` // Optional: Override region
|
||||
}
|
||||
|
||||
func (s *Service) Create(ctx context.Context, userID string, input CreateProfissionalInput, regiao string) (*generated.GetProfissionalByIDRow, error) {
|
||||
|
|
|
|||
|
|
@ -35,11 +35,12 @@ export const ProfessionalModal: React.FC<ProfessionalModalProps> = ({
|
|||
roles,
|
||||
onSuccess,
|
||||
}) => {
|
||||
const { token: contextToken } = useAuth();
|
||||
const { token: contextToken, user } = useAuth(); // Get User
|
||||
const token = contextToken || "";
|
||||
|
||||
const initialFormState: CreateProfessionalDTO & { senha?: string; confirmarSenha?: string } = {
|
||||
nome: "",
|
||||
regiao: "",
|
||||
funcao_profissional_id: "",
|
||||
funcoes_ids: [],
|
||||
email: "",
|
||||
|
|
@ -87,6 +88,7 @@ export const ProfessionalModal: React.FC<ProfessionalModalProps> = ({
|
|||
// Edit Mode
|
||||
setFormData({
|
||||
nome: professional.nome,
|
||||
regiao: professional.regiao || "",
|
||||
funcao_profissional_id: professional.funcao_profissional_id,
|
||||
funcoes_ids: professional.functions?.map(f => f.id) || (professional.funcao_profissional_id ? [professional.funcao_profissional_id] : []),
|
||||
email: professional.email || "",
|
||||
|
|
@ -119,12 +121,13 @@ export const ProfessionalModal: React.FC<ProfessionalModalProps> = ({
|
|||
setAvatarPreview(professional.avatar_url || (professional.avatar ?? GenericAvatar));
|
||||
} else {
|
||||
// Add Mode
|
||||
setFormData(initialFormState);
|
||||
const defaultRegion = user?.allowedRegions && user.allowedRegions.length > 0 ? user.allowedRegions[0] : "SP";
|
||||
setFormData({ ...initialFormState, regiao: defaultRegion });
|
||||
setAvatarPreview("");
|
||||
}
|
||||
setAvatarFile(null);
|
||||
}
|
||||
}, [isOpen, professional]);
|
||||
}, [isOpen, professional]); // user dependency intentionally omitted to avoid reset loop, but safe to add if needed
|
||||
|
||||
// Helpers
|
||||
const maskPhone = (value: string) => {
|
||||
|
|
@ -387,6 +390,22 @@ export const ProfessionalModal: React.FC<ProfessionalModalProps> = ({
|
|||
</div>
|
||||
</div>
|
||||
|
||||
{/* Region Selection (Only for Multi-Region Admins) */}
|
||||
{(user?.allowedRegions && user.allowedRegions.length > 1) || user?.role === "SUPERADMIN" ? (
|
||||
<div className="mb-4">
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">Região de Atuação *</label>
|
||||
<select
|
||||
value={formData.regiao || ""}
|
||||
onChange={e => setFormData({ ...formData, regiao: e.target.value })}
|
||||
className="block w-full rounded-md border-gray-300 shadow-sm focus:border-brand-gold focus:ring focus:ring-brand-gold focus:ring-opacity-50 p-2 border"
|
||||
>
|
||||
<option value="SP">São Paulo (SP)</option>
|
||||
<option value="MG">Minas Gerais (MG)</option>
|
||||
</select>
|
||||
<p className="text-xs text-gray-500 mt-1">Selecione onde este profissional irá atuar.</p>
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
{/* Seleção de Função (Movida para o topo) */}
|
||||
<div className="col-span-1 md:col-span-2 mb-4">
|
||||
<label className="block text-sm font-medium text-gray-700 mb-1">
|
||||
|
|
|
|||
|
|
@ -166,6 +166,7 @@ export interface Professional {
|
|||
id: string;
|
||||
usuario_id?: string;
|
||||
nome: string;
|
||||
regiao?: string; // Add region to interface
|
||||
name?: string; // Restore for compatibility
|
||||
email?: string;
|
||||
funcao_profissional_id: string;
|
||||
|
|
@ -209,6 +210,7 @@ export interface Professional {
|
|||
|
||||
export interface CreateProfessionalDTO {
|
||||
nome: string;
|
||||
regiao?: string;
|
||||
funcao_profissional_id: string; // Keep for compatibility (primary function)
|
||||
funcoes_ids?: string[]; // New multi-select
|
||||
email?: string;
|
||||
|
|
|
|||
Loading…
Reference in a new issue