Jofax commited on
Commit
a6a21a3
Β·
verified Β·
1 Parent(s): 460af57

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +63 -45
app.py CHANGED
@@ -4,67 +4,85 @@ import folium
4
  from streamlit_folium import st_folium
5
  from datetime import datetime
6
 
7
- # --- CONFIG & STYLING ---
8
- st.set_page_config(page_title="Maldives Vessel Tracker", layout="wide")
9
 
10
  st.markdown("""
11
  <style>
12
- .main { background-color: #f0f2f6; }
13
- .stButton>button { width: 100%; border-radius: 20px; background-color: #0077B6; color: white; }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  </style>
15
  """, unsafe_allow_html=True)
16
 
17
- # --- MOCK DATA (Simulating followme.mv) ---
18
- # In a real app, you would use 'requests' and 'BeautifulSoup' to scrape live data
19
- data = {
20
- "Vessel Name": ["Aanu Quick", "Coral Express", "Aagalaa", "Dhon Hiri", "Altec Dash"],
21
- "Type": ["Speedboat", "Ferry", "Supply Boat", "Dhoni", "Speedboat"],
22
- "Status": ["Live: On Time", "Delayed", "Scheduled", "Live: On Time", "Live: On Time"],
23
- "Lat": [4.1755, 4.1910, 4.1700, 4.2100, 4.1850],
24
- "Lon": [73.5093, 73.5200, 73.5000, 73.5350, 73.5150],
25
- "Speed": ["31.0 knots", "12.0 knots", "8.5 knots", "22.0 knots", "35.0 knots"]
26
- }
27
- df = pd.DataFrame(data)
28
 
