3131 ensure_data_directories ,
3232 optimize_existing_header_images ,
3333 DATA_DIR ,
34+ get_portal_content ,
35+ get_database_statistics ,
36+ create_feature_cards_from_databases ,
37+ create_statistics_data ,
38+ get_success_error_from_request ,
3439)
3540
3641import logging
@@ -1380,6 +1385,69 @@ async def export_system_logs(datasette, request, actor):
13801385 logger .error (f"Error exporting logs: { e } " )
13811386 # If export fails, redirect to settings tab with error
13821387 return Response .redirect (f"/system-admin?tab=settings&error=Export failed: { str (e )} " )
1388+
1389+ async def preview_portal_homepage (datasette , request ):
1390+ """Preview portal homepage with current admin edits - System Admin only."""
1391+ logger .debug (f"Preview Portal Homepage request: method={ request .method } " )
1392+
1393+ actor = get_actor_from_request (request )
1394+ if not actor or actor .get ("role" ) != "system_admin" :
1395+ logger .warning (f"Unauthorized portal preview attempt: actor={ actor } " )
1396+ return Response .redirect ("/login?error=System admin access required" )
1397+
1398+ # Verify user session and admin role
1399+ is_valid , user_data , redirect_response = await verify_user_session (datasette , actor )
1400+ if not is_valid :
1401+ return redirect_response
1402+
1403+ if user_data ["role" ] != "system_admin" :
1404+ logger .warning (f"Invalid role for portal preview: user_id={ actor .get ('id' )} " )
1405+ return Response .redirect ("/login?error=Unauthorized access" )
1406+
1407+ try :
1408+ # Get base content using common utility (same as index_page)
1409+ content = await get_portal_content (datasette )
1410+
1411+ # Get statistics for preview homepage (same as index_page)
1412+ stats = await get_database_statistics (datasette )
1413+
1414+ # Format featured databases as cards using common utility (same as index_page)
1415+ feature_cards = create_feature_cards_from_databases (stats ['featured_databases' ], limit = 50 )
1416+
1417+ # Statistics for the cards section using common utility (same as index_page)
1418+ statistics_data = create_statistics_data (stats )
1419+
1420+ # Add preview banner data to show this is a preview
1421+ preview_mode = True
1422+
1423+ logger .debug (f"Rendering portal preview with statistics: { stats } " )
1424+
1425+ # Render the same template as the main homepage but with preview flag
1426+ return Response .html (
1427+ await datasette .render_template (
1428+ "index.html" ,
1429+ {
1430+ "page_title" : content ['title' ].get ('content' , "Resette" ),
1431+ "header_image" : content ['header_image' ],
1432+ "info" : content ['info' ],
1433+ "feature_cards" : feature_cards ,
1434+ "total_published" : stats ['published_databases' ],
1435+ "statistics" : statistics_data ,
1436+ "content" : content ,
1437+ "actor" : actor ,
1438+ "preview_mode" : preview_mode , # Flag to show preview banner
1439+ "edit_url" : "/edit-portal-homepage" , # Link back to editor
1440+ ** get_success_error_from_request (request )
1441+ },
1442+ request = request
1443+ )
1444+ )
1445+
1446+ except Exception as e :
1447+ logger .error (f"Error in portal preview: { e } " )
1448+ import traceback
1449+ logger .error (f"Traceback: { traceback .format_exc ()} " )
1450+ return Response .text (f"Portal preview error: { str (e )} " , status = 500 )
13831451
13841452@hookimpl
13851453def register_routes ():
@@ -1392,10 +1460,12 @@ def register_routes():
13921460 (r"^/edit-user-role$" , edit_user_role ),
13931461 (r"^/delete-user$" , delete_user ),
13941462 (r"^/edit-portal-homepage$" , edit_portal_homepage ),
1463+ (r"^/preview-portal-homepage$" , preview_portal_homepage ),
13951464 (r"^/cleanup-expired-databases$" , cleanup_expired_databases ),
13961465 (r"^/api/database-details/([^/]+)$" , get_database_details_api ),
13971466 ]
13981467
1468+
13991469@hookimpl
14001470def startup (datasette ):
14011471 """Admin Panel module startup."""
0 commit comments