Skip to content

Commit

Permalink
Polish frontend
Browse files Browse the repository at this point in the history
  • Loading branch information
caseyavila committed Dec 8, 2023
1 parent 14a9c4d commit cd497b8
Show file tree
Hide file tree
Showing 4 changed files with 110 additions and 65 deletions.
74 changes: 40 additions & 34 deletions Frontend/src/pages/create.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,44 +10,43 @@ export default function Create() {
const [url, setUrl] = useState("");
const [isImageAccepted, setImageAccepted] = useState(null); // null = not decided, true = accepted, false = rejected
const [generating, setGenerating] = useState(false);
const [accepting, setAccepting] = useState(false);
const [failed, setFailed] = useState(false);

const handleSubmit = async (e) => {
e.preventDefault();

try {
setGenerating(true);
setFailed(false);
setImageAccepted(null);
await axios.post(
"http://localhost:5000/generate_image",
{ prompt: text },
{
headers: {
"Authorization": `Bearer ${Cookie.get("token")}`
}
},
).then(response => {
if (response.data.output) {
setUrl(response.data.output);
setImageAccepted(null); // Reset the decision state when a new image is fetched
} else if (response.data.error) {
setFailed(true);
console.error(response.data.error);
}
}).then(() => setGenerating(false));

} catch (error) {
setFailed(true);
setGenerating(false);
console.error("Error:", error);
}
setGenerating(true);
setFailed(false);
setImageAccepted(null);
await axios.post(
"http://localhost:5000/generate_image",
{ prompt: text },
{
headers: {
"Authorization": `Bearer ${Cookie.get("token")}`
}
},
).then(response => {
if (response.data.output) {
setUrl(response.data.output);
setImageAccepted(null); // Reset the decision state when a new image is fetched
} else if (response.data.error) {
setFailed(true);
console.error(response.data.error);
}
}).catch((error) => {
setFailed(true);
console.error("Error:", error);
}).then(() => {
setGenerating(false);
});
};

const handleAccept = async (e) => {
e.preventDefault();

setImageAccepted(true);
setAccepting(true);
await axios.post("http://localhost:5000/store_image",
{
"prompt": text,
Expand All @@ -57,11 +56,17 @@ export default function Create() {
headers: {
"Authorization": `Bearer ${Cookie.get("token")}`
}
}).catch((error) => console.error("Error: ", error))};
}).catch((error) => console.error("Error: ", error))
.then(() => {
setUrl("");
setAccepting(false);
setImageAccepted(true);
});
}

const handleReject = () => {
setImageAccepted(false);
setUrl(""); // Clear the image if rejected, or add any other logic if needed
setUrl("");
};

