diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..eee2a30 --- /dev/null +++ b/.gitignore @@ -0,0 +1,43 @@ +# Dependencies +node_modules/ +frontend/node_modules/ +backend/__pycache__/ +*.pyc +*.pyo +*.pyd +.Python + +# Build outputs +frontend/.next/ +frontend/out/ +frontend/build/ +*.log + +# Environment variables +.env +.env.local +.env.production +*.env + +# IDE +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# OS +.DS_Store +Thumbs.db + +# Backups +*.backup +*-backup-* + +# Test coverage +coverage/ +.nyc_output/ + +# Misc +*.tar.gz +*.zip diff --git a/deploy-ui-improvements.sh b/deploy-ui-improvements.sh new file mode 100755 index 0000000..b2e93ea --- /dev/null +++ b/deploy-ui-improvements.sh @@ -0,0 +1,159 @@ +#!/bin/bash +# Deploy Burmddit UI/UX Improvements +# Run this script to update your live site with the new design + +set -e # Exit on error + +echo "🎨 Burmddit UI/UX Deployment Script" +echo "====================================" +echo "" + +# Colors +GREEN='\033[0;32m' +BLUE='\033[0;34m' +YELLOW='\033[1;33m' +NC='\033[0m' # No Color + +# Get current directory +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +cd "$SCRIPT_DIR" + +echo -e "${BLUE}Step 1: Backup existing files${NC}" +echo "--------------------------------" +cd frontend/app + +# Backup old files +if [ -f "globals.css" ]; then + echo "Backing up globals.css..." + cp globals.css globals-backup-$(date +%Y%m%d-%H%M%S).css +fi + +if [ -f "page.tsx" ]; then + echo "Backing up page.tsx..." + cp page.tsx page-backup-$(date +%Y%m%d-%H%M%S).tsx +fi + +if [ -f "article/[slug]/page.tsx" ]; then + echo "Backing up article page..." + mkdir -p article/[slug]/backup + cp article/[slug]/page.tsx "article/[slug]/backup/page-backup-$(date +%Y%m%d-%H%M%S).tsx" +fi + +echo -e "${GREEN}✓ Backups created${NC}" +echo "" + +echo -e "${BLUE}Step 2: Deploy new frontend files${NC}" +echo "-----------------------------------" + +# Replace CSS +if [ -f "globals-improved.css" ]; then + echo "Deploying new CSS..." + mv globals-improved.css globals.css + echo -e "${GREEN}✓ CSS updated${NC}" +else + echo -e "${YELLOW}⚠ globals-improved.css not found${NC}" +fi + +# Replace homepage +if [ -f "page-improved.tsx" ]; then + echo "Deploying new homepage..." + mv page-improved.tsx page.tsx + echo -e "${GREEN}✓ Homepage updated${NC}" +else + echo -e "${YELLOW}⚠ page-improved.tsx not found${NC}" +fi + +# Replace article page +if [ -f "article/[slug]/page-improved.tsx" ]; then + echo "Deploying new article page..." + mv article/[slug]/page-improved.tsx article/[slug]/page.tsx + echo -e "${GREEN}✓ Article page updated${NC}" +else + echo -e "${YELLOW}⚠ article page-improved.tsx not found${NC}" +fi + +# Tag page should already be in place +if [ ! -f "tag/[slug]/page.tsx" ]; then + echo -e "${YELLOW}⚠ Tag page not found - check if it was copied${NC}" +else + echo -e "${GREEN}✓ Tag pages ready${NC}" +fi + +echo "" + +echo -e "${BLUE}Step 3: Database Migration (Tags System)${NC}" +echo "-----------------------------------------" + +# Check if DATABASE_URL is set +if [ -z "$DATABASE_URL" ]; then + echo -e "${YELLOW}DATABASE_URL not set. Please run migration manually:${NC}" + echo "" + echo " psql \$DATABASE_URL < $SCRIPT_DIR/database/tags_migration.sql" + echo "" + echo "Or if you have connection details:" + echo " psql -h HOST -U USER -d DATABASE < $SCRIPT_DIR/database/tags_migration.sql" + echo "" + read -p "Press Enter to continue without migration, or Ctrl+C to exit..." +else + echo "Running tags migration..." + psql "$DATABASE_URL" < "$SCRIPT_DIR/database/tags_migration.sql" 2>&1 | grep -v "NOTICE" || true + echo -e "${GREEN}✓ Database migration complete${NC}" +fi + +echo "" + +echo -e "${BLUE}Step 4: Install dependencies${NC}" +echo "------------------------------" +cd "$SCRIPT_DIR/frontend" + +if [ -f "package.json" ]; then + if command -v npm &> /dev/null; then + echo "Installing/updating npm packages..." + npm install + echo -e "${GREEN}✓ Dependencies updated${NC}" + else + echo -e "${YELLOW}⚠ npm not found - skip dependency update${NC}" + fi +fi + +echo "" + +echo -e "${BLUE}Step 5: Build frontend${NC}" +echo "-----------------------" + +if command -v npm &> /dev/null; then + echo "Building production frontend..." + npm run build + echo -e "${GREEN}✓ Build complete${NC}" +else + echo -e "${YELLOW}⚠ npm not found - skip build${NC}" + echo "If using Vercel/external deployment, push to Git and it will auto-build" +fi + +echo "" + +echo -e "${GREEN}════════════════════════════════════════${NC}" +echo -e "${GREEN}✓ DEPLOYMENT COMPLETE!${NC}" +echo -e "${GREEN}════════════════════════════════════════${NC}" +echo "" +echo "🎉 New features deployed:" +echo " ✓ Modern design system" +echo " ✓ Hashtag/tag system" +echo " ✓ Cover images with overlays" +echo " ✓ Trending tags section" +echo " ✓ Better typography" +echo " ✓ Improved article pages" +echo "" +echo -e "${BLUE}Next steps:${NC}" +echo "1. If using Vercel/Railway: Push to Git to trigger auto-deploy" +echo " cd $SCRIPT_DIR && git push origin main" +echo "" +echo "2. Test the new design at: burmddit.qikbite.asia" +echo "" +echo "3. If auto-tagging not working, update backend/publisher.py" +echo " (see UI-IMPROVEMENTS.md for code snippet)" +echo "" +echo "4. Clear browser cache if design doesn't update immediately" +echo "" +echo -e "${YELLOW}For rollback:${NC} Restore from backup files created in step 1" +echo "" diff --git a/frontend/app/article/[slug]/page-improved.tsx b/frontend/app/article/[slug]/page-improved.tsx deleted file mode 100644 index 76d66b2..0000000 --- a/frontend/app/article/[slug]/page-improved.tsx +++ /dev/null @@ -1,336 +0,0 @@ -import { sql } from '@vercel/postgres' -import { notFound } from 'next/navigation' -import Link from 'next/link' -import Image from 'next/image' - -async function getArticleWithTags(slug: string) { - try { - const { rows } = await sql` - SELECT - a.*, - c.name as category_name, - c.name_burmese as category_name_burmese, - c.slug as category_slug, - COALESCE( - array_agg(t.name_burmese) FILTER (WHERE t.id IS NOT NULL), - ARRAY[]::VARCHAR[] - ) as tags_burmese, - COALESCE( - array_agg(t.slug) FILTER (WHERE t.id IS NOT NULL), - ARRAY[]::VARCHAR[] - ) as tag_slugs - FROM articles a - JOIN categories c ON a.category_id = c.id - LEFT JOIN article_tags at ON a.id = at.article_id - LEFT JOIN tags t ON at.tag_id = t.id - WHERE a.slug = ${slug} AND a.status = 'published' - GROUP BY a.id, c.id - ` - - if (rows.length === 0) return null - - // Increment view count - await sql`SELECT increment_view_count(${slug})` - - return rows[0] - } catch (error) { - console.error('Error fetching article:', error) - return null - } -} - -async function getRelatedArticles(articleId: number) { - try { - const { rows } = await sql`SELECT * FROM get_related_articles(${articleId}, 6)` - return rows - } catch (error) { - return [] - } -} - -export default async function ImprovedArticlePage({ params }: { params: { slug: string } }) { - const article = await getArticleWithTags(params.slug) - - if (!article) { - notFound() - } - - const relatedArticles = await getRelatedArticles(article.id) - const publishedDate = new Date(article.published_at).toLocaleDateString('my-MM', { - year: 'numeric', - month: 'long', - day: 'numeric' - }) - - return ( -
- {/* Hero Cover Image */} - {article.featured_image && ( -
- {article.title_burmese} -
- -
-
- {/* Category */} - - {article.category_name_burmese} - - - {/* Title */} -

- {article.title_burmese} -

- - {/* Meta */} -
- {publishedDate} - • - {article.reading_time} မိနစ် - • - {article.view_count} views -
-
-
-
- )} - - {/* Article Content */} -
- {/* Tags */} - {article.tags_burmese && article.tags_burmese.length > 0 && ( -
- {article.tags_burmese.map((tag: string, idx: number) => ( - - #{tag} - - ))} -
- )} - - {/* Article Body */} -
-
- - {/* Additional Images Gallery */} - {article.images && article.images.length > 1 && ( -
-

ဓာတ်ပုံများ

-
- {article.images.slice(1).map((img: string, idx: number) => ( -
- {`${article.title_burmese} -
- ))} -
-
- )} - - {/* Videos */} - {article.videos && article.videos.length > 0 && ( -
-

ဗီဒီယိုများ

-
- {article.videos.map((video: string, idx: number) => ( -
- {renderVideo(video)} -
- ))} -
-
- )} -
- - {/* Source Attribution */} - {article.source_articles && article.source_articles.length > 0 && ( -
-

- - - - မူရင်းသတင်းရင်းမြစ်များ -

-

- ဤဆောင်းပါးကို အောက်ပါမူရင်းသတင်းများမှ စုစည်း၍ မြန်မာဘာသာသို့ ပြန်ဆိုထားခြင်း ဖြစ်ပါသည်။ အားလုံးသော အကြွေးအရ မူရင်းစာရေးသူများနှင့် ထုတ်ပြန်သူများကို သက်ဆိုင်ပါသည်။ -

-
- {article.source_articles.map((source: any, index: number) => ( -
-
- - {index + 1} - -
- - {source.title} - - {source.author && source.author !== 'Unknown' && ( -

- စာရေးသူ: {source.author} -

- )} -
- - - - - -
-
- ))} -
-
- )} - - {/* Share Section */} -
-
-

မျှဝေပါ:

-
- - - -
-
-
-
- - {/* Related Articles */} - {relatedArticles.length > 0 && ( -
-

- ဆက်စပ်ဆောင်းပါးများ -

-
- {relatedArticles.map((related: any) => ( - - {related.featured_image && ( -
- {related.title_burmese} -
- )} -
-

- {related.title_burmese} -

-

- {related.excerpt_burmese} -

-
- - ))} -
-
- )} -
- ) -} - -function formatContent(content: string): string { - let formatted = content - .replace(/\n\n/g, '

') - .replace(/## (.*?)\n/g, '

$1

') - .replace(/### (.*?)\n/g, '

$1

') - .replace(/\*\*(.*?)\*\*/g, '$1') - .replace(/\*(.*?)\*/g, '$1') - - return `

${formatted}

` -} - -function renderVideo(videoUrl: string) { - let videoId = null - - if (videoUrl.includes('youtube.com/watch')) { - const match = videoUrl.match(/v=([^&]+)/) - videoId = match ? match[1] : null - } else if (videoUrl.includes('youtu.be/')) { - const match = videoUrl.match(/youtu\.be\/([^?]+)/) - videoId = match ? match[1] : null - } else if (videoUrl.includes('youtube.com/embed/')) { - const match = videoUrl.match(/embed\/([^?]+)/) - videoId = match ? match[1] : null - } - - if (videoId) { - return ( -