init commit

This commit is contained in:
2025-08-31 17:55:26 +03:00
commit 876ddec94a
78 changed files with 11999 additions and 0 deletions

View File

@@ -0,0 +1,233 @@
import flet as ft
import requests
from config import API_BASE_URL
class DestinationsPage:
def __init__(self, page: ft.Page, dashboard):
self.page = page
self.dashboard = dashboard
self.destinations = []
self.destinations_column = ft.Column(expand=True, spacing=10, scroll=ft.ScrollMode.ADAPTIVE,)
self.dialog = None
self.delete_alert = None
self.current_edit = None
self.subscription_error = ft.Text("Please subscribe to add new destination", color=ft.Colors.RED)
def refresh(self):
self.destinations_column.controls.clear()
token = self.page.client_storage.get("token")
if not token:
print("Missing token.")
return
headers = {"Authorization": f"Bearer {token}"}
response = requests.get(f"{API_BASE_URL}/destinations/", headers=headers)
if response.status_code == 200:
self.destinations = response.json()
for destination in self.destinations:
street_and_number = destination["address"].split(" %")[0]
postal_code = destination["address"].split(" %")[1]
city = destination["address"].split(" %")[2]
region_county = destination["address"].split(" %")[3]
country = destination["address"].split(" %")[4]
address = ''
if len(street_and_number) > 0:
address += street_and_number +', '
if len(postal_code) > 0:
address += postal_code +', '
if len(city) > 0:
address += city +', '
if len(region_county) > 0:
address += region_county +', '
if len(country) > 0:
address += country
self.destinations_column.controls.append(
ft.Container(
content=ft.Row([
ft.Column(
[
ft.Text(destination["name"], weight = ft.FontWeight.BOLD),
ft.Text(address)
]
),
ft.Row(
[
ft.IconButton(icon=ft.Icons.LOCATION_PIN, on_click= lambda e, d=destination: self.open_location(d)),
ft.IconButton(icon=ft.Icons.EDIT, on_click=lambda e, d=destination: self.open_dialog(d)),
ft.IconButton(icon=ft.Icons.DELETE, on_click=lambda e, d=destination: self.confirm_delete(d)),
]
)
],
alignment=ft.MainAxisAlignment.SPACE_BETWEEN),
padding=10,
bgcolor=ft.Colors.BLUE_50,
border=ft.border.all(1, ft.Colors.GREY_300),
border_radius=10,
)
)
self.page.update()
def open_dialog(self, destination=None):
self.current_edit = destination
name = ft.TextField(
label="Name",
value=destination["name"] if destination else "",
input_filter=ft.InputFilter(
allow=True,
regex_string=r"^[\x20-\x7E]*$",
replacement_string=""
),
)
street_and_number = ft.TextField(
label="Street and number",
value=destination["address"].split("%")[0] if destination else "",
input_filter=ft.InputFilter(
allow=True,
regex_string=r"^[\x20-\x7E]*$",
replacement_string=""
),
)
postal_code = ft.TextField(
label="Postal code",
value=destination["address"].split("%")[1] if destination else "",
input_filter=ft.InputFilter(
allow=True,
regex_string=r"^[\x20-\x7E]*$",
replacement_string=""
),
)
city = ft.TextField(
label="City",
value=destination["address"].split("%")[2] if destination else "",
input_filter=ft.InputFilter(
allow=True,
regex_string=r"^[\x20-\x7E]*$",
replacement_string=""
),
)
region_county = ft.TextField(
label="Region / County",
value=destination["address"].split("%")[3] if destination else "",
input_filter=ft.InputFilter(
allow=True,
regex_string=r"^[\x20-\x7E]*$",
replacement_string=""
),
)
country = ft.TextField(
label="Country",
value=destination["address"].split("%")[4] if destination else "",
input_filter=ft.InputFilter(
allow=True,
regex_string=r"^[\x20-\x7E]*$",
replacement_string=""
),
)
def save_action(e):
address = f'{street_and_number.value} %{postal_code.value} %{city.value} %{region_county.value} %{country.value}'
self.save_destination(name.value, address)
self.dialog = ft.AlertDialog(
modal=True,
title=ft.Text("Edit Address" if destination else "Add Address"),
content=ft.Column(
[
name,
street_and_number,
postal_code,
city,
region_county,
country
],
width=400,
height=400
),
actions=[
ft.TextButton("Cancel", on_click=lambda e: self.page.close(self.dialog)),
ft.ElevatedButton(
"Save",
on_click=save_action
)
],
)
self.page.dialog = self.dialog
self.page.open(self.dialog)
def save_destination(self, name, address):
token = self.page.client_storage.get("token")
user_id = self.page.session.get("user_id")
if not token or not user_id:
print("Missing token or user_id.")
return
headers = {"Authorization": f"Bearer {token}"}
data = {"name": name, "address": address, "user_id": user_id}
if self.current_edit:
url = f"{API_BASE_URL}/destinations/{self.current_edit['id']}"
requests.put(url, json=data, headers=headers)
else:
requests.post(f"{API_BASE_URL}/destinations/", json=data, headers=headers)
self.page.close(self.dialog)
self.refresh()
def confirm_delete(self, destination):
def delete_action(e):
self.delete_destination(destination["id"])
self.delete_alert = ft.AlertDialog(
modal=True,
title=ft.Text("Confirm Deletion"),
content=ft.Text(f"Are you sure you want to delete destination: {destination['name']}?"),
actions=[
ft.TextButton("Cancel", on_click=lambda e: self.page.close(self.delete_alert)),
ft.TextButton("Delete", on_click=delete_action)
]
)
self.page.dialog = self.delete_alert
self.page.open(self.delete_alert)
def delete_destination(self, id):
token = self.page.client_storage.get("token")
if not token:
print("Missing token.")
return
headers = {"Authorization": f"Bearer {token}"}
requests.delete(f"{API_BASE_URL}/destinations/{id}", headers=headers)
self.page.close(self.delete_alert)
self.refresh()
def open_location(self, destination):
query = destination["address"].replace(" ", "+").replace(" %", "").replace(",", "")
maps_url = f"https://www.google.com/maps/search/?api=1&query={query}"
self.page.launch_url(maps_url)
def get_current_subscription_plan(self):
try:
token = self.page.client_storage.get("token")
headers = {"Authorization": f"Bearer {token}"}
response = requests.get(f"{API_BASE_URL}/subscription/", headers=headers)
#print(response.text)
return response.json()[-1] if response.status_code == 200 else None
except Exception as e:
print("Error loading subscription:", e)
def build(self):
self.refresh()
self.add_destination_btn = ft.ElevatedButton("Add Destination", icon=ft.Icons.ADD, on_click=lambda e: self.open_dialog())
self.headers = ft.Row([
ft.Text("Adderess", size=24, weight=ft.FontWeight.BOLD),
],
alignment=ft.MainAxisAlignment.SPACE_BETWEEN
)
subscription = self.get_current_subscription_plan()
if subscription:
if subscription['status'] != 'expired':
self.headers.controls.append(self.add_destination_btn)
else:
self.headers.controls.append(self.subscription_error)
else:
self.headers.controls.append(self.subscription_error)
return ft.Column(
[
self.headers,
self.destinations_column
],
expand=True,
)