return (
Expand Down Expand Up @@ -98,9 +103,10 @@ export default function Create() {
<div className="mt-4 flex justify-center gap-4">
<button
onClick={handleAccept}
className="bg-green-500 text-white p-2 rounded hover:bg-green-600 focus:outline-none focus:ring-2 focus:ring-green-500"
className="bg-green-500 text-white p-2 rounded hover:bg-green-600 focus:outline-none focus:ring-2 focus:ring-green-500 disabled:bg-green-300"
disabled={accepting}
>
Accept
{accepting ? "Accepting..." : "Accept"}
</button>
<button
onClick={handleReject}
Expand All @@ -112,10 +118,10 @@ export default function Create() {
</div>
)}

{isImageAccepted === true && (
{isImageAccepted === true && accepting === false && (
<p className="mt-8 text-green-500">Image accepted!</p>
)}
{isImageAccepted === false && (
{isImageAccepted === false && accepting === false && (
<p className="mt-8 text-red-500">Image rejected.</p>
)}
{failed === true && (
Expand Down
17 changes: 8 additions & 9 deletions Frontend/src/pages/leaderboard.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,19 +40,20 @@ const Leaderboard = () => {
{images.map((image) => (
<div
key={image.id}
className="bg-white p-4 rounded-lg shadow-md cursor-pointer transition-transform transform hover:scale-105"
className="transition-transform transform hover:scale-105"
onClick={() => openImageModal(image)}
>
<div className="w-full h-64 relative rounded-lg mb-4">
<div className="w-full h-full relative rounded-lg">
<Image
className="rounded-lg"
src={image.url}
alt='Votable Image'
layout="fill"
objectFit="cover"
width={1024}
height={1024}
/>
<div className="absolute inset-0 flex flex-col justify-end p-4 bg-black bg-opacity-0 text-white">
<p className="text-lg font-semibold">{image.creator}</p>
<p className="text-gray-100 font-semibold">ELO: {image.elo}</p>
<p className="text-lg font-semibold drop-shadow-[1px_1px_0.5px_rgba(0,0,0,1)]">{image.creator}</p>
<p className="text-gray-100 font-semibold drop-shadow-[1px_1px_0.5px_rgba(0,0,0,1)]">{image.elo}</p>
</div>
</div>
</div>
Expand All @@ -65,20 +66,18 @@ const Leaderboard = () => {
className="fixed top-0 left-0 w-full h-full flex justify-center items-center bg-black bg-opacity-80"
onClick={handleModalClick}
>
<div className="bg-white p-4 rounded-lg shadow-md" ref={modalRef}>
<div ref={modalRef}>
<button
className="absolute top-2 right-2 text-gray-600 hover:text-gray-900"
onClick={closeImageModal}
>
Close
</button>
<Image
src={selectedImage.url}
alt='Votable Image'
width={800}
height={800}
/>
<p className="text-lg text-gray-800 mt-2">&quot;{selectedImage.prompt}&quot; ~{selectedImage.creator}</p>
</div>
</div>
)}
Expand Down
8 changes: 4 additions & 4 deletions Frontend/src/pages/nav.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,22 +30,22 @@ const NavBar = () => {
{/* Primary Navbar items */}
<div className="hidden md:flex items-center space-x-1">
<Link href="/vote">
<span className="py-4 px-2 text-gray-300 font-semibold hover:text-blue-400 transition duration-300 cursor-pointer">
<span className={`py-4 px-2 ${window.location.pathname === "/vote" ? "text-blue-400" : "text-gray-300"} font-semibold hover:text-blue-400 transition duration-300 cursor-pointer`}>
Vote
</span>
</Link>
<Link href="/portfolio">
<span className="py-4 px-2 text-gray-300 font-semibold hover:text-blue-400 transition duration-300 cursor-pointer">
<span className={`py-4 px-2 ${window.location.pathname === "/portfolio" ? "text-blue-400" : "text-gray-300"} text-gray-300 font-semibold hover:text-blue-400 transition duration-300 cursor-pointer`}>
Portfolio
</span>
</Link>
<Link href="/leaderboard">
<span className="py-4 px-2 text-gray-300 font-semibold hover:text-blue-400 transition duration-300 cursor-pointer">
<span className={`py-4 px-2 ${window.location.pathname === "/leaderboard" ? "text-blue-400" : "text-gray-300"} text-gray-300 font-semibold hover:text-blue-400 transition duration-300 cursor-pointer`}>
Leaderboard
</span>
</Link>
<Link href="/create">
<span className="py-4 px-2 text-gray-300 font-semibold hover:text-blue-400 transition duration-300 cursor-pointer">
<span className={`py-4 px-2 ${window.location.pathname === "/create" ? "text-blue-400" : "text-gray-300"} text-gray-300 font-semibold hover:text-blue-400 transition duration-300 cursor-pointer`}>
Create
</span>
</Link>
Expand Down
76 changes: 58 additions & 18 deletions Frontend/src/pages/portfolio.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import Link from "next/link";
import { isAuthenticated } from "./auth";
import Cookie from "js-cookie";
import React, { useEffect, useState } from "react";
import React, { useEffect, useState, useRef } from "react";
import Image from "next/image";
import axios from "axios";

export default function Portfolio() {
const [portfolio, setPortfolio] = useState(null);
const [selectedImage, setSelectedImage] = useState(null);
const modalRef = useRef(null);

useEffect(() => {
async function fetch_portfolio() {
Expand All @@ -24,28 +26,66 @@ export default function Portfolio() {
fetch_portfolio();
}, []);

const openImageModal = (image) => {
setSelectedImage(image);
};

const closeImageModal = () => {
setSelectedImage(null);
};

const handleModalClick = (e) => {
// Check if the click event occurred outside the image modal
if (modalRef.current && !modalRef.current.contains(e.target)) {
closeImageModal();
}
};

return (
<div className="bg-gray-100 min-h-screen p-6">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
<div className="bg-gray-100 min-h-screen py-8">
<div className="container mx-auto">
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4">
{portfolio && portfolio.map((image) => (
<div key={image.url} className="w-full h-64 relative rounded-lg overflow-hidden mb-4"> {/* Add key here */}
<Image
src={image.url}
loader={() => image.url}
layout="fill"
objectFit="cover"
/>
<div
key={image.id}
className="transition-transform transform hover:scale-105"
onClick={() => openImageModal(image)}
>
<div className="w-full h-full relative rounded-lg">
<Image
className="rounded-lg"
src={image.url}
alt='Votable Image'
width={1024}
height={1024}
/>
</div>
</div>
))}

<Link legacyBehavior href="/create" passHref>
<a className="w-full h-64 rounded-lg flex justify-center items-center border-4 border-dotted border-gray-300 hover:border-solid hover:bg-gray-50 transition-all duration-300 cursor-pointer">
<svg xmlns="http://www.w3.org/2000/svg" className="h-16 w-16 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="2">
<path strokeLinecap="round" strokeLinejoin="round" d="M12 4v16m8-8H4" />
</svg>
</a>
</Link>
</div>
</div>

{selectedImage && (
<div
className="fixed top-0 left-0 w-full h-full flex justify-center items-center bg-black bg-opacity-80"
onClick={handleModalClick}
>
<div className="bg-white rounded-lg" ref={modalRef}>
<button
className="bg-white absolute top-2 right-2 text-gray-600 hover:text-gray-900"
onClick={closeImageModal}
>
</button>
<Image
src={selectedImage.url}
alt='Votable Image'
width={500}
height={500}
/>
<p className="m-4">"{selectedImage.prompt}"</p>
</div>
</div>
)}
</div>
);
};
Expand Down

0 comments on commit cd497b8

Please sign in to comment.