Add admin features, responsive UI, user reviews, visit stats, and channel-colored markers
- Admin: video management with Google Maps match status, manual restaurant mapping, restaurant remap on name change - Admin: user management tab with favorites/reviews detail - Admin: channel deletion fix for IDs with slashes - Frontend: responsive mobile layout (map top, list bottom, 2-row header) - Frontend: channel-colored map markers with legend - Frontend: my reviews list, favorites toggle, visit counter overlay - Frontend: force light mode for dark theme devices - Backend: visit tracking (site_visits table), user reviews endpoint - Backend: bulk transcript/extract streaming, geocode key fixes - Nginx config for production deployment Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -57,17 +57,53 @@ def _places_text_search(query: str) -> dict | None:
|
||||
if data.get("status") == "OK" and data.get("results"):
|
||||
place = data["results"][0]
|
||||
loc = place["geometry"]["location"]
|
||||
return {
|
||||
result = {
|
||||
"latitude": loc["lat"],
|
||||
"longitude": loc["lng"],
|
||||
"formatted_address": place.get("formatted_address", ""),
|
||||
"google_place_id": place.get("place_id", ""),
|
||||
"business_status": place.get("business_status"),
|
||||
"rating": place.get("rating"),
|
||||
"rating_count": place.get("user_ratings_total"),
|
||||
}
|
||||
# Fetch phone/website from Place Details
|
||||
place_id = place.get("place_id")
|
||||
if place_id:
|
||||
details = _place_details(place_id)
|
||||
if details:
|
||||
result.update(details)
|
||||
return result
|
||||
except Exception as e:
|
||||
logger.warning("Places text search failed for '%s': %s", query, e)
|
||||
return None
|
||||
|
||||
|
||||
def _place_details(place_id: str) -> dict | None:
|
||||
"""Fetch phone and website from Google Place Details API."""
|
||||
try:
|
||||
r = httpx.get(
|
||||
"https://maps.googleapis.com/maps/api/place/details/json",
|
||||
params={
|
||||
"place_id": place_id,
|
||||
"key": _api_key(),
|
||||
"language": "ko",
|
||||
"fields": "formatted_phone_number,website",
|
||||
},
|
||||
timeout=10,
|
||||
)
|
||||
r.raise_for_status()
|
||||
data = r.json()
|
||||
if data.get("status") == "OK" and data.get("result"):
|
||||
res = data["result"]
|
||||
return {
|
||||
"phone": res.get("formatted_phone_number"),
|
||||
"website": res.get("website"),
|
||||
}
|
||||
except Exception as e:
|
||||
logger.warning("Place details failed for '%s': %s", place_id, e)
|
||||
return None
|
||||
|
||||
|
||||
def _geocode(query: str) -> dict | None:
|
||||
"""Geocode an address string."""
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user