updates
This commit is contained in:
413
Backend/src/routes/page_content_routes.py
Normal file
413
Backend/src/routes/page_content_routes.py
Normal file
@@ -0,0 +1,413 @@
|
||||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from sqlalchemy.orm import Session
|
||||
from typing import Optional
|
||||
from datetime import datetime
|
||||
import json
|
||||
|
||||
from ..config.database import get_db
|
||||
from ..middleware.auth import get_current_user, authorize_roles
|
||||
from ..models.user import User
|
||||
from ..models.page_content import PageContent, PageType
|
||||
|
||||
router = APIRouter(prefix="/page-content", tags=["page-content"])
|
||||
|
||||
|
||||
@router.get("/")
|
||||
async def get_all_page_contents(
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
"""Get all page contents"""
|
||||
try:
|
||||
contents = db.query(PageContent).all()
|
||||
result = []
|
||||
for content in contents:
|
||||
content_dict = {
|
||||
"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,
|
||||
"contact_info": json.loads(content.contact_info) if content.contact_info else None,
|
||||
"map_url": content.map_url,
|
||||
"social_links": json.loads(content.social_links) if content.social_links else None,
|
||||
"footer_links": json.loads(content.footer_links) if content.footer_links else None,
|
||||
"hero_title": content.hero_title,
|
||||
"hero_subtitle": content.hero_subtitle,
|
||||
"hero_image": content.hero_image,
|
||||
"story_content": content.story_content,
|
||||
"values": json.loads(content.values) if content.values else None,
|
||||
"features": json.loads(content.features) if content.features else None,
|
||||
"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,
|
||||
}
|
||||
result.append(content_dict)
|
||||
|
||||
return {
|
||||
"status": "success",
|
||||
"data": {
|
||||
"page_contents": result
|
||||
}
|
||||
}
|
||||
except Exception as e:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail=f"Error fetching page contents: {str(e)}"
|
||||
)
|
||||
|
||||
|
||||
@router.get("/{page_type}")
|
||||
async def get_page_content(
|
||||
page_type: PageType,
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
"""Get content for a specific page"""
|
||||
try:
|
||||
content = db.query(PageContent).filter(PageContent.page_type == page_type).first()
|
||||
|
||||
if not content:
|
||||
# Return default structure if not found
|
||||
return {
|
||||
"status": "success",
|
||||
"data": {
|
||||
"page_content": None
|
||||
}
|
||||
}
|
||||
|
||||
content_dict = {
|
||||
"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,
|
||||
"contact_info": json.loads(content.contact_info) if content.contact_info else None,
|
||||
"social_links": json.loads(content.social_links) if content.social_links else None,
|
||||
"footer_links": json.loads(content.footer_links) if content.footer_links else None,
|
||||
"hero_title": content.hero_title,
|
||||
"hero_subtitle": content.hero_subtitle,
|
||||
"hero_image": content.hero_image,
|
||||
"story_content": content.story_content,
|
||||
"values": json.loads(content.values) if content.values else None,
|
||||
"features": json.loads(content.features) if content.features else None,
|
||||
"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,
|
||||
}
|
||||
|
||||
return {
|
||||
"status": "success",
|
||||
"data": {
|
||||
"page_content": content_dict
|
||||
}
|
||||
}
|
||||
except Exception as e:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail=f"Error fetching page content: {str(e)}"
|
||||
)
|
||||
|
||||
|
||||
@router.post("/{page_type}")
|
||||
async def create_or_update_page_content(
|
||||
page_type: PageType,
|
||||
title: Optional[str] = None,
|
||||
subtitle: Optional[str] = None,
|
||||
description: Optional[str] = None,
|
||||
content: Optional[str] = None,
|
||||
meta_title: Optional[str] = None,
|
||||
meta_description: Optional[str] = None,
|
||||
meta_keywords: Optional[str] = None,
|
||||
og_title: Optional[str] = None,
|
||||
og_description: Optional[str] = None,
|
||||
og_image: Optional[str] = None,
|
||||
canonical_url: Optional[str] = None,
|
||||
contact_info: Optional[str] = None,
|
||||
map_url: Optional[str] = None,
|
||||
social_links: Optional[str] = None,
|
||||
footer_links: Optional[str] = None,
|
||||
hero_title: Optional[str] = None,
|
||||
hero_subtitle: Optional[str] = None,
|
||||
hero_image: Optional[str] = None,
|
||||
story_content: Optional[str] = None,
|
||||
values: Optional[str] = None,
|
||||
features: Optional[str] = None,
|
||||
is_active: bool = True,
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
"""Create or update page content (admin only)"""
|
||||
try:
|
||||
authorize_roles(current_user, ["admin"])
|
||||
|
||||
# Validate JSON fields if provided
|
||||
if contact_info:
|
||||
try:
|
||||
json.loads(contact_info)
|
||||
except json.JSONDecodeError:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail="Invalid JSON in contact_info"
|
||||
)
|
||||
|
||||
if social_links:
|
||||
try:
|
||||
json.loads(social_links)
|
||||
except json.JSONDecodeError:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail="Invalid JSON in social_links"
|
||||
)
|
||||
|
||||
if footer_links:
|
||||
try:
|
||||
json.loads(footer_links)
|
||||
except json.JSONDecodeError:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail="Invalid JSON in footer_links"
|
||||
)
|
||||
|
||||
if values:
|
||||
try:
|
||||
json.loads(values)
|
||||
except json.JSONDecodeError:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail="Invalid JSON in values"
|
||||
)
|
||||
|
||||
if features:
|
||||
try:
|
||||
json.loads(features)
|
||||
except json.JSONDecodeError:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail="Invalid JSON in features"
|
||||
)
|
||||
|
||||
# Check if content exists
|
||||
existing_content = db.query(PageContent).filter(PageContent.page_type == page_type).first()
|
||||
|
||||
if existing_content:
|
||||
# Update existing
|
||||
if title is not None:
|
||||
existing_content.title = title
|
||||
if subtitle is not None:
|
||||
existing_content.subtitle = subtitle
|
||||
if description is not None:
|
||||
existing_content.description = description
|
||||
if content is not None:
|
||||
existing_content.content = content
|
||||
if meta_title is not None:
|
||||
existing_content.meta_title = meta_title
|
||||
if meta_description is not None:
|
||||
existing_content.meta_description = meta_description
|
||||
if meta_keywords is not None:
|
||||
existing_content.meta_keywords = meta_keywords
|
||||
if og_title is not None:
|
||||
existing_content.og_title = og_title
|
||||
if og_description is not None:
|
||||
existing_content.og_description = og_description
|
||||
if og_image is not None:
|
||||
existing_content.og_image = og_image
|
||||
if canonical_url is not None:
|
||||
existing_content.canonical_url = canonical_url
|
||||
if contact_info is not None:
|
||||
existing_content.contact_info = contact_info
|
||||
if map_url is not None:
|
||||
existing_content.map_url = map_url
|
||||
if social_links is not None:
|
||||
existing_content.social_links = social_links
|
||||
if footer_links is not None:
|
||||
existing_content.footer_links = footer_links
|
||||
if hero_title is not None:
|
||||
existing_content.hero_title = hero_title
|
||||
if hero_subtitle is not None:
|
||||
existing_content.hero_subtitle = hero_subtitle
|
||||
if hero_image is not None:
|
||||
existing_content.hero_image = hero_image
|
||||
if story_content is not None:
|
||||
existing_content.story_content = story_content
|
||||
if values is not None:
|
||||
existing_content.values = values
|
||||
if features is not None:
|
||||
existing_content.features = features
|
||||
if is_active is not None:
|
||||
existing_content.is_active = is_active
|
||||
|
||||
existing_content.updated_at = datetime.utcnow()
|
||||
db.commit()
|
||||
db.refresh(existing_content)
|
||||
|
||||
return {
|
||||
"status": "success",
|
||||
"message": "Page content updated successfully",
|
||||
"data": {
|
||||
"page_content": {
|
||||
"id": existing_content.id,
|
||||
"page_type": existing_content.page_type.value,
|
||||
"title": existing_content.title,
|
||||
"updated_at": existing_content.updated_at.isoformat() if existing_content.updated_at else None,
|
||||
}
|
||||
}
|
||||
}
|
||||
else:
|
||||
# Create new
|
||||
new_content = PageContent(
|
||||
page_type=page_type,
|
||||
title=title,
|
||||
subtitle=subtitle,
|
||||
description=description,
|
||||
content=content,
|
||||
meta_title=meta_title,
|
||||
meta_description=meta_description,
|
||||
meta_keywords=meta_keywords,
|
||||
og_title=og_title,
|
||||
og_description=og_description,
|
||||
og_image=og_image,
|
||||
canonical_url=canonical_url,
|
||||
contact_info=contact_info,
|
||||
map_url=map_url,
|
||||
social_links=social_links,
|
||||
footer_links=footer_links,
|
||||
hero_title=hero_title,
|
||||
hero_subtitle=hero_subtitle,
|
||||
hero_image=hero_image,
|
||||
story_content=story_content,
|
||||
values=values,
|
||||
features=features,
|
||||
is_active=is_active,
|
||||
)
|
||||
|
||||
db.add(new_content)
|
||||
db.commit()
|
||||
db.refresh(new_content)
|
||||
|
||||
return {
|
||||
"status": "success",
|
||||
"message": "Page content created successfully",
|
||||
"data": {
|
||||
"page_content": {
|
||||
"id": new_content.id,
|
||||
"page_type": new_content.page_type.value,
|
||||
"title": new_content.title,
|
||||
"created_at": new_content.created_at.isoformat() if new_content.created_at else None,
|
||||
}
|
||||
}
|
||||
}
|
||||
except HTTPException:
|
||||
raise
|
||||
except Exception as e:
|
||||
db.rollback()
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail=f"Error saving page content: {str(e)}"
|
||||
)
|
||||
|
||||
|
||||
@router.put("/{page_type}")
|
||||
async def update_page_content(
|
||||
page_type: PageType,
|
||||
page_data: dict,
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
"""Create or update page content using JSON body (admin only)"""
|
||||
try:
|
||||
authorize_roles(current_user, ["admin"])
|
||||
|
||||
existing_content = db.query(PageContent).filter(PageContent.page_type == page_type).first()
|
||||
|
||||
if not existing_content:
|
||||
# Create new content if it doesn't exist
|
||||
existing_content = PageContent(
|
||||
page_type=page_type,
|
||||
is_active=True,
|
||||
)
|
||||
db.add(existing_content)
|
||||
|
||||
# Update fields from request body
|
||||
for key, value in page_data.items():
|
||||
if hasattr(existing_content, key):
|
||||
# Handle JSON fields - convert dict/list to JSON string
|
||||
if key in ["contact_info", "social_links", "footer_links", "values", "features"] and value is not None:
|
||||
if isinstance(value, str):
|
||||
# Already a string, validate it's valid JSON
|
||||
try:
|
||||
json.loads(value)
|
||||
except json.JSONDecodeError:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail=f"Invalid JSON in {key}"
|
||||
)
|
||||
elif isinstance(value, (dict, list)):
|
||||
# Convert dict/list to JSON string for storage
|
||||
value = json.dumps(value)
|
||||
|
||||
# Skip None values to allow partial updates
|
||||
if value is not None:
|
||||
setattr(existing_content, key, value)
|
||||
|
||||
existing_content.updated_at = datetime.utcnow()
|
||||
db.commit()
|
||||
db.refresh(existing_content)
|
||||
|
||||
content_dict = {
|
||||
"id": existing_content.id,
|
||||
"page_type": existing_content.page_type.value,
|
||||
"title": existing_content.title,
|
||||
"subtitle": existing_content.subtitle,
|
||||
"description": existing_content.description,
|
||||
"content": existing_content.content,
|
||||
"meta_title": existing_content.meta_title,
|
||||
"meta_description": existing_content.meta_description,
|
||||
"meta_keywords": existing_content.meta_keywords,
|
||||
"og_title": existing_content.og_title,
|
||||
"og_description": existing_content.og_description,
|
||||
"og_image": existing_content.og_image,
|
||||
"canonical_url": existing_content.canonical_url,
|
||||
"contact_info": json.loads(existing_content.contact_info) if existing_content.contact_info else None,
|
||||
"social_links": json.loads(existing_content.social_links) if existing_content.social_links else None,
|
||||
"footer_links": json.loads(existing_content.footer_links) if existing_content.footer_links else None,
|
||||
"hero_title": existing_content.hero_title,
|
||||
"hero_subtitle": existing_content.hero_subtitle,
|
||||
"hero_image": existing_content.hero_image,
|
||||
"story_content": existing_content.story_content,
|
||||
"values": json.loads(existing_content.values) if existing_content.values else None,
|
||||
"features": json.loads(existing_content.features) if existing_content.features else None,
|
||||
"is_active": existing_content.is_active,
|
||||
"updated_at": existing_content.updated_at.isoformat() if existing_content.updated_at else None,
|
||||
}
|
||||
|
||||
return {
|
||||
"status": "success",
|
||||
"message": "Page content updated successfully",
|
||||
"data": {
|
||||
"page_content": content_dict
|
||||
}
|
||||
}
|
||||
except HTTPException:
|
||||
raise
|
||||
except Exception as e:
|
||||
db.rollback()
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail=f"Error updating page content: {str(e)}"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user