29
- # --- SIDEBAR: SEARCH & FILTERS ---
30
- st.sidebar.header("🚒 Vessel Finder")
31
- search_query = st.sidebar.text_input("Search vessel name...", "")
32
- filter_type = st.sidebar.multiselect("Vessel Type", options=df["Type"].unique(), default=df["Type"].unique())
33
-
34
- # Filter Logic
35
- filtered_df = df[(df["Vessel Name"].str.contains(search_query, case=False)) & (df["Type"].isin(filter_type))]
36
-
37
- # --- MAIN UI ---
38
- st.title("🌊 Maldives Vessel Management")
39
- st.write(f"Updated: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
40
 
 
41
  col1, col2 = st.columns([2, 1])
42
 
43
  with col1:
44
- st.subheader("πŸ“ Live Tracking Map")
45
- # Create Folium Map (Dark Theme for Gen Z aesthetic)
46
- m = folium.Map(location=[4.1755, 73.5093], zoom_start=13, tiles="cartodbpositron")
47
 
48
- for _, row in filtered_df.iterrows():
49
- color = "green" if "On Time" in row["Status"] else "red"
50
  folium.Marker(
51
- location=[row["Lat"], row["Lon"]],
52
- popup=f"{row['Vessel Name']} ({row['Speed']})",
53
  icon=folium.Icon(color=color, icon="ship", prefix="fa")
54
  ).add_to(m)
55
 
56
- st_folium(m, width=800, height=500)
57
 
58
  with col2:
59
- st.subheader("πŸ’³ Fast Payment (50 MVR)")
60
- if not filtered_df.empty:
61
- selected_vessel = st.selectbox("Select Vessel to Pay", filtered_df["Vessel Name"])
62
- if st.button(f"Pay for {selected_vessel}"):
63
- st.balloons()
64
- st.success(f"Payment for {selected_vessel} successful! Check your SMS for the ticket. 🎫")
65
- else:
66
- st.warning("No vessels found matching your search.")
 
 
 
 
 
 
 
 
67
 
68
- # --- DATA TABLE ---
69
- st.subheader("πŸ“‹ Vessel Status Board")
70
- st.dataframe(filtered_df[["Vessel Name", "Type", "Status", "Speed"]], use_container_width=True)
 
4
  from streamlit_folium import st_folium
5
  from datetime import datetime
6
 
7
+ # --- GEN Z DESIGN: CUSTOM CSS ---
8
+ st.set_page_config(page_title="Maldives Vessel Tracker", page_icon="🚒", layout="wide")
9
 
10
  st.markdown("""
11
  <style>
12
+ /* Maldivian Blue Gradient Header */
13
+ .main {
14
+ background: linear-gradient(135deg, #0077B6 0%, #00B4D8 50%, #90E0EF 100%);
15
+ color: white;
16
+ }
17
+ .stApp {
18
+ background-color: #f8f9fa;
19
+ }
20
+ .vessel-card {
21
+ background: white;
22
+ padding: 20px;
23
+ border-radius: 20px;
24
+ box-shadow: 0 4px 15px rgba(0,0,0,0.1);
25
+ margin-bottom: 15px;
26
+ color: #333;
27
+ }
28
+ .status-badge {
29
+ padding: 5px 12px;
30
+ border-radius: 15px;
31
+ font-size: 0.8em;
32
+ font-weight: bold;
33
+ }
34
  </style>
35
  """, unsafe_allow_html=True)
36
 
37
+ # --- MOCK DATA: CONNECTED TO YOUR ANDROID LOGIC ---
38
+ vessel_data = [
39
+ {"id": 1, "name": "Aanu Quick", "type": "Speedboat", "status": "Live: On Time", "lat": 4.1755, "lon": 73.5093, "speed": "31 knots"},
40
+ {"id": 2, "name": "Coral Express", "type": "Ferry", "status": "Delayed", "lat": 4.1910, "lon": 73.5200, "speed": "12 knots"},
41
+ {"id": 3, "name": "Dhon Hiri", "type": "Dhoni", "status": "Live: On Time", "lat": 4.2100, "lon": 73.5350, "speed": "22 knots"},
42
+ {"id": 4, "name": "Altec Dash", "type": "Speedboat", "status": "Scheduled", "lat": 4.1850, "lon": 73.5150, "speed": "0 knots"}
43
+ ]
44
+ df = pd.DataFrame(vessel_data)
 
 
 
45
 
46
+ # --- HEADER ---
47
+ st.title("🌊 Maldives Vessel Tracker")
48
+ st.write(f"Last Synced with FollowMe: {datetime.now().strftime('%H:%M:%S')}")
 
 
 
 
 
 
 
 
49
 
50
+ # --- LAYOUT: MAP & LIST ---
51
  col1, col2 = st.columns([2, 1])
52
 
53
  with col1:
54
+ st.subheader("πŸ“ Live Fleet Map")
55
+ # Modern Map centered on Male'
56
+ m = folium.Map(location=[4.1850, 73.5150], zoom_start=13, tiles="CartoDB positron")
57
 
58
+ for _, boat in df.iterrows():
59
+ color = "green" if "On Time" in boat["status"] else "orange" if "Delayed" in boat["status"] else "gray"
60
  folium.Marker(
61
+ [boat["lat"], boat["lon"]],
62
+ popup=f"<b>{boat['name']}</b><br>Speed: {boat['speed']}",
63
  icon=folium.Icon(color=color, icon="ship", prefix="fa")
64
  ).add_to(m)
65
 
66
+ st_folium(m, width="100%", height=500)
67
 
68
  with col2:
69
+ st.subheader("🚒 Vessel List")
70
+ search = st.text_input("Search (e.g. 'Aanu')", "")
71
+
72
+ for _, boat in df.iterrows():
73
+ if search.lower() in boat["name"].lower():
74
+ with st.container():
75
+ st.markdown(f"""
76
+ <div class="vessel-card">
77
+ <h3 style="margin:0;">{boat['name']}</h3>
78
+ <p style="color:gray; margin-bottom:10px;">{boat['type']} β€’ {boat['speed']}</p>
79
+ <span class="status-badge" style="background:#e1f5fe; color:#01579b;">{boat['status']}</span>
80
+ </div>
81
+ """, unsafe_allow_html=True)
82
+ if st.button(f"Pay 50 MVR for {boat['name']}", key=boat['id']):
83
+ st.balloons()
84
+ st.success("Payment successful! 🎫")
85
 
86
+ # --- FOOTER ---
87
+ st.divider()
88
+ st.info("πŸ’‘ Note: This is a web preview. For the full experience with real-time push notifications, download the Android APK.")