Skip to content

Commit

Permalink
Image Details Working
Browse files Browse the repository at this point in the history
  • Loading branch information
maxtyson123 committed Oct 5, 2024
1 parent b3f6b95 commit 68fcf6c
Show file tree
Hide file tree
Showing 15 changed files with 302 additions and 151 deletions.
1 change: 1 addition & 0 deletions server/my_sql/create_tables.sql
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ CREATE TABLE IF NOT EXISTS posts (
post_image TEXT,
post_approved BOOLEAN,
post_in_use BOOLEAN,
post_description TEXT,
PRIMARY KEY (id),
FOREIGN KEY (post_plant_id) REFERENCES plants(id),
FOREIGN KEY (post_user_id) REFERENCES users(id)
Expand Down
73 changes: 73 additions & 0 deletions website/src/components/input_sections.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -983,4 +983,77 @@ export function PlantSelector({defaultValue, setPlant, allowNew}: PlantSelectorP
forceOptions={allowNew}
/>
)
}

type UserSelectorProps = {
defaultValue?: string | number;
setUser: (value: number) => void;
allowNew?: boolean;
}

export function UserSelector({defaultValue, setUser, allowNew}: UserSelectorProps) {

const [userNames, setUserNames] = useState<string[]>(["Enter a user name"]);
const [userIDs, setUserIDs] = useState<number[]>([]);
const [defaultUser, setDefaultUser] = useState<string>();
const [selectedUser, setSelectedUser] = useState<string>("");

useEffect(() => {
fetchData()
}, [])

useEffect(() => {

// Set the plant
setUser(userIDs[userNames.indexOf(selectedUser)])

}, [selectedUser]);


useEffect(() => {

if(userNames[0] == "Loading..."){
return
}

// If number get the string
if(typeof defaultValue === "number"){
setDefaultUser(userNames[userIDs.indexOf(defaultValue)])
}
else {
setDefaultUser(defaultValue)
}


}, [defaultValue, userNames]);


const fetchData = async () => {
// Get the users
let users = await makeCachedRequest('user_names_all', '/api/plants/search?getNames=true&getUsers=true&getPlants=false', true);
users = users.users

// Get the plant names
let userNames = users.map((user: any) => { return user.user_name });

// Set the first letter to be capital
userNames = userNames.map(option => toTitleCase(option));

const plantIDs = users.map((user: any) => user.id);

setUserNames(userNames);
setUserIDs(plantIDs);
}

return (
<FilteredSearchInput
required={false}
placeHolder={"User"}
state={"normal"}
options={userNames}
defaultValue={defaultUser}
changeEventHandler={setSelectedUser}
forceOptions={allowNew}
/>
)
}
85 changes: 63 additions & 22 deletions website/src/components/modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {getFilePath, getPostImage} from "@/lib/data";
import {UserCard} from "@/pages/media/components/cards";
import {RongoaUser} from "@/lib/users";
import {useSession} from "next-auth/react";
import {PlantSelector} from "@/components/input_sections";
import {PlantSelector, SimpleTextArea, UserSelector} from "@/components/input_sections";
import {Loading} from "@/components/loading";
import {postImage} from "@/pages/media/new";

Expand Down Expand Up @@ -84,7 +84,8 @@ export function ImagePopup({show, hideCallback, id = 0, setImages, startImages}:
const [currentImageDescription, setCurrentImageDescription] = useState("No Description")
const [currentImageDate, setCurrentImageDate] = useState("No Date")
const [currentImagePlant, setCurrentImagePlant] = useState("No Plant Selected")
const [currentImageUser, setCurrentImageUser] = useState(20)
const [currentImageUser, setCurrentImageUser] = useState(0)
const [currentImageMine, setCurrentImageMine] = useState(true)

const [thisImages, setThisImages] = useState<object[]>([])
const [postImages, setPostImages] = useState<object[]>([])
Expand Down Expand Up @@ -180,11 +181,8 @@ export function ImagePopup({show, hideCallback, id = 0, setImages, startImages}:

}


let cSelectedImages = [Array(thisPlantPosts.length).fill(false), Array(thisPostsPosts.length).fill(false), Array(plantUserPosts.length).fill(false)]
setSelectedImages(cSelectedImages)


}


