diff --git a/backend/create_favicons.py b/backend/create_favicons.py new file mode 100644 index 0000000..496afcc --- /dev/null +++ b/backend/create_favicons.py @@ -0,0 +1,78 @@ +#!/usr/bin/env python3 +""" +Create properly sized favicon images from the logo +""" +from PIL import Image +import os + +# Paths +logo_path = "/media/pts/Website/PromptTech_Solution_Site/Logo/PTB-logo.png" +public_dir = "/media/pts/Website/PromptTech_Solution_Site/frontend/public" + +# Load the original logo +print("Loading logo...") +logo = Image.open(logo_path) +print(f"Original size: {logo.size}") + +# Convert to RGBA if needed +if logo.mode != 'RGBA': + logo = logo.convert('RGBA') + +# Define sizes to create +sizes = [ + (16, 16, "favicon-16x16.png"), + (32, 32, "favicon-32x32.png"), + (48, 48, "favicon-48x48.png"), + (64, 64, "favicon-64x64.png"), + (180, 180, "apple-touch-icon.png"), + (192, 192, "android-chrome-192x192.png"), + (512, 512, "android-chrome-512x512.png"), +] + +# Create each size +for width, height, filename in sizes: + # Create a square canvas + size = (width, height) + + # Resize with high quality + resized = logo.copy() + resized.thumbnail(size, Image.Resampling.LANCZOS) + + # Create a new image with transparent background + new_img = Image.new('RGBA', size, (255, 255, 255, 0)) + + # Calculate position to center the logo + paste_x = (size[0] - resized.size[0]) // 2 + paste_y = (size[1] - resized.size[1]) // 2 + + # Paste the resized logo + new_img.paste(resized, (paste_x, paste_y), resized) + + # Save + output_path = os.path.join(public_dir, filename) + new_img.save(output_path, "PNG", optimize=True) + print(f"Created: {filename} ({width}x{height})") + +# Create favicon.ico with multiple sizes +print("\nCreating favicon.ico with multiple sizes...") +ico_sizes = [(16, 16), (32, 32), (48, 48)] +ico_images = [] + +for width, height in ico_sizes: + resized = logo.copy() + resized.thumbnail((width, height), Image.Resampling.LANCZOS) + + # Create centered image + new_img = Image.new('RGBA', (width, height), (255, 255, 255, 0)) + paste_x = (width - resized.size[0]) // 2 + paste_y = (height - resized.size[1]) // 2 + new_img.paste(resized, (paste_x, paste_y), resized) + + ico_images.append(new_img) + +# Save as ICO +favicon_path = os.path.join(public_dir, "favicon.ico") +ico_images[0].save(favicon_path, format='ICO', sizes=[(img.width, img.height) for img in ico_images]) +print(f"Created: favicon.ico with sizes: {[(img.width, img.height) for img in ico_images]}") + +print("\nā All favicon images created successfully!") diff --git a/backend/update_hero_image.py b/backend/update_hero_image.py new file mode 100644 index 0000000..73978e0 --- /dev/null +++ b/backend/update_hero_image.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python3 +"""Update the About page hero section image URL in the database.""" + +import asyncio +from sqlalchemy import text +from database import async_engine + +async def update_hero_image(): + """Update the hero section image_url in about_content table.""" + + image_url = "/uploads/media/aa5bcc15-3b1e-4ed8-8708-1a3dceb9494d.jpg" + + async with async_engine.begin() as conn: + # Update the hero section image_url + result = await conn.execute( + text(""" + UPDATE about_content + SET image_url = :image_url, + updated_at = NOW() + WHERE section = 'hero' + """), + {"image_url": image_url} + ) + + print(f"ā Updated hero section image_url to: {image_url}") + print(f" Rows affected: {result.rowcount}") + + # Verify the update + verify = await conn.execute( + text("SELECT section, image_url FROM about_content WHERE section = 'hero'") + ) + row = verify.fetchone() + if row: + print(f"ā Verified - Section: {row[0]}, Image URL: {row[1]}") + else: + print("ā No hero section found!") + +if __name__ == "__main__": + asyncio.run(update_hero_image()) diff --git a/frontend/public/android-chrome-192x192.png b/frontend/public/android-chrome-192x192.png new file mode 100644 index 0000000..ddd4af0 Binary files /dev/null and b/frontend/public/android-chrome-192x192.png differ diff --git a/frontend/public/android-chrome-512x512.png b/frontend/public/android-chrome-512x512.png new file mode 100644 index 0000000..13ed78b Binary files /dev/null and b/frontend/public/android-chrome-512x512.png differ diff --git a/frontend/public/apple-touch-icon.png b/frontend/public/apple-touch-icon.png new file mode 100644 index 0000000..47fcc7d Binary files /dev/null and b/frontend/public/apple-touch-icon.png differ diff --git a/frontend/public/favicon-16x16.png b/frontend/public/favicon-16x16.png new file mode 100644 index 0000000..1fbc004 Binary files /dev/null and b/frontend/public/favicon-16x16.png differ diff --git a/frontend/public/favicon-32x32.png b/frontend/public/favicon-32x32.png new file mode 100644 index 0000000..556ebfc Binary files /dev/null and b/frontend/public/favicon-32x32.png differ diff --git a/frontend/public/favicon-48x48.png b/frontend/public/favicon-48x48.png new file mode 100644 index 0000000..d1ac936 Binary files /dev/null and b/frontend/public/favicon-48x48.png differ diff --git a/frontend/public/favicon-64x64.png b/frontend/public/favicon-64x64.png new file mode 100644 index 0000000..a91a0b2 Binary files /dev/null and b/frontend/public/favicon-64x64.png differ diff --git a/frontend/public/favicon.ico b/frontend/public/favicon.ico index 0aa4c5c..d35e151 100644 Binary files a/frontend/public/favicon.ico and b/frontend/public/favicon.ico differ diff --git a/frontend/public/index.html b/frontend/public/index.html index e9932a9..ec60355 100644 --- a/frontend/public/index.html +++ b/frontend/public/index.html @@ -2,7 +2,17 @@
- + + + + + + + + + + + { +const ProductCard = ({ product, viewMode = "grid" }) => { const { addToCart } = useCart(); const { isAuthenticated } = useAuth(); @@ -41,6 +41,96 @@ const ProductCard = ({ product }) => { return product.image_url; }; + // List View Layout + if (viewMode === "list") { + return ( + + {/* Image Container - Fixed Size */} ++ {product.description} +
+ )} +