feat: redesign superadmin agencies list, implement flat design, add date filters, and fix UI bugs
This commit is contained in:
@@ -19,14 +19,21 @@ func NewTenantRepository(db *sql.DB) *TenantRepository {
|
||||
return &TenantRepository{db: db}
|
||||
}
|
||||
|
||||
// DB returns the underlying database connection
|
||||
func (r *TenantRepository) DB() *sql.DB {
|
||||
return r.db
|
||||
}
|
||||
|
||||
// Create creates a new tenant
|
||||
func (r *TenantRepository) Create(tenant *domain.Tenant) error {
|
||||
query := `
|
||||
INSERT INTO tenants (
|
||||
id, name, domain, subdomain, cnpj, razao_social, email, website,
|
||||
address, city, state, zip, description, industry, created_at, updated_at
|
||||
id, name, domain, subdomain, cnpj, razao_social, email, phone, website,
|
||||
address, neighborhood, number, complement, city, state, zip,
|
||||
description, industry, team_size, primary_color, secondary_color,
|
||||
logo_url, logo_horizontal_url, created_at, updated_at
|
||||
)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16)
|
||||
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, created_at, updated_at
|
||||
`
|
||||
|
||||
@@ -44,13 +51,22 @@ func (r *TenantRepository) Create(tenant *domain.Tenant) error {
|
||||
tenant.CNPJ,
|
||||
tenant.RazaoSocial,
|
||||
tenant.Email,
|
||||
tenant.Phone,
|
||||
tenant.Website,
|
||||
tenant.Address,
|
||||
tenant.Neighborhood,
|
||||
tenant.Number,
|
||||
tenant.Complement,
|
||||
tenant.City,
|
||||
tenant.State,
|
||||
tenant.Zip,
|
||||
tenant.Description,
|
||||
tenant.Industry,
|
||||
tenant.TeamSize,
|
||||
tenant.PrimaryColor,
|
||||
tenant.SecondaryColor,
|
||||
tenant.LogoURL,
|
||||
tenant.LogoHorizontalURL,
|
||||
tenant.CreatedAt,
|
||||
tenant.UpdatedAt,
|
||||
).Scan(&tenant.ID, &tenant.CreatedAt, &tenant.UpdatedAt)
|
||||
@@ -59,14 +75,16 @@ func (r *TenantRepository) Create(tenant *domain.Tenant) error {
|
||||
// FindByID finds a tenant by ID
|
||||
func (r *TenantRepository) FindByID(id uuid.UUID) (*domain.Tenant, error) {
|
||||
query := `
|
||||
SELECT id, name, domain, subdomain, cnpj, razao_social, email, phone, website,
|
||||
address, city, state, zip, description, industry, is_active, created_at, updated_at
|
||||
SELECT id, name, domain, subdomain, cnpj, razao_social, email, phone, website,
|
||||
address, neighborhood, number, complement, city, state, zip, description, industry, team_size,
|
||||
primary_color, secondary_color, logo_url, logo_horizontal_url,
|
||||
is_active, created_at, updated_at
|
||||
FROM tenants
|
||||
WHERE id = $1
|
||||
`
|
||||
|
||||
tenant := &domain.Tenant{}
|
||||
var cnpj, razaoSocial, email, phone, website, address, city, state, zip, description, industry sql.NullString
|
||||
var cnpj, razaoSocial, email, phone, website, address, neighborhood, number, complement, city, state, zip, description, industry, teamSize, primaryColor, secondaryColor, logoURL, logoHorizontalURL sql.NullString
|
||||
|
||||
err := r.db.QueryRow(query, id).Scan(
|
||||
&tenant.ID,
|
||||
@@ -79,11 +97,19 @@ func (r *TenantRepository) FindByID(id uuid.UUID) (*domain.Tenant, error) {
|
||||
&phone,
|
||||
&website,
|
||||
&address,
|
||||
&neighborhood,
|
||||
&number,
|
||||
&complement,
|
||||
&city,
|
||||
&state,
|
||||
&zip,
|
||||
&description,
|
||||
&industry,
|
||||
&teamSize,
|
||||
&primaryColor,
|
||||
&secondaryColor,
|
||||
&logoURL,
|
||||
&logoHorizontalURL,
|
||||
&tenant.IsActive,
|
||||
&tenant.CreatedAt,
|
||||
&tenant.UpdatedAt,
|
||||
@@ -116,6 +142,15 @@ func (r *TenantRepository) FindByID(id uuid.UUID) (*domain.Tenant, error) {
|
||||
if address.Valid {
|
||||
tenant.Address = address.String
|
||||
}
|
||||
if neighborhood.Valid {
|
||||
tenant.Neighborhood = neighborhood.String
|
||||
}
|
||||
if number.Valid {
|
||||
tenant.Number = number.String
|
||||
}
|
||||
if complement.Valid {
|
||||
tenant.Complement = complement.String
|
||||
}
|
||||
if city.Valid {
|
||||
tenant.City = city.String
|
||||
}
|
||||
@@ -131,6 +166,21 @@ func (r *TenantRepository) FindByID(id uuid.UUID) (*domain.Tenant, error) {
|
||||
if industry.Valid {
|
||||
tenant.Industry = industry.String
|
||||
}
|
||||
if teamSize.Valid {
|
||||
tenant.TeamSize = teamSize.String
|
||||
}
|
||||
if primaryColor.Valid {
|
||||
tenant.PrimaryColor = primaryColor.String
|
||||
}
|
||||
if secondaryColor.Valid {
|
||||
tenant.SecondaryColor = secondaryColor.String
|
||||
}
|
||||
if logoURL.Valid {
|
||||
tenant.LogoURL = logoURL.String
|
||||
}
|
||||
if logoHorizontalURL.Valid {
|
||||
tenant.LogoHorizontalURL = logoHorizontalURL.String
|
||||
}
|
||||
|
||||
return tenant, nil
|
||||
}
|
||||
@@ -171,7 +221,7 @@ func (r *TenantRepository) SubdomainExists(subdomain string) (bool, error) {
|
||||
// FindAll returns all tenants
|
||||
func (r *TenantRepository) FindAll() ([]*domain.Tenant, error) {
|
||||
query := `
|
||||
SELECT id, name, domain, subdomain, is_active, created_at, updated_at
|
||||
SELECT id, name, domain, subdomain, email, phone, cnpj, logo_url, is_active, created_at, updated_at
|
||||
FROM tenants
|
||||
ORDER BY created_at DESC
|
||||
`
|
||||
@@ -185,11 +235,17 @@ func (r *TenantRepository) FindAll() ([]*domain.Tenant, error) {
|
||||
var tenants []*domain.Tenant
|
||||
for rows.Next() {
|
||||
tenant := &domain.Tenant{}
|
||||
var email, phone, cnpj, logoURL sql.NullString
|
||||
|
||||
err := rows.Scan(
|
||||
&tenant.ID,
|
||||
&tenant.Name,
|
||||
&tenant.Domain,
|
||||
&tenant.Subdomain,
|
||||
&email,
|
||||
&phone,
|
||||
&cnpj,
|
||||
&logoURL,
|
||||
&tenant.IsActive,
|
||||
&tenant.CreatedAt,
|
||||
&tenant.UpdatedAt,
|
||||
@@ -197,6 +253,20 @@ func (r *TenantRepository) FindAll() ([]*domain.Tenant, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if email.Valid {
|
||||
tenant.Email = email.String
|
||||
}
|
||||
if phone.Valid {
|
||||
tenant.Phone = phone.String
|
||||
}
|
||||
if cnpj.Valid {
|
||||
tenant.CNPJ = cnpj.String
|
||||
}
|
||||
if logoURL.Valid {
|
||||
tenant.LogoURL = logoURL.String
|
||||
}
|
||||
|
||||
tenants = append(tenants, tenant)
|
||||
}
|
||||
|
||||
@@ -209,7 +279,21 @@ func (r *TenantRepository) FindAll() ([]*domain.Tenant, error) {
|
||||
|
||||
// Delete removes a tenant (and cascades to related data)
|
||||
func (r *TenantRepository) Delete(id uuid.UUID) error {
|
||||
result, err := r.db.Exec(`DELETE FROM tenants WHERE id = $1`, id)
|
||||
// Start transaction
|
||||
tx, err := r.db.Begin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer tx.Rollback()
|
||||
|
||||
// Delete all users associated with this tenant first
|
||||
_, err = tx.Exec(`DELETE FROM users WHERE tenant_id = $1`, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Delete the tenant
|
||||
result, err := tx.Exec(`DELETE FROM tenants WHERE id = $1`, id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -223,7 +307,8 @@ func (r *TenantRepository) Delete(id uuid.UUID) error {
|
||||
return sql.ErrNoRows
|
||||
}
|
||||
|
||||
return nil
|
||||
// Commit transaction
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
// UpdateProfile updates tenant profile information
|
||||
@@ -237,13 +322,21 @@ func (r *TenantRepository) UpdateProfile(id uuid.UUID, updates map[string]interf
|
||||
phone = COALESCE($5, phone),
|
||||
website = COALESCE($6, website),
|
||||
address = COALESCE($7, address),
|
||||
city = COALESCE($8, city),
|
||||
state = COALESCE($9, state),
|
||||
zip = COALESCE($10, zip),
|
||||
description = COALESCE($11, description),
|
||||
industry = COALESCE($12, industry),
|
||||
updated_at = $13
|
||||
WHERE id = $14
|
||||
neighborhood = COALESCE($8, neighborhood),
|
||||
number = COALESCE($9, number),
|
||||
complement = COALESCE($10, complement),
|
||||
city = COALESCE($11, city),
|
||||
state = COALESCE($12, state),
|
||||
zip = COALESCE($13, zip),
|
||||
description = COALESCE($14, description),
|
||||
industry = COALESCE($15, industry),
|
||||
team_size = COALESCE($16, team_size),
|
||||
primary_color = COALESCE($17, primary_color),
|
||||
secondary_color = COALESCE($18, secondary_color),
|
||||
logo_url = COALESCE($19, logo_url),
|
||||
logo_horizontal_url = COALESCE($20, logo_horizontal_url),
|
||||
updated_at = $21
|
||||
WHERE id = $22
|
||||
`
|
||||
|
||||
_, err := r.db.Exec(
|
||||
@@ -255,14 +348,29 @@ func (r *TenantRepository) UpdateProfile(id uuid.UUID, updates map[string]interf
|
||||
updates["phone"],
|
||||
updates["website"],
|
||||
updates["address"],
|
||||
updates["neighborhood"],
|
||||
updates["number"],
|
||||
updates["complement"],
|
||||
updates["city"],
|
||||
updates["state"],
|
||||
updates["zip"],
|
||||
updates["description"],
|
||||
updates["industry"],
|
||||
updates["team_size"],
|
||||
updates["primary_color"],
|
||||
updates["secondary_color"],
|
||||
updates["logo_url"],
|
||||
updates["logo_horizontal_url"],
|
||||
time.Now(),
|
||||
id,
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// UpdateStatus updates the is_active status of a tenant
|
||||
func (r *TenantRepository) UpdateStatus(id uuid.UUID, isActive bool) error {
|
||||
query := `UPDATE tenants SET is_active = $1, updated_at = $2 WHERE id = $3`
|
||||
_, err := r.db.Exec(query, isActive, time.Now(), id)
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user