Expand All @@ -200,6 +198,7 @@ export function ImagePopup({show, hideCallback, id = 0, setImages, startImages}:
setCurrentImageUser(currentImage.post_user_id)
setCurrentImagePlant((plantNames[plantIDs.indexOf(currentImage.post_plant_id)]))
setCurrentImageDate(new Date(currentImage.post_date).toLocaleString())
setCurrentImageDescription(currentImage.post_description)

// If the current tab is the post gallery
if(tab === 1){
Expand All @@ -224,7 +223,7 @@ export function ImagePopup({show, hideCallback, id = 0, setImages, startImages}:
}
}else{

// Update the posts tab if its the same image
// Update the posts tab if it's the same image
let myPostIndex = myImages.findIndex((post: any) => post.id === currentImage.id)
if(myPostIndex !== -1){
newSelectedImages[2][myPostIndex] = newSelectedImages[tab][imageIndex]
Expand Down Expand Up @@ -274,9 +273,11 @@ export function ImagePopup({show, hideCallback, id = 0, setImages, startImages}:
const resetCurrentImage = () => {
setCurrentImage("/media/images/logo.svg")
setCurrentImageName("No Image Selected")
setCurrentImageUser(20)
setCurrentImageUser(0)
setCurrentImagePlant("No Plant Selected")
setCurrentImageDate("No Date")
setCurrentImageMine(false)
setCurrentImageDescription("No Description")
}


Expand Down Expand Up @@ -389,18 +390,31 @@ export function ImagePopup({show, hideCallback, id = 0, setImages, startImages}:

const uploadImage = async (image: string) => {


// Get the file
const file = localFiles[localImages.indexOf(image)]
console.log(file)

// Check if the title has been set
const titleInput = document.getElementById("title") as HTMLElement;
const title = titleInput.innerText;
if(title === "Please Type a Title Here" || title === "No Image Selected") {
if(title === "Please Type a Title Here" || title === "No Image Selected" || title.length < 3) {
alert("Please type a title")
return;
}

// Check if the description has been set
if(currentImageDescription === "No Description" || currentImageDescription.length < 3) {
alert("Please type a description")
return;
}

// Check if the user is the author
if(!currentImageMine && (currentImageUser === 0 || currentImageUser == undefined)){
alert("Please select a user or check the 'I took this image' box")
return
}



// Set the loading message
setLoadingMessage("Uploading image")
Expand All @@ -412,7 +426,7 @@ export function ImagePopup({show, hideCallback, id = 0, setImages, startImages}:
const userName = user.database.user_name

// Upload the image
const newPost = await postImage(file, title, id, userID, userName, setLoadingMessage, true)
const newPost = await postImage(file, title, currentImageDescription, id, (currentImageMine ? userID : currentImageUser), userName, setLoadingMessage, true)

if(!newPost)
return
Expand All @@ -429,7 +443,9 @@ export function ImagePopup({show, hideCallback, id = 0, setImages, startImages}:
sessionStorage.removeItem("editor_posts_"+id)
sessionStorage.removeItem("editor_posts_mine_"+id)

setMyImages((prev) => [...prev, newPost])
if(currentImageMine)
setMyImages((prev) => [...prev, newPost])

setThisImages((prev) => [...prev, newPost])
let newSelectedImages = selectedImages
newSelectedImages[0].push(true)
Expand Down Expand Up @@ -472,30 +488,52 @@ export function ImagePopup({show, hideCallback, id = 0, setImages, startImages}:

{/* Side panel */}
<div className={styles.sidePanel}>
<img src={currentImage}
alt={currentImageName}/>

<img src={currentImage} alt={currentImageName}/>
<div>
<h1
id={"title"}
contentEditable={activeTab == 3 && currentImageName !== "No Image Selected"}
>{currentImageName}</h1>
<h2>Description</h2>

{ activeTab !== 3 ?
<p>{currentImageDescription}</p>
:
<SimpleTextArea
placeHolder={"Description"}
required={true}
state={"normal"}
changeEventHandler={setCurrentImageDescription}
/>
}

</div>

<div>
<h3>{currentImage}</h3>
{ activeTab !== 3 &&
<div key={currentImageMine ? "a" : "b"}>
{ activeTab !== 3 ?
<>
<h3>{currentImage}</h3>
<h3>{currentImagePlant}</h3>
<h3>{currentImageDate}</h3>
</>
:
<>
<div className={styles.myImage}>
<input type={"checkbox"} id={"myImage"} name={"myImage"} defaultChecked={currentImageMine} onChange={() => setCurrentImageMine(!currentImageMine)}/>
<label htmlFor={"myImage"}>I took this image</label>
</div>
{
!currentImageMine &&
<UserSelector
setUser={setCurrentImageUser}
/>
}
</>
}
</div>

{activeTab == 3 ?
<>
<button
<>
<button
className={styles.uploadImageButton}
onClick={() => uploadImage(currentImage)}>Upload</button>
</>
Expand Down Expand Up @@ -526,6 +564,8 @@ export function ImagePopup({show, hideCallback, id = 0, setImages, startImages}:
onClick={() => {
setCurrentImage(image)
setCurrentImageName("Please Type a Title Here")
setCurrentImageMine(false)
setCurrentImageDescription("")
}}
/>
</div>
Expand All @@ -534,8 +574,9 @@ export function ImagePopup({show, hideCallback, id = 0, setImages, startImages}:

{/* Upload Image Only Button */}
{!isDragging &&
<button className={styles.uploadImageButton} onClick={submitFile}>Upload
Image</button>}
<button className={styles.uploadImageButton} onClick={submitFile}>Select
Image(s)</button>
}

</>
:
Expand Down
56 changes: 14 additions & 42 deletions website/src/components/plant_card.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
import styles from "@/styles/components/plant_card.module.css"
import Link from "next/link";
import {fetchPlant, getNamesInPreference, ImageMetaData, PlantData} from "@/lib/plant_data";
import {fetchPlant, getNamesInPreference, ImageMetaData, PlantData, PostData} from "@/lib/plant_data";
import {useEffect, useRef, useState} from "react";
import Image from "next/image";
import {CreditedImage} from "@/components/credits";
import {useRouter} from "next/router";
import {getPostImage} from "@/lib/data";

//TODO: Move all to cards.tsx

// Define the props for the plant card and the types for the plant data
type PlantCardProps = {
Expand All @@ -22,55 +25,24 @@ type PlantCardProps = {
export default function PlantCardData({ data}: PlantCardProps){

const [names, setNames] = useState(["None", "None", "None"])
const [mainImage, setMainImage] = useState("/media/images/loading.gif")
const [mainImageAlt, setMainImageAlt] = useState("Loading")
const [mainImageCredits, setMainImageCredits] = useState("None")
const router = useRouter()
let currentImage = {
post_user_id: 0,
post_title: "",
post_image: "/media/images/loading.gif",

} as PostData

// Run on page start
useEffect(() => {

// Update the names
setNames(getNamesInPreference(data))

}, [data])
if(data.display_images.length === 0) return
currentImage = data.display_images[Math.floor(Math.random() * data.display_images.length)]

useEffect(() => {
// Get all the attachments with image type
let images = data?.attachments.filter((attachment) => attachment.type === "image")

// Set the main image
switch (data?.display_image){

case "Default":
setMainImage("/media/images/default_noImage.png")
setMainImageAlt("Default Image")
break;

case "Random":
// Get a random index and set the image
if(images){
let image = images[Math.floor(Math.random() * images.length)]
setMainImage(image.path)
setMainImageAlt((image.meta as ImageMetaData).name)
}
break;

default:
// Find the image with the same name as the display image
if(images){
let image = images.find((image) => (image.meta as ImageMetaData).name === data?.display_image)
if(!image){
break;
}
setMainImage(image.path)
setMainImageAlt((image.meta as ImageMetaData).name)
setMainImageCredits((image.meta as ImageMetaData).credits)
}
break;

}
}, [])
}, [data])


const goToIndex = (filter: string) => {
Expand Down Expand Up @@ -99,7 +71,7 @@ export default function PlantCardData({ data}: PlantCardProps){
{/* Image of the plant, grabbed from the image attachments of the pant data*/}
<div className={styles.imageContainer}>
<Link href={"/plants/" + data.id}>
<CreditedImage url={mainImage} alt={mainImageAlt} credits={mainImageCredits} colour={"white"}/>
<CreditedImage url={currentImage.post_user_id == 0 ? currentImage.post_image : getPostImage(currentImage)} alt={currentImage.post_title} credits={currentImage.post_user_id.toString()} colour={"white"}/>
</Link>
</div>

Expand Down
7 changes: 4 additions & 3 deletions website/src/lib/api_tools.ts
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ export async function makeRequestWithToken (
}


export async function makeCachedRequest(key: string, url: string){
export async function makeCachedRequest(key: string, url: string, dontParse: boolean = false){

let cache = getFromCache(key)
if(cache){
Expand All @@ -173,9 +173,10 @@ export async function makeCachedRequest(key: string, url: string){
cache = await makeRequestWithToken("get",url)
if(!cache.data.error){

saveToCache(key, cache.data.data)

saveToCache(key, dontParse ? cache.data : cache.data.data)
}
return cache.data.data
return dontParse ? cache.data : cache.data.data
}

export function removeCachedRequest(key: string){
Expand Down
Loading

0 comments on commit 68fcf6c

Please sign in to comment.