import flet as ft import requests from helpers.roles import Roles class ArticlesSettings: def __init__(self, page: ft.Page): self.page = page self.base_url = self.page.session.store.get('api_base_url') self.token = self.page.session.store.get('token') self.search_bar = ft.TextField( label="Caută expert...", prefix_icon=ft.Icons.SEARCH, on_change=self.on_search_change, expand=True ) self.experts_list = ft.ListView( spacing=10, expand=True, padding=10 ) self.all_experts = [] def get_experts(self): try: response = requests.get( f"{self.base_url}/users/", headers={'Authorization': f'Bearer {self.token}'} ) if response.status_code == 200: users = response.json() # Filtrăm doar utilizatorii cu rol de expert sau ba self.all_experts = [u for u in users if u.get('role') in [Roles.EXPERT, Roles.BA]] return self.all_experts except Exception as e: print(f"Error fetching experts: {e}") return [] def load_experts_list(self, query=""): self.experts_list.controls.clear() query = query.strip().lower() filtered = [ exp for exp in self.all_experts if query in f"{exp.get('first_name', '')} {exp.get('last_name', '')} {exp.get('email', '')}".lower() ] if not filtered: self.experts_list.controls.append( ft.Container( content=ft.Text("Nu s-au găsit experți.", size=16, color=ft.Colors.GREY_600), alignment=ft.Alignment.CENTER, padding=20 ) ) else: for exp in filtered: expert_id = exp['id'] name = f"{exp.get('first_name') or ''} {exp.get('last_name') or ''}".strip() or "Nume nespecificat" email = exp.get('email', 'Email nespecificat') role_label = exp.get('role', '').upper() can_create = exp.get('can_create_articles') == 1 self.experts_list.controls.append( ft.Container( content=ft.Row( [ ft.Row( [ ft.CircleAvatar( content=ft.Icon(ft.Icons.PERSON, color=ft.Colors.BLUE_800), bgcolor=ft.Colors.BLUE_50, radius=20 ), ft.Column( [ ft.Text(name, weight=ft.FontWeight.BOLD, size=15), ft.Row( [ ft.Text(email, size=13, color=ft.Colors.GREY_600), ft.Container( content=ft.Text(role_label, size=10, color=ft.Colors.BLUE_800, weight=ft.FontWeight.BOLD), bgcolor=ft.Colors.BLUE_50, padding=ft.Padding(5, 2, 5, 2), border_radius=4 ) ], spacing=10 ) ], alignment=ft.MainAxisAlignment.CENTER, spacing=2 ) ], spacing=15 ), ft.Switch( value=can_create, on_change=lambda e, uid=expert_id, uemail=email: self.toggle_permission(e, uid, uemail) ) ], alignment=ft.MainAxisAlignment.SPACE_BETWEEN ), bgcolor=ft.Colors.WHITE, padding=15, border_radius=10, border=ft.Border.all(1, ft.Colors.GREY_200), shadow=ft.BoxShadow( blur_radius=4, color=ft.Colors.with_opacity(0.05, ft.Colors.BLACK), offset=ft.Offset(0, 2) ) ) ) def toggle_permission(self, e, user_id, user_email): new_val = 1 if e.control.value else 0 try: payload = {"can_create_articles": new_val} response = requests.put( f"{self.base_url}/users/update/{user_id}", json=payload, headers={'Authorization': f'Bearer {self.token}'} ) if response.status_code == 200: # Update local data model for exp in self.all_experts: if exp['id'] == user_id: exp['can_create_articles'] = new_val break status_msg = "permisiune acordată" if new_val == 1 else "permisiune retrasă" self.show_snack_bar(f"Drepturi actualizate pentru {user_email}: {status_msg}.", ft.Colors.GREEN) else: e.control.value = not e.control.value e.control.update() self.show_snack_bar("Eroare la salvarea permisiunilor.", ft.Colors.RED) except Exception as ex: print(f"Error toggling permission: {ex}") e.control.value = not e.control.value e.control.update() self.show_snack_bar("Eroare de conexiune la server.", ft.Colors.RED) def on_search_change(self, e): self.load_experts_list(self.search_bar.value) def show_snack_bar(self, message, color): self.page.snack_bar = ft.SnackBar( content=ft.Text(message, color=ft.Colors.WHITE), bgcolor=color, duration=3000 ) self.page.snack_bar.open = True self.page.update() def build(self): self.get_experts() self.load_experts_list() return ft.Container( content=ft.Column( [ ft.Container( content=ft.Column( [ ft.Text("Configurare Drepturi Publicare", size=20, weight=ft.FontWeight.BOLD), ft.Text( "Permiteți sau blocați dreptul experților de a crea, edita și șterge publicații de pe blog.", size=14, color=ft.Colors.GREY_600 ), ], spacing=5 ), margin=ft.Margin(0, 0, 0, 10) ), ft.Row([self.search_bar]), ft.Divider(height=10, color=ft.Colors.GREY_100), self.experts_list ], expand=True ), expand=True, padding=20, bgcolor=ft.Colors.GREY_50 )