Spaces:
Running
Running
Add 3 files
Browse files- README.md +7 -5
- index.html +761 -19
- prompts.txt +1 -0
README.md
CHANGED
|
@@ -1,10 +1,12 @@
|
|
| 1 |
---
|
| 2 |
-
title:
|
| 3 |
-
emoji:
|
| 4 |
-
colorFrom:
|
| 5 |
-
colorTo:
|
| 6 |
sdk: static
|
| 7 |
pinned: false
|
|
|
|
|
|
|
| 8 |
---
|
| 9 |
|
| 10 |
-
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
|
| 1 |
---
|
| 2 |
+
title: portfolio-page
|
| 3 |
+
emoji: 🐳
|
| 4 |
+
colorFrom: blue
|
| 5 |
+
colorTo: green
|
| 6 |
sdk: static
|
| 7 |
pinned: false
|
| 8 |
+
tags:
|
| 9 |
+
- deepsite
|
| 10 |
---
|
| 11 |
|
| 12 |
+
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
index.html
CHANGED
|
@@ -1,19 +1,761 @@
|
|
| 1 |
-
<!
|
| 2 |
-
<html>
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
|
| 7 |
-
|
| 8 |
-
|
| 9 |
-
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="UTF-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
| 6 |
+
<title>Art & Lens | Creative Portfolio</title>
|
| 7 |
+
<script src="https://cdn.tailwindcss.com"></script>
|
| 8 |
+
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
|
| 9 |
+
<style>
|
| 10 |
+
.gallery-item {
|
| 11 |
+
transition: all 0.3s ease;
|
| 12 |
+
}
|
| 13 |
+
.gallery-item:hover {
|
| 14 |
+
transform: scale(1.02);
|
| 15 |
+
box-shadow: 0 10px 20px rgba(0,0,0,0.2);
|
| 16 |
+
}
|
| 17 |
+
.modal {
|
| 18 |
+
transition: opacity 0.3s ease;
|
| 19 |
+
}
|
| 20 |
+
.auth-modal {
|
| 21 |
+
animation: slideDown 0.4s ease-out;
|
| 22 |
+
}
|
| 23 |
+
@keyframes slideDown {
|
| 24 |
+
from {
|
| 25 |
+
transform: translateY(-50px);
|
| 26 |
+
opacity: 0;
|
| 27 |
+
}
|
| 28 |
+
to {
|
| 29 |
+
transform: translateY(0);
|
| 30 |
+
opacity: 1;
|
| 31 |
+
}
|
| 32 |
+
}
|
| 33 |
+
.like-animation {
|
| 34 |
+
animation: heartBeat 0.7s;
|
| 35 |
+
}
|
| 36 |
+
@keyframes heartBeat {
|
| 37 |
+
0% { transform: scale(1); }
|
| 38 |
+
14% { transform: scale(1.3); }
|
| 39 |
+
28% { transform: scale(1); }
|
| 40 |
+
42% { transform: scale(1.3); }
|
| 41 |
+
70% { transform: scale(1); }
|
| 42 |
+
}
|
| 43 |
+
</style>
|
| 44 |
+
</head>
|
| 45 |
+
<body class="bg-gray-50 font-sans">
|
| 46 |
+
<!-- Navigation -->
|
| 47 |
+
<nav class="bg-white shadow-lg sticky top-0 z-50">
|
| 48 |
+
<div class="max-w-7xl mx-auto px-4">
|
| 49 |
+
<div class="flex justify-between items-center h-16">
|
| 50 |
+
<div class="flex items-center">
|
| 51 |
+
<a href="#" class="flex items-center" onclick="showHomePage()">
|
| 52 |
+
<span class="text-2xl font-bold text-indigo-600">Art & Lens</span>
|
| 53 |
+
</a>
|
| 54 |
+
</div>
|
| 55 |
+
<div class="hidden md:flex items-center space-x-8">
|
| 56 |
+
<a href="#" class="text-gray-700 hover:text-indigo-600 px-3 py-2 font-medium" onclick="showHomePage()">Home</a>
|
| 57 |
+
<a href="#" class="text-gray-700 hover:text-indigo-600 px-3 py-2 font-medium" onclick="showArtistPage()">Artist</a>
|
| 58 |
+
<a href="#" class="text-gray-700 hover:text-indigo-600 px-3 py-2 font-medium" onclick="showPhotographerPage()">Photographer</a>
|
| 59 |
+
<a href="#" class="text-gray-700 hover:text-indigo-600 px-3 py-2 font-medium" onclick="showAboutPage()">About</a>
|
| 60 |
+
<button id="auth-btn" class="bg-indigo-600 text-white px-4 py-2 rounded-md hover:bg-indigo-700 transition" onclick="toggleAuthModal()">
|
| 61 |
+
Login
|
| 62 |
+
</button>
|
| 63 |
+
</div>
|
| 64 |
+
<div class="md:hidden">
|
| 65 |
+
<button class="text-gray-700 focus:outline-none" onclick="toggleMobileMenu()">
|
| 66 |
+
<svg class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
| 67 |
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16"></path>
|
| 68 |
+
</svg>
|
| 69 |
+
</button>
|
| 70 |
+
</div>
|
| 71 |
+
</div>
|
| 72 |
+
</div>
|
| 73 |
+
<!-- Mobile menu -->
|
| 74 |
+
<div id="mobile-menu" class="md:hidden hidden bg-white">
|
| 75 |
+
<div class="px-2 pt-2 pb-3 space-y-1 sm:px-3">
|
| 76 |
+
<a href="#" class="block px-3 py-2 text-gray-700 hover:text-indigo-600" onclick="showHomePage()">Home</a>
|
| 77 |
+
<a href="#" class="block px-3 py-2 text-gray-700 hover:text-indigo-600" onclick="showArtistPage()">Artist</a>
|
| 78 |
+
<a href="#" class="block px-3 py-2 text-gray-700 hover:text-indigo-600" onclick="showPhotographerPage()">Photographer</a>
|
| 79 |
+
<a href="#" class="block px-3 py-2 text-gray-700 hover:text-indigo-600" onclick="showAboutPage()">About</a>
|
| 80 |
+
<button class="block w-full text-left px-3 py-2 text-gray-700 hover:text-indigo-600" onclick="toggleAuthModal()">
|
| 81 |
+
Login
|
| 82 |
+
</button>
|
| 83 |
+
</div>
|
| 84 |
+
</div>
|
| 85 |
+
</nav>
|
| 86 |
+
|
| 87 |
+
<!-- Main Content -->
|
| 88 |
+
<main class="max-w-7xl mx-auto px-4 py-8">
|
| 89 |
+
<!-- Home Page -->
|
| 90 |
+
<div id="home-page">
|
| 91 |
+
<div class="text-center mb-12">
|
| 92 |
+
<h1 class="text-4xl font-bold text-gray-800 mb-4">Welcome to Art & Lens</h1>
|
| 93 |
+
<p class="text-xl text-gray-600 max-w-3xl mx-auto">A collaborative portfolio showcasing the creative works of our artist and photographer. Explore their unique perspectives and creative expressions.</p>
|
| 94 |
+
</div>
|
| 95 |
+
|
| 96 |
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-8 mb-16">
|
| 97 |
+
<div class="bg-white rounded-xl shadow-md overflow-hidden transition transform hover:-translate-y-2 cursor-pointer" onclick="showArtistPage()">
|
| 98 |
+
<div class="h-64 bg-gradient-to-r from-purple-400 via-pink-500 to-red-500 flex items-center justify-center">
|
| 99 |
+
<i class="fas fa-palette text-white text-7xl"></i>
|
| 100 |
+
</div>
|
| 101 |
+
<div class="p-6">
|
| 102 |
+
<h2 class="text-2xl font-bold text-gray-800 mb-2">The Artist</h2>
|
| 103 |
+
<p class="text-gray-600">Explore a world of colors, textures, and imagination through our artist's unique creations.</p>
|
| 104 |
+
<button class="mt-4 text-indigo-600 font-medium hover:text-indigo-800">View Gallery →</button>
|
| 105 |
+
</div>
|
| 106 |
+
</div>
|
| 107 |
+
|
| 108 |
+
<div class="bg-white rounded-xl shadow-md overflow-hidden transition transform hover:-translate-y-2 cursor-pointer" onclick="showPhotographerPage()">
|
| 109 |
+
<div class="h-64 bg-gradient-to-r from-blue-400 via-green-500 to-teal-500 flex items-center justify-center">
|
| 110 |
+
<i class="fas fa-camera text-white text-7xl"></i>
|
| 111 |
+
</div>
|
| 112 |
+
<div class="p-6">
|
| 113 |
+
<h2 class="text-2xl font-bold text-gray-800 mb-2">The Photographer</h2>
|
| 114 |
+
<p class="text-gray-600">Discover moments frozen in time through our photographer's lens, capturing beauty in the ordinary.</p>
|
| 115 |
+
<button class="mt-4 text-indigo-600 font-medium hover:text-indigo-800">View Gallery →</button>
|
| 116 |
+
</div>
|
| 117 |
+
</div>
|
| 118 |
+
</div>
|
| 119 |
+
|
| 120 |
+
<div class="text-center">
|
| 121 |
+
<button onclick="showAboutPage()" class="bg-indigo-600 text-white px-6 py-3 rounded-lg hover:bg-indigo-700 transition">
|
| 122 |
+
Learn About the Creators
|
| 123 |
+
</button>
|
| 124 |
+
</div>
|
| 125 |
+
</div>
|
| 126 |
+
|
| 127 |
+
<!-- Artist Page -->
|
| 128 |
+
<div id="artist-page" class="hidden">
|
| 129 |
+
<div class="flex justify-between items-center mb-8">
|
| 130 |
+
<h1 class="text-3xl font-bold text-gray-800">Artist Gallery</h1>
|
| 131 |
+
<button id="add-artist-btn" class="hidden bg-indigo-600 text-white px-4 py-2 rounded-md hover:bg-indigo-700 transition" onclick="showAddImageModal('artist')">
|
| 132 |
+
<i class="fas fa-plus mr-2"></i>Add Artwork
|
| 133 |
+
</button>
|
| 134 |
+
</div>
|
| 135 |
+
|
| 136 |
+
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6" id="artist-gallery">
|
| 137 |
+
<!-- Artist gallery items will be added here by JavaScript -->
|
| 138 |
+
</div>
|
| 139 |
+
</div>
|
| 140 |
+
|
| 141 |
+
<!-- Photographer Page -->
|
| 142 |
+
<div id="photographer-page" class="hidden">
|
| 143 |
+
<div class="flex justify-between items-center mb-8">
|
| 144 |
+
<h1 class="text-3xl font-bold text-gray-800">Photography Gallery</h1>
|
| 145 |
+
<button id="add-photographer-btn" class="hidden bg-indigo-600 text-white px-4 py-2 rounded-md hover:bg-indigo-700 transition" onclick="showAddImageModal('photographer')">
|
| 146 |
+
<i class="fas fa-plus mr-2"></i>Add Photo
|
| 147 |
+
</button>
|
| 148 |
+
</div>
|
| 149 |
+
|
| 150 |
+
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6" id="photographer-gallery">
|
| 151 |
+
<!-- Photographer gallery items will be added here by JavaScript -->
|
| 152 |
+
</div>
|
| 153 |
+
</div>
|
| 154 |
+
|
| 155 |
+
<!-- About Page -->
|
| 156 |
+
<div id="about-page" class="hidden">
|
| 157 |
+
<h1 class="text-3xl font-bold text-gray-800 mb-8 text-center">About the Creators</h1>
|
| 158 |
+
|
| 159 |
+
<div class="grid grid-cols-1 md:grid-cols-2 gap-12 mb-16">
|
| 160 |
+
<div class="bg-white rounded-xl shadow-md overflow-hidden">
|
| 161 |
+
<div class="h-64 bg-gradient-to-r from-purple-400 via-pink-500 to-red-500 flex items-center justify-center">
|
| 162 |
+
<i class="fas fa-palette text-white text-7xl"></i>
|
| 163 |
+
</div>
|
| 164 |
+
<div class="p-6">
|
| 165 |
+
<h2 class="text-2xl font-bold text-gray-800 mb-2">Emma Richardson</h2>
|
| 166 |
+
<h3 class="text-lg text-indigo-600 mb-4">Visual Artist</h3>
|
| 167 |
+
<p class="text-gray-600 mb-4">Emma is a contemporary artist specializing in mixed media and abstract expressionism. Her work explores the intersection of human emotion and the natural world.</p>
|
| 168 |
+
<div class="flex space-x-4">
|
| 169 |
+
<a href="#" class="text-blue-500 hover:text-blue-700"><i class="fab fa-instagram text-xl"></i></a>
|
| 170 |
+
<a href="#" class="text-blue-800 hover:text-blue-900"><i class="fab fa-facebook text-xl"></i></a>
|
| 171 |
+
<a href="#" class="text-red-500 hover:text-red-700"><i class="fab fa-youtube text-xl"></i></a>
|
| 172 |
+
</div>
|
| 173 |
+
</div>
|
| 174 |
+
</div>
|
| 175 |
+
|
| 176 |
+
<div class="bg-white rounded-xl shadow-md overflow-hidden">
|
| 177 |
+
<div class="h-64 bg-gradient-to-r from-blue-400 via-green-500 to-teal-500 flex items-center justify-center">
|
| 178 |
+
<i class="fas fa-camera text-white text-7xl"></i>
|
| 179 |
+
</div>
|
| 180 |
+
<div class="p-6">
|
| 181 |
+
<h2 class="text-2xl font-bold text-gray-800 mb-2">James Carter</h2>
|
| 182 |
+
<h3 class="text-lg text-indigo-600 mb-4">Photographer</h3>
|
| 183 |
+
<p class="text-gray-600 mb-4">James is a documentary and landscape photographer with a passion for capturing authentic moments and the beauty of untouched nature.</p>
|
| 184 |
+
<div class="flex space-x-4">
|
| 185 |
+
<a href="#" class="text-blue-500 hover:text-blue-700"><i class="fab fa-instagram text-xl"></i></a>
|
| 186 |
+
<a href="#" class="text-blue-800 hover:text-blue-900"><i class="fab fa-facebook text-xl"></i></a>
|
| 187 |
+
<a href="#" class="text-red-500 hover:text-red-700"><i class="fab fa-youtube text-xl"></i></a>
|
| 188 |
+
</div>
|
| 189 |
+
</div>
|
| 190 |
+
</div>
|
| 191 |
+
</div>
|
| 192 |
+
|
| 193 |
+
<div class="bg-white rounded-xl shadow-md p-8">
|
| 194 |
+
<h2 class="text-2xl font-bold text-gray-800 mb-4">Their Story</h2>
|
| 195 |
+
<p class="text-gray-600 mb-6">Emma and James met during an art exhibition in 2015 where James was photographing the event. Recognizing the synergy between their creative visions, they began collaborating on projects that blend painting and photography in innovative ways.</p>
|
| 196 |
+
|
| 197 |
+
<h3 class="text-xl font-semibold text-gray-800 mb-3">Collaborative Projects</h3>
|
| 198 |
+
<ul class="list-disc pl-5 text-gray-600 space-y-2 mb-6">
|
| 199 |
+
<li>"Light & Texture" - 2017 (Exhibited at Modern Art Gallery)</li>
|
| 200 |
+
<li>"Urban Perspectives" - 2019 (Featured in Art Monthly)</li>
|
| 201 |
+
<li>"Nature Reimagined" - 2021 (Traveling exhibition)</li>
|
| 202 |
+
</ul>
|
| 203 |
+
|
| 204 |
+
<h3 class="text-xl font-semibold text-gray-800 mb-3">Contact</h3>
|
| 205 |
+
<p class="text-gray-600">For inquiries about their work or potential collaborations:</p>
|
| 206 |
+
<p class="text-indigo-600 mt-2">hello@artandlens.com</p>
|
| 207 |
+
<p class="text-gray-600">+1 (555) 123-4567</p>
|
| 208 |
+
</div>
|
| 209 |
+
</div>
|
| 210 |
+
</main>
|
| 211 |
+
|
| 212 |
+
<!-- Image Modal -->
|
| 213 |
+
<div id="image-modal" class="fixed inset-0 bg-black bg-opacity-75 flex items-center justify-center z-50 hidden modal">
|
| 214 |
+
<div class="bg-white rounded-lg max-w-4xl w-full max-h-screen overflow-auto">
|
| 215 |
+
<div class="p-4">
|
| 216 |
+
<div class="flex justify-between items-center mb-4">
|
| 217 |
+
<h3 id="modal-title" class="text-xl font-bold text-gray-800"></h3>
|
| 218 |
+
<button onclick="closeImageModal()" class="text-gray-500 hover:text-gray-700">
|
| 219 |
+
<i class="fas fa-times"></i>
|
| 220 |
+
</button>
|
| 221 |
+
</div>
|
| 222 |
+
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
| 223 |
+
<div class="bg-gray-100 rounded-lg overflow-hidden">
|
| 224 |
+
<img id="modal-image" src="" alt="" class="w-full h-auto object-cover">
|
| 225 |
+
</div>
|
| 226 |
+
<div>
|
| 227 |
+
<div class="flex items-center mb-4">
|
| 228 |
+
<div id="like-container" class="mr-4 cursor-pointer" onclick="toggleLike()">
|
| 229 |
+
<i id="like-icon" class="far fa-heart text-2xl text-gray-500"></i>
|
| 230 |
+
<span id="like-count" class="ml-1 text-gray-700">0</span>
|
| 231 |
+
</div>
|
| 232 |
+
<div id="delete-btn" class="hidden">
|
| 233 |
+
<button onclick="deleteImage()" class="text-red-500 hover:text-red-700">
|
| 234 |
+
<i class="fas fa-trash-alt mr-1"></i> Delete
|
| 235 |
+
</button>
|
| 236 |
+
</div>
|
| 237 |
+
</div>
|
| 238 |
+
<p id="modal-description" class="text-gray-700 mb-4"></p>
|
| 239 |
+
<p id="modal-date" class="text-sm text-gray-500"></p>
|
| 240 |
+
</div>
|
| 241 |
+
</div>
|
| 242 |
+
</div>
|
| 243 |
+
</div>
|
| 244 |
+
</div>
|
| 245 |
+
|
| 246 |
+
<!-- Add Image Modal -->
|
| 247 |
+
<div id="add-image-modal" class="fixed inset-0 bg-black bg-opacity-75 flex items-center justify-center z-50 hidden modal">
|
| 248 |
+
<div class="bg-white rounded-lg max-w-md w-full p-6 auth-modal">
|
| 249 |
+
<div class="flex justify-between items-center mb-4">
|
| 250 |
+
<h3 id="add-modal-title" class="text-xl font-bold text-gray-800">Add New Image</h3>
|
| 251 |
+
<button onclick="closeAddImageModal()" class="text-gray-500 hover:text-gray-700">
|
| 252 |
+
<i class="fas fa-times"></i>
|
| 253 |
+
</button>
|
| 254 |
+
</div>
|
| 255 |
+
<form id="add-image-form" onsubmit="addNewImage(event)">
|
| 256 |
+
<div class="mb-4">
|
| 257 |
+
<label class="block text-gray-700 mb-2" for="image-title">Title</label>
|
| 258 |
+
<input type="text" id="image-title" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500" required>
|
| 259 |
+
</div>
|
| 260 |
+
<div class="mb-4">
|
| 261 |
+
<label class="block text-gray-700 mb-2" for="image-description">Description</label>
|
| 262 |
+
<textarea id="image-description" rows="3" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500"></textarea>
|
| 263 |
+
</div>
|
| 264 |
+
<div class="mb-4">
|
| 265 |
+
<label class="block text-gray-700 mb-2" for="image-upload">Image</label>
|
| 266 |
+
<div class="border-2 border-dashed border-gray-300 rounded-md p-4 text-center">
|
| 267 |
+
<input type="file" id="image-upload" accept="image/*" class="hidden" required>
|
| 268 |
+
<label for="image-upload" class="cursor-pointer">
|
| 269 |
+
<i class="fas fa-cloud-upload-alt text-4xl text-gray-400 mb-2"></i>
|
| 270 |
+
<p class="text-gray-600">Click to upload or drag and drop</p>
|
| 271 |
+
<p class="text-sm text-gray-500 mt-1">PNG, JPG, GIF up to 5MB</p>
|
| 272 |
+
</label>
|
| 273 |
+
</div>
|
| 274 |
+
<div id="image-preview" class="mt-2 hidden">
|
| 275 |
+
<img id="preview-image" src="" alt="Preview" class="max-h-40 rounded-md">
|
| 276 |
+
</div>
|
| 277 |
+
</div>
|
| 278 |
+
<input type="hidden" id="image-category">
|
| 279 |
+
<button type="submit" class="w-full bg-indigo-600 text-white py-2 px-4 rounded-md hover:bg-indigo-700 transition">
|
| 280 |
+
Add Image
|
| 281 |
+
</button>
|
| 282 |
+
</form>
|
| 283 |
+
</div>
|
| 284 |
+
</div>
|
| 285 |
+
|
| 286 |
+
<!-- Auth Modal -->
|
| 287 |
+
<div id="auth-modal" class="fixed inset-0 bg-black bg-opacity-75 flex items-center justify-center z-50 hidden modal">
|
| 288 |
+
<div class="bg-white rounded-lg max-w-md w-full p-6 auth-modal">
|
| 289 |
+
<div class="flex justify-between items-center mb-4">
|
| 290 |
+
<h3 class="text-xl font-bold text-gray-800" id="auth-modal-title">Login</h3>
|
| 291 |
+
<button onclick="toggleAuthModal()" class="text-gray-500 hover:text-gray-700">
|
| 292 |
+
<i class="fas fa-times"></i>
|
| 293 |
+
</button>
|
| 294 |
+
</div>
|
| 295 |
+
<div id="login-form">
|
| 296 |
+
<div class="mb-4">
|
| 297 |
+
<label class="block text-gray-700 mb-2" for="login-email">Email</label>
|
| 298 |
+
<input type="email" id="login-email" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500" required>
|
| 299 |
+
</div>
|
| 300 |
+
<div class="mb-6">
|
| 301 |
+
<label class="block text-gray-700 mb-2" for="login-password">Password</label>
|
| 302 |
+
<input type="password" id="login-password" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500" required>
|
| 303 |
+
</div>
|
| 304 |
+
<button onclick="login()" class="w-full bg-indigo-600 text-white py-2 px-4 rounded-md hover:bg-indigo-700 transition mb-4">
|
| 305 |
+
Login
|
| 306 |
+
</button>
|
| 307 |
+
<p class="text-center text-gray-600">
|
| 308 |
+
Don't have an account?
|
| 309 |
+
<button onclick="showRegisterForm()" class="text-indigo-600 hover:text-indigo-800">Register</button>
|
| 310 |
+
</p>
|
| 311 |
+
</div>
|
| 312 |
+
<div id="register-form" class="hidden">
|
| 313 |
+
<div class="mb-4">
|
| 314 |
+
<label class="block text-gray-700 mb-2" for="register-name">Name</label>
|
| 315 |
+
<input type="text" id="register-name" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500" required>
|
| 316 |
+
</div>
|
| 317 |
+
<div class="mb-4">
|
| 318 |
+
<label class="block text-gray-700 mb-2" for="register-email">Email</label>
|
| 319 |
+
<input type="email" id="register-email" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500" required>
|
| 320 |
+
</div>
|
| 321 |
+
<div class="mb-6">
|
| 322 |
+
<label class="block text-gray-700 mb-2" for="register-password">Password</label>
|
| 323 |
+
<input type="password" id="register-password" class="w-full px-3 py-2 border border-gray-300 rounded-md focus:outline-none focus:ring-2 focus:ring-indigo-500" required>
|
| 324 |
+
</div>
|
| 325 |
+
<button onclick="register()" class="w-full bg-indigo-600 text-white py-2 px-4 rounded-md hover:bg-indigo-700 transition mb-4">
|
| 326 |
+
Register
|
| 327 |
+
</button>
|
| 328 |
+
<p class="text-center text-gray-600">
|
| 329 |
+
Already have an account?
|
| 330 |
+
<button onclick="showLoginForm()" class="text-indigo-600 hover:text-indigo-800">Login</button>
|
| 331 |
+
</p>
|
| 332 |
+
</div>
|
| 333 |
+
</div>
|
| 334 |
+
</div>
|
| 335 |
+
|
| 336 |
+
<script>
|
| 337 |
+
// State management
|
| 338 |
+
let currentUser = null;
|
| 339 |
+
let currentPage = 'home';
|
| 340 |
+
let images = {
|
| 341 |
+
artist: [
|
| 342 |
+
{
|
| 343 |
+
id: 1,
|
| 344 |
+
title: "Abstract Harmony",
|
| 345 |
+
description: "A vibrant exploration of color and form, this piece represents the artist's emotional journey through 2020.",
|
| 346 |
+
imageUrl: "https://source.unsplash.com/random/600x400/?abstract,art",
|
| 347 |
+
likes: 24,
|
| 348 |
+
date: "2023-05-15",
|
| 349 |
+
liked: false
|
| 350 |
+
},
|
| 351 |
+
{
|
| 352 |
+
id: 2,
|
| 353 |
+
title: "Urban Dreams",
|
| 354 |
+
description: "Mixed media on canvas depicting the contrast between urban architecture and natural elements.",
|
| 355 |
+
imageUrl: "https://source.unsplash.com/random/600x400/?city,art",
|
| 356 |
+
likes: 18,
|
| 357 |
+
date: "2023-03-22",
|
| 358 |
+
liked: false
|
| 359 |
+
},
|
| 360 |
+
{
|
| 361 |
+
id: 3,
|
| 362 |
+
title: "Ocean Memories",
|
| 363 |
+
description: "Acrylic painting inspired by childhood summers spent by the sea.",
|
| 364 |
+
imageUrl: "https://source.unsplash.com/random/600x400/?ocean,art",
|
| 365 |
+
likes: 31,
|
| 366 |
+
date: "2023-01-10",
|
| 367 |
+
liked: false
|
| 368 |
+
}
|
| 369 |
+
],
|
| 370 |
+
photographer: [
|
| 371 |
+
{
|
| 372 |
+
id: 1,
|
| 373 |
+
title: "Mountain Dawn",
|
| 374 |
+
description: "Captured during a sunrise hike in the Rockies, this photo showcases the breathtaking beauty of alpine light.",
|
| 375 |
+
imageUrl: "https://source.unsplash.com/random/600x400/?mountain",
|
| 376 |
+
likes: 42,
|
| 377 |
+
date: "2023-06-08",
|
| 378 |
+
liked: false
|
| 379 |
+
},
|
| 380 |
+
{
|
| 381 |
+
id: 2,
|
| 382 |
+
title: "Street Life",
|
| 383 |
+
description: "Candid street photography from downtown Chicago, capturing the energy of urban life.",
|
| 384 |
+
imageUrl: "https://source.unsplash.com/random/600x400/?street,photography",
|
| 385 |
+
likes: 29,
|
| 386 |
+
date: "2023-04-17",
|
| 387 |
+
liked: false
|
| 388 |
+
},
|
| 389 |
+
{
|
| 390 |
+
id: 3,
|
| 391 |
+
title: "Silent Forest",
|
| 392 |
+
description: "Morning mist in an old-growth forest creates an ethereal atmosphere.",
|
| 393 |
+
imageUrl: "https://source.unsplash.com/random/600x400/?forest",
|
| 394 |
+
likes: 36,
|
| 395 |
+
date: "2023-02-03",
|
| 396 |
+
liked: false
|
| 397 |
+
}
|
| 398 |
+
]
|
| 399 |
+
};
|
| 400 |
+
|
| 401 |
+
// DOM Elements
|
| 402 |
+
const homePage = document.getElementById('home-page');
|
| 403 |
+
const artistPage = document.getElementById('artist-page');
|
| 404 |
+
const photographerPage = document.getElementById('photographer-page');
|
| 405 |
+
const aboutPage = document.getElementById('about-page');
|
| 406 |
+
const artistGallery = document.getElementById('artist-gallery');
|
| 407 |
+
const photographerGallery = document.getElementById('photographer-gallery');
|
| 408 |
+
const imageModal = document.getElementById('image-modal');
|
| 409 |
+
const modalImage = document.getElementById('modal-image');
|
| 410 |
+
const modalTitle = document.getElementById('modal-title');
|
| 411 |
+
const modalDescription = document.getElementById('modal-description');
|
| 412 |
+
const modalDate = document.getElementById('modal-date');
|
| 413 |
+
const likeIcon = document.getElementById('like-icon');
|
| 414 |
+
const likeCount = document.getElementById('like-count');
|
| 415 |
+
const deleteBtn = document.getElementById('delete-btn');
|
| 416 |
+
const addImageModal = document.getElementById('add-image-modal');
|
| 417 |
+
const addModalTitle = document.getElementById('add-modal-title');
|
| 418 |
+
const imageCategory = document.getElementById('image-category');
|
| 419 |
+
const authModal = document.getElementById('auth-modal');
|
| 420 |
+
const authModalTitle = document.getElementById('auth-modal-title');
|
| 421 |
+
const loginForm = document.getElementById('login-form');
|
| 422 |
+
const registerForm = document.getElementById('register-form');
|
| 423 |
+
const authBtn = document.getElementById('auth-btn');
|
| 424 |
+
const addArtistBtn = document.getElementById('add-artist-btn');
|
| 425 |
+
const addPhotographerBtn = document.getElementById('add-photographer-btn');
|
| 426 |
+
const mobileMenu = document.getElementById('mobile-menu');
|
| 427 |
+
const imageUpload = document.getElementById('image-upload');
|
| 428 |
+
const imagePreview = document.getElementById('image-preview');
|
| 429 |
+
const previewImage = document.getElementById('preview-image');
|
| 430 |
+
|
| 431 |
+
// Current image being viewed in modal
|
| 432 |
+
let currentImage = null;
|
| 433 |
+
let currentCategory = null;
|
| 434 |
+
|
| 435 |
+
// Initialize the page
|
| 436 |
+
function init() {
|
| 437 |
+
renderGalleries();
|
| 438 |
+
showHomePage();
|
| 439 |
+
|
| 440 |
+
// Event listener for image upload preview
|
| 441 |
+
imageUpload.addEventListener('change', function(e) {
|
| 442 |
+
if (e.target.files.length > 0) {
|
| 443 |
+
const file = e.target.files[0];
|
| 444 |
+
const reader = new FileReader();
|
| 445 |
+
|
| 446 |
+
reader.onload = function(event) {
|
| 447 |
+
previewImage.src = event.target.result;
|
| 448 |
+
imagePreview.classList.remove('hidden');
|
| 449 |
+
};
|
| 450 |
+
|
| 451 |
+
reader.readAsDataURL(file);
|
| 452 |
+
}
|
| 453 |
+
});
|
| 454 |
+
}
|
| 455 |
+
|
| 456 |
+
// Render galleries
|
| 457 |
+
function renderGalleries() {
|
| 458 |
+
renderGallery('artist');
|
| 459 |
+
renderGallery('photographer');
|
| 460 |
+
}
|
| 461 |
+
|
| 462 |
+
// Render a specific gallery
|
| 463 |
+
function renderGallery(category) {
|
| 464 |
+
const gallery = category === 'artist' ? artistGallery : photographerGallery;
|
| 465 |
+
gallery.innerHTML = '';
|
| 466 |
+
|
| 467 |
+
images[category].forEach(image => {
|
| 468 |
+
const galleryItem = document.createElement('div');
|
| 469 |
+
galleryItem.className = 'gallery-item bg-white rounded-lg shadow-md overflow-hidden cursor-pointer';
|
| 470 |
+
galleryItem.innerHTML = `
|
| 471 |
+
<div class="relative">
|
| 472 |
+
<img src="${image.imageUrl}" alt="${image.title}" class="w-full h-64 object-cover">
|
| 473 |
+
<div class="absolute bottom-2 right-2 bg-black bg-opacity-50 text-white px-2 py-1 rounded flex items-center">
|
| 474 |
+
<i class="far fa-heart mr-1"></i>
|
| 475 |
+
<span>${image.likes}</span>
|
| 476 |
+
</div>
|
| 477 |
+
</div>
|
| 478 |
+
<div class="p-4">
|
| 479 |
+
<h3 class="font-semibold text-lg text-gray-800 mb-1">${image.title}</h3>
|
| 480 |
+
<p class="text-gray-600 text-sm truncate">${image.description}</p>
|
| 481 |
+
</div>
|
| 482 |
+
`;
|
| 483 |
+
|
| 484 |
+
galleryItem.addEventListener('click', () => openImageModal(category, image.id));
|
| 485 |
+
gallery.appendChild(galleryItem);
|
| 486 |
+
});
|
| 487 |
+
}
|
| 488 |
+
|
| 489 |
+
// Page navigation functions
|
| 490 |
+
function showHomePage() {
|
| 491 |
+
homePage.classList.remove('hidden');
|
| 492 |
+
artistPage.classList.add('hidden');
|
| 493 |
+
photographerPage.classList.add('hidden');
|
| 494 |
+
aboutPage.classList.add('hidden');
|
| 495 |
+
currentPage = 'home';
|
| 496 |
+
document.title = "Art & Lens | Creative Portfolio";
|
| 497 |
+
}
|
| 498 |
+
|
| 499 |
+
function showArtistPage() {
|
| 500 |
+
homePage.classList.add('hidden');
|
| 501 |
+
artistPage.classList.remove('hidden');
|
| 502 |
+
photographerPage.classList.add('hidden');
|
| 503 |
+
aboutPage.classList.add('hidden');
|
| 504 |
+
currentPage = 'artist';
|
| 505 |
+
document.title = "Art & Lens | Artist Gallery";
|
| 506 |
+
toggleMobileMenu();
|
| 507 |
+
}
|
| 508 |
+
|
| 509 |
+
function showPhotographerPage() {
|
| 510 |
+
homePage.classList.add('hidden');
|
| 511 |
+
artistPage.classList.add('hidden');
|
| 512 |
+
photographerPage.classList.remove('hidden');
|
| 513 |
+
aboutPage.classList.add('hidden');
|
| 514 |
+
currentPage = 'photographer';
|
| 515 |
+
document.title = "Art & Lens | Photography Gallery";
|
| 516 |
+
toggleMobileMenu();
|
| 517 |
+
}
|
| 518 |
+
|
| 519 |
+
function showAboutPage() {
|
| 520 |
+
homePage.classList.add('hidden');
|
| 521 |
+
artistPage.classList.add('hidden');
|
| 522 |
+
photographerPage.classList.add('hidden');
|
| 523 |
+
aboutPage.classList.remove('hidden');
|
| 524 |
+
currentPage = 'about';
|
| 525 |
+
document.title = "Art & Lens | About the Creators";
|
| 526 |
+
toggleMobileMenu();
|
| 527 |
+
}
|
| 528 |
+
|
| 529 |
+
// Image modal functions
|
| 530 |
+
function openImageModal(category, id) {
|
| 531 |
+
currentCategory = category;
|
| 532 |
+
const image = images[category].find(img => img.id === id);
|
| 533 |
+
currentImage = image;
|
| 534 |
+
|
| 535 |
+
modalImage.src = image.imageUrl;
|
| 536 |
+
modalImage.alt = image.title;
|
| 537 |
+
modalTitle.textContent = image.title;
|
| 538 |
+
modalDescription.textContent = image.description;
|
| 539 |
+
modalDate.textContent = `Added on ${image.date}`;
|
| 540 |
+
likeCount.textContent = image.likes;
|
| 541 |
+
|
| 542 |
+
if (image.liked) {
|
| 543 |
+
likeIcon.className = 'fas fa-heart text-2xl text-red-500';
|
| 544 |
+
} else {
|
| 545 |
+
likeIcon.className = 'far fa-heart text-2xl text-gray-500';
|
| 546 |
+
}
|
| 547 |
+
|
| 548 |
+
// Show delete button only for logged in users
|
| 549 |
+
if (currentUser) {
|
| 550 |
+
deleteBtn.classList.remove('hidden');
|
| 551 |
+
} else {
|
| 552 |
+
deleteBtn.classList.add('hidden');
|
| 553 |
+
}
|
| 554 |
+
|
| 555 |
+
imageModal.classList.remove('hidden');
|
| 556 |
+
}
|
| 557 |
+
|
| 558 |
+
function closeImageModal() {
|
| 559 |
+
imageModal.classList.add('hidden');
|
| 560 |
+
}
|
| 561 |
+
|
| 562 |
+
function toggleLike() {
|
| 563 |
+
if (!currentUser) {
|
| 564 |
+
toggleAuthModal();
|
| 565 |
+
return;
|
| 566 |
+
}
|
| 567 |
+
|
| 568 |
+
const image = currentImage;
|
| 569 |
+
const category = currentCategory;
|
| 570 |
+
|
| 571 |
+
const imageIndex = images[category].findIndex(img => img.id === image.id);
|
| 572 |
+
|
| 573 |
+
if (images[category][imageIndex].liked) {
|
| 574 |
+
images[category][imageIndex].liked = false;
|
| 575 |
+
images[category][imageIndex].likes--;
|
| 576 |
+
likeIcon.className = 'far fa-heart text-2xl text-gray-500';
|
| 577 |
+
} else {
|
| 578 |
+
images[category][imageIndex].liked = true;
|
| 579 |
+
images[category][imageIndex].likes++;
|
| 580 |
+
likeIcon.className = 'fas fa-heart text-2xl text-red-500';
|
| 581 |
+
likeIcon.classList.add('like-animation');
|
| 582 |
+
setTimeout(() => {
|
| 583 |
+
likeIcon.classList.remove('like-animation');
|
| 584 |
+
}, 700);
|
| 585 |
+
}
|
| 586 |
+
|
| 587 |
+
likeCount.textContent = images[category][imageIndex].likes;
|
| 588 |
+
renderGalleries();
|
| 589 |
+
}
|
| 590 |
+
|
| 591 |
+
function deleteImage() {
|
| 592 |
+
if (!currentUser) return;
|
| 593 |
+
|
| 594 |
+
const category = currentCategory;
|
| 595 |
+
const id = currentImage.id;
|
| 596 |
+
|
| 597 |
+
images[category] = images[category].filter(img => img.id !== id);
|
| 598 |
+
renderGalleries();
|
| 599 |
+
closeImageModal();
|
| 600 |
+
}
|
| 601 |
+
|
| 602 |
+
// Add image modal functions
|
| 603 |
+
function showAddImageModal(category) {
|
| 604 |
+
if (!currentUser) {
|
| 605 |
+
toggleAuthModal();
|
| 606 |
+
return;
|
| 607 |
+
}
|
| 608 |
+
|
| 609 |
+
imageCategory.value = category;
|
| 610 |
+
addModalTitle.textContent = category === 'artist' ? 'Add New Artwork' : 'Add New Photo';
|
| 611 |
+
document.getElementById('image-title').value = '';
|
| 612 |
+
document.getElementById('image-description').value = '';
|
| 613 |
+
imageUpload.value = '';
|
| 614 |
+
imagePreview.classList.add('hidden');
|
| 615 |
+
addImageModal.classList.remove('hidden');
|
| 616 |
+
}
|
| 617 |
+
|
| 618 |
+
function closeAddImageModal() {
|
| 619 |
+
addImageModal.classList.add('hidden');
|
| 620 |
+
}
|
| 621 |
+
|
| 622 |
+
function addNewImage(e) {
|
| 623 |
+
e.preventDefault();
|
| 624 |
+
|
| 625 |
+
const category = imageCategory.value;
|
| 626 |
+
const title = document.getElementById('image-title').value;
|
| 627 |
+
const description = document.getElementById('image-description').value;
|
| 628 |
+
const file = imageUpload.files[0];
|
| 629 |
+
|
| 630 |
+
if (!file) return;
|
| 631 |
+
|
| 632 |
+
// In a real app, you would upload the file to a server
|
| 633 |
+
// For this demo, we'll use a placeholder
|
| 634 |
+
const reader = new FileReader();
|
| 635 |
+
reader.onload = function(event) {
|
| 636 |
+
const newImage = {
|
| 637 |
+
id: images[category].length + 1,
|
| 638 |
+
title: title,
|
| 639 |
+
description: description,
|
| 640 |
+
imageUrl: event.target.result,
|
| 641 |
+
likes: 0,
|
| 642 |
+
date: new Date().toISOString().split('T')[0],
|
| 643 |
+
liked: false
|
| 644 |
+
};
|
| 645 |
+
|
| 646 |
+
images[category].unshift(newImage);
|
| 647 |
+
renderGalleries();
|
| 648 |
+
closeAddImageModal();
|
| 649 |
+
|
| 650 |
+
// Open the new image in the modal
|
| 651 |
+
setTimeout(() => {
|
| 652 |
+
openImageModal(category, newImage.id);
|
| 653 |
+
}, 300);
|
| 654 |
+
};
|
| 655 |
+
|
| 656 |
+
reader.readAsDataURL(file);
|
| 657 |
+
}
|
| 658 |
+
|
| 659 |
+
// Auth functions
|
| 660 |
+
function toggleAuthModal() {
|
| 661 |
+
if (authModal.classList.contains('hidden')) {
|
| 662 |
+
authModal.classList.remove('hidden');
|
| 663 |
+
showLoginForm();
|
| 664 |
+
} else {
|
| 665 |
+
authModal.classList.add('hidden');
|
| 666 |
+
}
|
| 667 |
+
}
|
| 668 |
+
|
| 669 |
+
function showLoginForm() {
|
| 670 |
+
loginForm.classList.remove('hidden');
|
| 671 |
+
registerForm.classList.add('hidden');
|
| 672 |
+
authModalTitle.textContent = 'Login';
|
| 673 |
+
}
|
| 674 |
+
|
| 675 |
+
function showRegisterForm() {
|
| 676 |
+
loginForm.classList.add('hidden');
|
| 677 |
+
registerForm.classList.remove('hidden');
|
| 678 |
+
authModalTitle.textContent = 'Register';
|
| 679 |
+
}
|
| 680 |
+
|
| 681 |
+
function login() {
|
| 682 |
+
const email = document.getElementById('login-email').value;
|
| 683 |
+
const password = document.getElementById('login-password').value;
|
| 684 |
+
|
| 685 |
+
// In a real app, you would validate against a backend
|
| 686 |
+
if (email && password) {
|
| 687 |
+
currentUser = {
|
| 688 |
+
email: email,
|
| 689 |
+
name: email.split('@')[0]
|
| 690 |
+
};
|
| 691 |
+
|
| 692 |
+
authBtn.innerHTML = `<i class="fas fa-user-circle mr-2"></i>${currentUser.name}`;
|
| 693 |
+
toggleAuthModal();
|
| 694 |
+
|
| 695 |
+
// Show add buttons if on artist or photographer page
|
| 696 |
+
if (currentPage === 'artist') {
|
| 697 |
+
addArtistBtn.classList.remove('hidden');
|
| 698 |
+
} else if (currentPage === 'photographer') {
|
| 699 |
+
addPhotographerBtn.classList.remove('hidden');
|
| 700 |
+
}
|
| 701 |
+
|
| 702 |
+
// Update delete button visibility in modal if open
|
| 703 |
+
if (!imageModal.classList.contains('hidden')) {
|
| 704 |
+
deleteBtn.classList.remove('hidden');
|
| 705 |
+
}
|
| 706 |
+
}
|
| 707 |
+
}
|
| 708 |
+
|
| 709 |
+
function register() {
|
| 710 |
+
const name = document.getElementById('register-name').value;
|
| 711 |
+
const email = document.getElementById('register-email').value;
|
| 712 |
+
const password = document.getElementById('register-password').value;
|
| 713 |
+
|
| 714 |
+
// In a real app, you would send this to a backend
|
| 715 |
+
if (name && email && password) {
|
| 716 |
+
currentUser = {
|
| 717 |
+
email: email,
|
| 718 |
+
name: name
|
| 719 |
+
};
|
| 720 |
+
|
| 721 |
+
authBtn.innerHTML = `<i class="fas fa-user-circle mr-2"></i>${currentUser.name}`;
|
| 722 |
+
toggleAuthModal();
|
| 723 |
+
showLoginForm();
|
| 724 |
+
|
| 725 |
+
// Show add buttons if on artist or photographer page
|
| 726 |
+
if (currentPage === 'artist') {
|
| 727 |
+
addArtistBtn.classList.remove('hidden');
|
| 728 |
+
} else if (currentPage === 'photographer') {
|
| 729 |
+
addPhotographerBtn.classList.remove('hidden');
|
| 730 |
+
}
|
| 731 |
+
}
|
| 732 |
+
}
|
| 733 |
+
|
| 734 |
+
function logout() {
|
| 735 |
+
currentUser = null;
|
| 736 |
+
authBtn.textContent = 'Login';
|
| 737 |
+
|
| 738 |
+
// Hide add buttons
|
| 739 |
+
addArtistBtn.classList.add('hidden');
|
| 740 |
+
addPhotographerBtn.classList.add('hidden');
|
| 741 |
+
|
| 742 |
+
// Update delete button visibility in modal if open
|
| 743 |
+
if (!imageModal.classList.contains('hidden')) {
|
| 744 |
+
deleteBtn.classList.add('hidden');
|
| 745 |
+
}
|
| 746 |
+
}
|
| 747 |
+
|
| 748 |
+
// Mobile menu toggle
|
| 749 |
+
function toggleMobileMenu() {
|
| 750 |
+
if (mobileMenu.classList.contains('hidden')) {
|
| 751 |
+
mobileMenu.classList.remove('hidden');
|
| 752 |
+
} else {
|
| 753 |
+
mobileMenu.classList.add('hidden');
|
| 754 |
+
}
|
| 755 |
+
}
|
| 756 |
+
|
| 757 |
+
// Initialize the app
|
| 758 |
+
init();
|
| 759 |
+
</script>
|
| 760 |
+
<p style="border-radius: 8px; text-align: center; font-size: 12px; color: #fff; margin-top: 16px;position: fixed; left: 8px; bottom: 8px; z-index: 10; background: rgba(0, 0, 0, 0.8); padding: 4px 8px;">Made with <img src="https://enzostvs-deepsite.hf.space/logo.svg" alt="DeepSite Logo" style="width: 16px; height: 16px; vertical-align: middle;display:inline-block;margin-right:3px;filter:brightness(0) invert(1);"><a href="https://enzostvs-deepsite.hf.space" style="color: #fff;text-decoration: underline;" target="_blank" >DeepSite</a> - 🧬 <a href="https://enzostvs-deepsite.hf.space?remix=Doces/portfolio-page" style="color: #fff;text-decoration: underline;" target="_blank" >Remix</a></p></body>
|
| 761 |
+
</html>
|
prompts.txt
ADDED
|
@@ -0,0 +1 @@
|
|
|
|
|
|
|
| 1 |
+
Write a photo portfolio website for two people, an artist and a photographer. The site should have a page for each of the two people. Add the ability to add and delete images, add a description to each photo. Add the authorization option. Add the option to like it. Add a separate page about the authors
|