updates
This commit is contained in:
Binary file not shown.
@@ -91,10 +91,8 @@ async def health_check(db: Session=Depends(get_db)):
|
||||
async def metrics():
|
||||
return {'status': 'success', 'service': settings.APP_NAME, 'version': settings.APP_VERSION, 'environment': settings.ENVIRONMENT, 'timestamp': datetime.utcnow().isoformat()}
|
||||
app.include_router(auth_routes.router, prefix='/api')
|
||||
app.include_router(privacy_routes.router, prefix='/api')
|
||||
app.include_router(auth_routes.router, prefix=settings.API_V1_PREFIX)
|
||||
app.include_router(privacy_routes.router, prefix=settings.API_V1_PREFIX)
|
||||
from .routes import room_routes, booking_routes, payment_routes, invoice_routes, banner_routes, favorite_routes, service_routes, service_booking_routes, promotion_routes, report_routes, review_routes, user_routes, audit_routes, admin_privacy_routes, system_settings_routes, contact_routes, page_content_routes, home_routes, about_routes, contact_content_routes, footer_routes, chat_routes
|
||||
from .routes import room_routes, booking_routes, payment_routes, invoice_routes, banner_routes, favorite_routes, service_routes, service_booking_routes, promotion_routes, report_routes, review_routes, user_routes, audit_routes, admin_privacy_routes, system_settings_routes, contact_routes, page_content_routes, home_routes, about_routes, contact_content_routes, footer_routes, chat_routes, privacy_routes, terms_routes, refunds_routes, cancellation_routes, accessibility_routes, faq_routes
|
||||
app.include_router(room_routes.router, prefix='/api')
|
||||
app.include_router(booking_routes.router, prefix='/api')
|
||||
app.include_router(payment_routes.router, prefix='/api')
|
||||
@@ -115,6 +113,12 @@ app.include_router(home_routes.router, prefix='/api')
|
||||
app.include_router(about_routes.router, prefix='/api')
|
||||
app.include_router(contact_content_routes.router, prefix='/api')
|
||||
app.include_router(footer_routes.router, prefix='/api')
|
||||
app.include_router(privacy_routes.router, prefix='/api')
|
||||
app.include_router(terms_routes.router, prefix='/api')
|
||||
app.include_router(refunds_routes.router, prefix='/api')
|
||||
app.include_router(cancellation_routes.router, prefix='/api')
|
||||
app.include_router(accessibility_routes.router, prefix='/api')
|
||||
app.include_router(faq_routes.router, prefix='/api')
|
||||
app.include_router(chat_routes.router, prefix='/api')
|
||||
app.include_router(room_routes.router, prefix=settings.API_V1_PREFIX)
|
||||
app.include_router(booking_routes.router, prefix=settings.API_V1_PREFIX)
|
||||
@@ -136,6 +140,12 @@ app.include_router(home_routes.router, prefix=settings.API_V1_PREFIX)
|
||||
app.include_router(about_routes.router, prefix=settings.API_V1_PREFIX)
|
||||
app.include_router(contact_content_routes.router, prefix=settings.API_V1_PREFIX)
|
||||
app.include_router(footer_routes.router, prefix=settings.API_V1_PREFIX)
|
||||
app.include_router(privacy_routes.router, prefix=settings.API_V1_PREFIX)
|
||||
app.include_router(terms_routes.router, prefix=settings.API_V1_PREFIX)
|
||||
app.include_router(refunds_routes.router, prefix=settings.API_V1_PREFIX)
|
||||
app.include_router(cancellation_routes.router, prefix=settings.API_V1_PREFIX)
|
||||
app.include_router(accessibility_routes.router, prefix=settings.API_V1_PREFIX)
|
||||
app.include_router(faq_routes.router, prefix=settings.API_V1_PREFIX)
|
||||
app.include_router(chat_routes.router, prefix=settings.API_V1_PREFIX)
|
||||
app.include_router(page_content_routes.router, prefix='/api')
|
||||
app.include_router(page_content_routes.router, prefix=settings.API_V1_PREFIX)
|
||||
|
||||
Binary file not shown.
@@ -10,11 +10,17 @@ class PageType(str, enum.Enum):
|
||||
ABOUT = 'about'
|
||||
FOOTER = 'footer'
|
||||
SEO = 'seo'
|
||||
PRIVACY = 'privacy'
|
||||
TERMS = 'terms'
|
||||
REFUNDS = 'refunds'
|
||||
CANCELLATION = 'cancellation'
|
||||
ACCESSIBILITY = 'accessibility'
|
||||
FAQ = 'faq'
|
||||
|
||||
class PageContent(Base):
|
||||
__tablename__ = 'page_contents'
|
||||
id = Column(Integer, primary_key=True, index=True)
|
||||
page_type = Column(SQLEnum(PageType), nullable=False, unique=True, index=True)
|
||||
page_type = Column(SQLEnum(PageType, values_callable=lambda x: [e.value for e in x], native_enum=False, length=50), nullable=False, unique=True, index=True)
|
||||
title = Column(String(500), nullable=True)
|
||||
subtitle = Column(String(1000), nullable=True)
|
||||
description = Column(Text, nullable=True)
|
||||
|
||||
Binary file not shown.
Binary file not shown.
BIN
Backend/src/routes/__pycache__/faq_routes.cpython-312.pyc
Normal file
BIN
Backend/src/routes/__pycache__/faq_routes.cpython-312.pyc
Normal file
Binary file not shown.
Binary file not shown.
BIN
Backend/src/routes/__pycache__/refunds_routes.cpython-312.pyc
Normal file
BIN
Backend/src/routes/__pycache__/refunds_routes.cpython-312.pyc
Normal file
Binary file not shown.
BIN
Backend/src/routes/__pycache__/terms_routes.cpython-312.pyc
Normal file
BIN
Backend/src/routes/__pycache__/terms_routes.cpython-312.pyc
Normal file
Binary file not shown.
44
Backend/src/routes/accessibility_routes.py
Normal file
44
Backend/src/routes/accessibility_routes.py
Normal file
@@ -0,0 +1,44 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from sqlalchemy.orm import Session
|
||||
from ..config.database import get_db
|
||||
from ..config.logging_config import get_logger
|
||||
from ..models.page_content import PageContent, PageType
|
||||
logger = get_logger(__name__)
|
||||
router = APIRouter(prefix='/accessibility', tags=['accessibility'])
|
||||
|
||||
def serialize_page_content(content: PageContent) -> dict:
|
||||
return {
|
||||
'id': content.id,
|
||||
'page_type': content.page_type.value,
|
||||
'title': content.title,
|
||||
'subtitle': content.subtitle,
|
||||
'description': content.description,
|
||||
'content': content.content,
|
||||
'meta_title': content.meta_title,
|
||||
'meta_description': content.meta_description,
|
||||
'meta_keywords': content.meta_keywords,
|
||||
'og_title': content.og_title,
|
||||
'og_description': content.og_description,
|
||||
'og_image': content.og_image,
|
||||
'canonical_url': content.canonical_url,
|
||||
'is_active': content.is_active,
|
||||
'created_at': content.created_at.isoformat() if content.created_at else None,
|
||||
'updated_at': content.updated_at.isoformat() if content.updated_at else None
|
||||
}
|
||||
|
||||
@router.get('/')
|
||||
async def get_accessibility_content(db: Session=Depends(get_db)):
|
||||
try:
|
||||
content = db.query(PageContent).filter(PageContent.page_type == PageType.ACCESSIBILITY).first()
|
||||
if not content:
|
||||
return {'status': 'success', 'data': {'page_content': None, 'is_active': False}}
|
||||
if not content.is_active:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail='Accessibility page is currently disabled')
|
||||
content_dict = serialize_page_content(content)
|
||||
return {'status': 'success', 'data': {'page_content': content_dict}}
|
||||
except HTTPException:
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error(f'Error fetching accessibility content: {str(e)}', exc_info=True)
|
||||
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f'Error fetching accessibility content: {str(e)}')
|
||||
|
||||
44
Backend/src/routes/cancellation_routes.py
Normal file
44
Backend/src/routes/cancellation_routes.py
Normal file
@@ -0,0 +1,44 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from sqlalchemy.orm import Session
|
||||
from ..config.database import get_db
|
||||
from ..config.logging_config import get_logger
|
||||
from ..models.page_content import PageContent, PageType
|
||||
logger = get_logger(__name__)
|
||||
router = APIRouter(prefix='/cancellation', tags=['cancellation'])
|
||||
|
||||
def serialize_page_content(content: PageContent) -> dict:
|
||||
return {
|
||||
'id': content.id,
|
||||
'page_type': content.page_type.value,
|
||||
'title': content.title,
|
||||
'subtitle': content.subtitle,
|
||||
'description': content.description,
|
||||
'content': content.content,
|
||||
'meta_title': content.meta_title,
|
||||
'meta_description': content.meta_description,
|
||||
'meta_keywords': content.meta_keywords,
|
||||
'og_title': content.og_title,
|
||||
'og_description': content.og_description,
|
||||
'og_image': content.og_image,
|
||||
'canonical_url': content.canonical_url,
|
||||
'is_active': content.is_active,
|
||||
'created_at': content.created_at.isoformat() if content.created_at else None,
|
||||
'updated_at': content.updated_at.isoformat() if content.updated_at else None
|
||||
}
|
||||
|
||||
@router.get('/')
|
||||
async def get_cancellation_content(db: Session=Depends(get_db)):
|
||||
try:
|
||||
content = db.query(PageContent).filter(PageContent.page_type == PageType.CANCELLATION).first()
|
||||
if not content:
|
||||
return {'status': 'success', 'data': {'page_content': None, 'is_active': False}}
|
||||
if not content.is_active:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail='Cancellation policy page is currently disabled')
|
||||
content_dict = serialize_page_content(content)
|
||||
return {'status': 'success', 'data': {'page_content': content_dict}}
|
||||
except HTTPException:
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error(f'Error fetching cancellation content: {str(e)}', exc_info=True)
|
||||
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f'Error fetching cancellation content: {str(e)}')
|
||||
|
||||
44
Backend/src/routes/faq_routes.py
Normal file
44
Backend/src/routes/faq_routes.py
Normal file
@@ -0,0 +1,44 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from sqlalchemy.orm import Session
|
||||
from ..config.database import get_db
|
||||
from ..config.logging_config import get_logger
|
||||
from ..models.page_content import PageContent, PageType
|
||||
logger = get_logger(__name__)
|
||||
router = APIRouter(prefix='/faq', tags=['faq'])
|
||||
|
||||
def serialize_page_content(content: PageContent) -> dict:
|
||||
return {
|
||||
'id': content.id,
|
||||
'page_type': content.page_type.value,
|
||||
'title': content.title,
|
||||
'subtitle': content.subtitle,
|
||||
'description': content.description,
|
||||
'content': content.content,
|
||||
'meta_title': content.meta_title,
|
||||
'meta_description': content.meta_description,
|
||||
'meta_keywords': content.meta_keywords,
|
||||
'og_title': content.og_title,
|
||||
'og_description': content.og_description,
|
||||
'og_image': content.og_image,
|
||||
'canonical_url': content.canonical_url,
|
||||
'is_active': content.is_active,
|
||||
'created_at': content.created_at.isoformat() if content.created_at else None,
|
||||
'updated_at': content.updated_at.isoformat() if content.updated_at else None
|
||||
}
|
||||
|
||||
@router.get('/')
|
||||
async def get_faq_content(db: Session=Depends(get_db)):
|
||||
try:
|
||||
content = db.query(PageContent).filter(PageContent.page_type == PageType.FAQ).first()
|
||||
if not content:
|
||||
return {'status': 'success', 'data': {'page_content': None, 'is_active': False}}
|
||||
if not content.is_active:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail='FAQ page is currently disabled')
|
||||
content_dict = serialize_page_content(content)
|
||||
return {'status': 'success', 'data': {'page_content': content_dict}}
|
||||
except HTTPException:
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error(f'Error fetching FAQ content: {str(e)}', exc_info=True)
|
||||
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f'Error fetching FAQ content: {str(e)}')
|
||||
|
||||
@@ -1,39 +1,110 @@
|
||||
from fastapi import APIRouter, Depends, Request, Response, status
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from sqlalchemy.orm import Session
|
||||
import json
|
||||
from datetime import datetime
|
||||
from ..config.database import get_db
|
||||
from ..config.logging_config import get_logger
|
||||
from ..config.settings import settings
|
||||
from ..middleware.cookie_consent import COOKIE_CONSENT_COOKIE_NAME, _parse_consent_cookie
|
||||
from ..schemas.admin_privacy import PublicPrivacyConfigResponse
|
||||
from ..schemas.privacy import CookieCategoryPreferences, CookieConsent, CookieConsentResponse, UpdateCookieConsentRequest
|
||||
from ..models.page_content import PageContent, PageType
|
||||
from ..services.privacy_admin_service import privacy_admin_service
|
||||
from ..schemas.privacy import CookieConsent, CookieConsentResponse, UpdateCookieConsentRequest, CookieCategoryPreferences
|
||||
from ..schemas.admin_privacy import PublicPrivacyConfigResponse
|
||||
logger = get_logger(__name__)
|
||||
router = APIRouter(prefix='/privacy', tags=['privacy'])
|
||||
|
||||
@router.get('/cookie-consent', response_model=CookieConsentResponse, status_code=status.HTTP_200_OK)
|
||||
async def get_cookie_consent(request: Request) -> CookieConsentResponse:
|
||||
raw_cookie = request.cookies.get(COOKIE_CONSENT_COOKIE_NAME)
|
||||
consent = _parse_consent_cookie(raw_cookie)
|
||||
consent.categories.necessary = True
|
||||
return CookieConsentResponse(data=consent)
|
||||
def serialize_page_content(content: PageContent) -> dict:
|
||||
return {
|
||||
'id': content.id,
|
||||
'page_type': content.page_type.value,
|
||||
'title': content.title,
|
||||
'subtitle': content.subtitle,
|
||||
'description': content.description,
|
||||
'content': content.content,
|
||||
'meta_title': content.meta_title,
|
||||
'meta_description': content.meta_description,
|
||||
'meta_keywords': content.meta_keywords,
|
||||
'og_title': content.og_title,
|
||||
'og_description': content.og_description,
|
||||
'og_image': content.og_image,
|
||||
'canonical_url': content.canonical_url,
|
||||
'is_active': content.is_active,
|
||||
'created_at': content.created_at.isoformat() if content.created_at else None,
|
||||
'updated_at': content.updated_at.isoformat() if content.updated_at else None
|
||||
}
|
||||
|
||||
@router.post('/cookie-consent', response_model=CookieConsentResponse, status_code=status.HTTP_200_OK)
|
||||
async def update_cookie_consent(request: UpdateCookieConsentRequest, response: Response) -> CookieConsentResponse:
|
||||
existing_raw = response.headers.get('cookie')
|
||||
categories = CookieCategoryPreferences()
|
||||
if request.analytics is not None:
|
||||
categories.analytics = request.analytics
|
||||
if request.marketing is not None:
|
||||
categories.marketing = request.marketing
|
||||
if request.preferences is not None:
|
||||
categories.preferences = request.preferences
|
||||
categories.necessary = True
|
||||
consent = CookieConsent(categories=categories, has_decided=True)
|
||||
response.set_cookie(key=COOKIE_CONSENT_COOKIE_NAME, value=consent.model_dump_json(), httponly=True, secure=settings.is_production, samesite='lax', max_age=365 * 24 * 60 * 60, path='/')
|
||||
logger.info('Cookie consent updated: analytics=%s, marketing=%s, preferences=%s', consent.categories.analytics, consent.categories.marketing, consent.categories.preferences)
|
||||
return CookieConsentResponse(data=consent)
|
||||
@router.get('/')
|
||||
async def get_privacy_content(db: Session=Depends(get_db)):
|
||||
try:
|
||||
content = db.query(PageContent).filter(PageContent.page_type == PageType.PRIVACY).first()
|
||||
if not content:
|
||||
return {'status': 'success', 'data': {'page_content': None, 'is_active': False}}
|
||||
if not content.is_active:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail='Privacy policy page is currently disabled')
|
||||
content_dict = serialize_page_content(content)
|
||||
return {'status': 'success', 'data': {'page_content': content_dict}}
|
||||
except HTTPException:
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error(f'Error fetching privacy content: {str(e)}', exc_info=True)
|
||||
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f'Error fetching privacy content: {str(e)}')
|
||||
|
||||
@router.get('/config', response_model=PublicPrivacyConfigResponse, status_code=status.HTTP_200_OK)
|
||||
async def get_public_privacy_config(db: Session=Depends(get_db)) -> PublicPrivacyConfigResponse:
|
||||
config = privacy_admin_service.get_public_privacy_config(db)
|
||||
return PublicPrivacyConfigResponse(data=config)
|
||||
@router.get('/cookie-consent', response_model=CookieConsentResponse)
|
||||
async def get_cookie_consent(db: Session=Depends(get_db)):
|
||||
"""
|
||||
Get the default cookie consent structure.
|
||||
Note: Actual consent is stored client-side (localStorage), this endpoint provides the default structure.
|
||||
"""
|
||||
try:
|
||||
# Return default consent structure
|
||||
# The actual consent state is managed client-side
|
||||
consent = CookieConsent(
|
||||
version=1,
|
||||
updated_at=datetime.utcnow(),
|
||||
has_decided=False,
|
||||
categories=CookieCategoryPreferences(
|
||||
necessary=True, # Always true
|
||||
analytics=False,
|
||||
marketing=False,
|
||||
preferences=False
|
||||
)
|
||||
)
|
||||
return CookieConsentResponse(status='success', data=consent)
|
||||
except Exception as e:
|
||||
logger.error(f'Error fetching cookie consent: {str(e)}', exc_info=True)
|
||||
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f'Error fetching cookie consent: {str(e)}')
|
||||
|
||||
@router.post('/cookie-consent', response_model=CookieConsentResponse)
|
||||
async def update_cookie_consent(payload: UpdateCookieConsentRequest, db: Session=Depends(get_db)):
|
||||
"""
|
||||
Update cookie consent preferences.
|
||||
Note: This endpoint acknowledges the consent update. Actual consent is stored client-side.
|
||||
"""
|
||||
try:
|
||||
# Create updated consent structure
|
||||
consent = CookieConsent(
|
||||
version=1,
|
||||
updated_at=datetime.utcnow(),
|
||||
has_decided=True,
|
||||
categories=CookieCategoryPreferences(
|
||||
necessary=True, # Always true
|
||||
analytics=payload.analytics if payload.analytics is not None else False,
|
||||
marketing=payload.marketing if payload.marketing is not None else False,
|
||||
preferences=payload.preferences if payload.preferences is not None else False
|
||||
)
|
||||
)
|
||||
return CookieConsentResponse(status='success', data=consent)
|
||||
except Exception as e:
|
||||
logger.error(f'Error updating cookie consent: {str(e)}', exc_info=True)
|
||||
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f'Error updating cookie consent: {str(e)}')
|
||||
|
||||
@router.get('/config', response_model=PublicPrivacyConfigResponse)
|
||||
async def get_public_privacy_config(db: Session=Depends(get_db)):
|
||||
"""
|
||||
Get public privacy configuration including cookie policy settings and integration configs.
|
||||
This endpoint is public and does not require authentication.
|
||||
"""
|
||||
try:
|
||||
config = privacy_admin_service.get_public_privacy_config(db)
|
||||
return PublicPrivacyConfigResponse(status='success', data=config)
|
||||
except Exception as e:
|
||||
logger.error(f'Error fetching public privacy config: {str(e)}', exc_info=True)
|
||||
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f'Error fetching public privacy config: {str(e)}')
|
||||
|
||||
45
Backend/src/routes/refunds_routes.py
Normal file
45
Backend/src/routes/refunds_routes.py
Normal file
@@ -0,0 +1,45 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from sqlalchemy.orm import Session
|
||||
import json
|
||||
from ..config.database import get_db
|
||||
from ..config.logging_config import get_logger
|
||||
from ..models.page_content import PageContent, PageType
|
||||
logger = get_logger(__name__)
|
||||
router = APIRouter(prefix='/refunds', tags=['refunds'])
|
||||
|
||||
def serialize_page_content(content: PageContent) -> dict:
|
||||
return {
|
||||
'id': content.id,
|
||||
'page_type': content.page_type.value,
|
||||
'title': content.title,
|
||||
'subtitle': content.subtitle,
|
||||
'description': content.description,
|
||||
'content': content.content,
|
||||
'meta_title': content.meta_title,
|
||||
'meta_description': content.meta_description,
|
||||
'meta_keywords': content.meta_keywords,
|
||||
'og_title': content.og_title,
|
||||
'og_description': content.og_description,
|
||||
'og_image': content.og_image,
|
||||
'canonical_url': content.canonical_url,
|
||||
'is_active': content.is_active,
|
||||
'created_at': content.created_at.isoformat() if content.created_at else None,
|
||||
'updated_at': content.updated_at.isoformat() if content.updated_at else None
|
||||
}
|
||||
|
||||
@router.get('/')
|
||||
async def get_refunds_content(db: Session=Depends(get_db)):
|
||||
try:
|
||||
content = db.query(PageContent).filter(PageContent.page_type == PageType.REFUNDS).first()
|
||||
if not content:
|
||||
return {'status': 'success', 'data': {'page_content': None, 'is_active': False}}
|
||||
if not content.is_active:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail='Refunds policy page is currently disabled')
|
||||
content_dict = serialize_page_content(content)
|
||||
return {'status': 'success', 'data': {'page_content': content_dict}}
|
||||
except HTTPException:
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error(f'Error fetching refunds content: {str(e)}', exc_info=True)
|
||||
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f'Error fetching refunds content: {str(e)}')
|
||||
|
||||
45
Backend/src/routes/terms_routes.py
Normal file
45
Backend/src/routes/terms_routes.py
Normal file
@@ -0,0 +1,45 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from sqlalchemy.orm import Session
|
||||
import json
|
||||
from ..config.database import get_db
|
||||
from ..config.logging_config import get_logger
|
||||
from ..models.page_content import PageContent, PageType
|
||||
logger = get_logger(__name__)
|
||||
router = APIRouter(prefix='/terms', tags=['terms'])
|
||||
|
||||
def serialize_page_content(content: PageContent) -> dict:
|
||||
return {
|
||||
'id': content.id,
|
||||
'page_type': content.page_type.value,
|
||||
'title': content.title,
|
||||
'subtitle': content.subtitle,
|
||||
'description': content.description,
|
||||
'content': content.content,
|
||||
'meta_title': content.meta_title,
|
||||
'meta_description': content.meta_description,
|
||||
'meta_keywords': content.meta_keywords,
|
||||
'og_title': content.og_title,
|
||||
'og_description': content.og_description,
|
||||
'og_image': content.og_image,
|
||||
'canonical_url': content.canonical_url,
|
||||
'is_active': content.is_active,
|
||||
'created_at': content.created_at.isoformat() if content.created_at else None,
|
||||
'updated_at': content.updated_at.isoformat() if content.updated_at else None
|
||||
}
|
||||
|
||||
@router.get('/')
|
||||
async def get_terms_content(db: Session=Depends(get_db)):
|
||||
try:
|
||||
content = db.query(PageContent).filter(PageContent.page_type == PageType.TERMS).first()
|
||||
if not content:
|
||||
return {'status': 'success', 'data': {'page_content': None, 'is_active': False}}
|
||||
if not content.is_active:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail='Terms & Conditions page is currently disabled')
|
||||
content_dict = serialize_page_content(content)
|
||||
return {'status': 'success', 'data': {'page_content': content_dict}}
|
||||
except HTTPException:
|
||||
raise
|
||||
except Exception as e:
|
||||
logger.error(f'Error fetching terms content: {str(e)}', exc_info=True)
|
||||
raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f'Error fetching terms content: {str(e)}')
|
||||
|
||||
Reference in New Issue
Block a user