From 68fcf6c8967eca345607fd0e474fb32f940d5c73 Mon Sep 17 00:00:00 2001 From: Max Tyson <98maxt98@gmail.com> Date: Sat, 5 Oct 2024 17:34:49 +1300 Subject: [PATCH] Image Details Working --- server/my_sql/create_tables.sql | 1 + website/src/components/input_sections.tsx | 73 +++++++++ website/src/components/modal.tsx | 85 ++++++++--- website/src/components/plant_card.tsx | 56 ++----- website/src/lib/api_tools.ts | 7 +- website/src/lib/databse.ts | 2 + website/src/lib/plant_data.ts | 1 + website/src/pages/api/plants/search.ts | 139 ++++++++++-------- website/src/pages/api/posts/new.ts | 8 +- website/src/pages/index.tsx | 10 +- website/src/pages/media/components/cards.tsx | 3 + website/src/pages/media/new.tsx | 34 ++++- website/src/pages/plants/[id].tsx | 19 ++- website/src/pages/plants/create.tsx | 2 +- .../src/styles/components/modal.module.css | 13 ++ 15 files changed, 302 insertions(+), 151 deletions(-) diff --git a/server/my_sql/create_tables.sql b/server/my_sql/create_tables.sql index eb2660a..2b148bb 100644 --- a/server/my_sql/create_tables.sql +++ b/server/my_sql/create_tables.sql @@ -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) diff --git a/website/src/components/input_sections.tsx b/website/src/components/input_sections.tsx index b8e00e0..1f11454 100644 --- a/website/src/components/input_sections.tsx +++ b/website/src/components/input_sections.tsx @@ -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(["Enter a user name"]); + const [userIDs, setUserIDs] = useState([]); + const [defaultUser, setDefaultUser] = useState(); + const [selectedUser, setSelectedUser] = useState(""); + + 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 ( + + ) } \ No newline at end of file diff --git a/website/src/components/modal.tsx b/website/src/components/modal.tsx index ddd816f..c62f41f 100644 --- a/website/src/components/modal.tsx +++ b/website/src/components/modal.tsx @@ -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"; @@ -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([]) const [postImages, setPostImages] = useState([]) @@ -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) - - } @@ -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){ @@ -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] @@ -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") } @@ -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") @@ -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 @@ -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) @@ -472,30 +488,52 @@ export function ImagePopup({show, hideCallback, id = 0, setImages, startImages}: {/* Side panel */}
- {currentImageName}/ - + {currentImageName}/

{currentImageName}

-

Description

+ + { activeTab !== 3 ? +

{currentImageDescription}

+ : + + } +
-
-

{currentImage}

- { activeTab !== 3 && +
+ { activeTab !== 3 ? <> +

{currentImage}

{currentImagePlant}

{currentImageDate}

+ : + <> +
+ setCurrentImageMine(!currentImageMine)}/> + +
+ { + !currentImageMine && + + } + }
{activeTab == 3 ? - <> - @@ -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("") }} />
@@ -534,8 +574,9 @@ export function ImagePopup({show, hideCallback, id = 0, setImages, startImages}: {/* Upload Image Only Button */} {!isDragging && - } + + } : diff --git a/website/src/components/plant_card.tsx b/website/src/components/plant_card.tsx index fae72d3..a07bf94 100644 --- a/website/src/components/plant_card.tsx +++ b/website/src/components/plant_card.tsx @@ -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 = { @@ -22,10 +25,13 @@ 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(() => { @@ -33,44 +39,10 @@ export default function PlantCardData({ data}: PlantCardProps){ // 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) => { @@ -99,7 +71,7 @@ export default function PlantCardData({ data}: PlantCardProps){ {/* Image of the plant, grabbed from the image attachments of the pant data*/}
- +
diff --git a/website/src/lib/api_tools.ts b/website/src/lib/api_tools.ts index 234256d..c5c627b 100644 --- a/website/src/lib/api_tools.ts +++ b/website/src/lib/api_tools.ts @@ -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){ @@ -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){ diff --git a/website/src/lib/databse.ts b/website/src/lib/databse.ts index 0f43829..5f9add0 100644 --- a/website/src/lib/databse.ts +++ b/website/src/lib/databse.ts @@ -99,6 +99,7 @@ export class SQLDatabase { post_image: string; post_approved: string; post_in_use: string; + post_description: string; // Likes Table like_post_id: string; @@ -207,6 +208,7 @@ export class SQLDatabase { this.post_image = "post_image"; this.post_approved = "post_approved"; this.post_in_use = "post_in_use"; + this.post_description = "post_description"; // Likes Table this.like_post_id = "like_post_id"; diff --git a/website/src/lib/plant_data.ts b/website/src/lib/plant_data.ts index 4d5795f..6b492a0 100644 --- a/website/src/lib/plant_data.ts +++ b/website/src/lib/plant_data.ts @@ -194,6 +194,7 @@ export type PostData = { post_image: string; post_approved: boolean; post_in_use: boolean; + post_description: string; } /** diff --git a/website/src/pages/api/plants/search.ts b/website/src/pages/api/plants/search.ts index 9991dcc..704842c 100644 --- a/website/src/pages/api/plants/search.ts +++ b/website/src/pages/api/plants/search.ts @@ -22,6 +22,10 @@ export default async function handler( const permission = await checkApiPermissions(request, response, session, client, makeQuery, "api:plants:search:access") if(!permission) return response.status(401).json({error: "Not Authorized"}) + let userIds = [] as any + let postIds = [] as any + let plantIds = [] as any + // Get the ID and table from the query string let { amount, @@ -30,6 +34,7 @@ export default async function handler( mushrooms, page, getExtras, + getPlants, getUsers, getPosts, getUnpublished @@ -41,98 +46,105 @@ export default async function handler( const tables = getTables() const amountPerPage = 3 - // Assemble the query let query = ``; - let selector = "WHERE" + if(getPlants !== "false") { - // If the user specified a name, get the plant id from the plants database - let shouldGetNames = ``; - if (getNames) { - shouldGetNames = `, english_name, maori_name, latin_name, preferred_name`; - } + // Assemble the query - // If the user specified to get extra - let shouldGetExtras = ``; - if (getExtras) { - shouldGetExtras = `, ${tables.plant_type}, ${tables.last_modified}`; - } + let selector = "WHERE" - // Get the plant id from the plants database - query += ` SELECT id ${shouldGetNames} ${shouldGetExtras} FROM plants`; + // If the user specified a name, get the plant id from the plants database + let shouldGetNames = ``; + if (getNames) { + shouldGetNames = `, english_name, maori_name, latin_name, preferred_name`; + } - // Select what the user entered - if (name) { + // If the user specified to get extra + let shouldGetExtras = ``; + if (getExtras) { + shouldGetExtras = `, ${tables.plant_type}, ${tables.last_modified}`; + } + // Get the plant id from the plants database + query += ` SELECT id ${shouldGetNames} ${shouldGetExtras} FROM plants`; - //TODO: Find a better way to include these characters - let replaceChars = ["ā", "ē", "ī", "ō", "ū", "Ā", "Ē", "Ī", "Ō", "Ū", "a", "e", "i", "o", "u", "A", "E", "I", "O", "U"] - // Replace macrons with wildcard - for (let i = 0; i < replaceChars.length; i++) { - name = (name as string).replaceAll(replaceChars[i], `_`) - } + // Select what the user entered + if (name) { - query += ` ${selector} (english_name LIKE '%${name}%' OR maori_name LIKE '%${name}%' OR latin_name LIKE '%${name}%')`; - selector = "AND"; - } + //TODO: Find a better way to include these characters + let replaceChars = ["ā", "ē", "ī", "ō", "ū", "Ā", "Ē", "Ī", "Ō", "Ū", "a", "e", "i", "o", "u", "A", "E", "I", "O", "U"] - // Check wether to get non-published plants - if (!getUnpublished) { - query += ` ${selector} ${tables.published} = 1`; - selector = "AND"; - } + // Replace macrons with wildcard + for (let i = 0; i < replaceChars.length; i++) { + name = (name as string).replaceAll(replaceChars[i], `_`) + } - // Filter mushrooms - if (!mushrooms){ - mushrooms = "exclude" - } - switch (mushrooms) { - case "include": - break; + query += ` ${selector} (english_name LIKE '%${name}%' OR maori_name LIKE '%${name}%' OR latin_name LIKE '%${name}%')`; + selector = "AND"; + } + + // Check wether to get non-published plants + if (!getUnpublished) { + query += ` ${selector} ${tables.published} = 1`; + selector = "AND"; + } + + // Filter mushrooms + if (!mushrooms){ + mushrooms = "exclude" + } - case "exclude": - query += ` ${selector} ${tables.plant_type} NOT LIKE '%Mushroom%'`; - break; + switch (mushrooms) { + case "include": + break; - case "only": - query += ` ${selector} ${tables.plant_type} LIKE '%Mushroom%'`; - break; + case "exclude": + query += ` ${selector} ${tables.plant_type} NOT LIKE '%Mushroom%'`; + break; - default: - query += ` ${selector} ${tables.plant_type} NOT LIKE '%Mushroom%'`; - break; + case "only": + query += ` ${selector} ${tables.plant_type} LIKE '%Mushroom%'`; + break; + + default: + query += ` ${selector} ${tables.plant_type} NOT LIKE '%Mushroom%'`; + break; + } + + // Only get a certain amount + if (amount) { + query += ` LIMIT ${amount}` } - // Only get a certain amount - if (amount) { - query += ` LIMIT ${amount}` - } + // If the user specified a page, get the correct page + if (page) { - // If the user specified a page, get the correct page - if (page) { + let currentPage = parseInt(page as string) - let currentPage = parseInt(page as string) + query += ` LIMIT ${amountPerPage} OFFSET ${(currentPage - 1) * amountPerPage}` + } - query += ` LIMIT ${amountPerPage} OFFSET ${(currentPage - 1) * amountPerPage}` - } + // Return the plants that match the query + plantIds = await makeQuery(query, client) - // Return the plants that match the query - const plantIds = await makeQuery(query, client) - let userIds = [] as any - let postIds = [] as any - // If there are no plants, return an error - if (!plantIds) { - return response.status(404).json({ error: 'No plants found' }); + // If there are no plants, return an error + if (!plantIds) { + return response.status(404).json({ error: 'No plants found' }); + } } if(getUsers){ - query = `SELECT id FROM users WHERE ${tables.user_name} LIKE '%${name}%'` + + query = `SELECT id ${getNames ? `,${tables.user_name}` : ""} FROM users ${name ? `WHERE ${tables.user_name} LIKE '%${name}%'` : ""}` + console.log("Query: " + query) const users = await makeQuery(query, client) + console.log("Users: " + users) // If there are no users, return an error if (!users) { @@ -167,6 +179,7 @@ export default async function handler( } + // Return the plant ids // TODO: deprecate the data part return response.status(200).json( { data: plantIds, plants: plantIds, users: userIds, posts: postIds}); diff --git a/website/src/pages/api/posts/new.ts b/website/src/pages/api/posts/new.ts index cd29f9f..48f43b2 100644 --- a/website/src/pages/api/posts/new.ts +++ b/website/src/pages/api/posts/new.ts @@ -45,6 +45,7 @@ export default async function handler( plant, image, inUse, + description } = request.query; let post_in_use = false; @@ -55,8 +56,13 @@ export default async function handler( const timeFunction = USE_POSTGRES ? "to_timestamp" : "FROM_UNIXTIME"; + // Check if missing data + if (!title || !plant || !image || !description) { + return response.status(400).json({ error: "Missing data" }); + } + // Run the query - const query = `INSERT INTO posts (${tables.post_title}, ${tables.post_plant_id}, ${tables.post_user_id}, ${tables.post_image}, ${tables.post_date}, ${tables.post_approved}, ${tables.post_in_use}) VALUES ('${title}', ${plant}, ${user_id}, '${image}', ${timeFunction}(${Date.now()} / 1000.0), ${!user_is_member}, ${post_in_use} ) ${process.env.USING_MYSQL == "true" ? '' : 'RETURNING id;'}`; + const query = `INSERT INTO posts (${tables.post_title}, ${tables.post_plant_id}, ${tables.post_user_id}, ${tables.post_image}, ${tables.post_date}, ${tables.post_approved}, ${tables.post_in_use}, ${tables.post_description}) VALUES ('${title}', ${plant}, ${user_id}, '${image}', ${timeFunction}(${Date.now()} / 1000.0), ${!user_is_member}, ${post_in_use}, '${description}' ) ${process.env.USING_MYSQL == "true" ? '' : 'RETURNING id;'}`; const data = await makeQuery(query, client, true); let id; diff --git a/website/src/pages/index.tsx b/website/src/pages/index.tsx index 00b3efd..eeda714 100644 --- a/website/src/pages/index.tsx +++ b/website/src/pages/index.tsx @@ -26,13 +26,17 @@ import PostFeed from "@/components/postfeed"; // = = Live Chats // = = Better Plan Search // = = Link To Rongoa -// - - Image Description +// = = Image Description +// = = Upload set user // - - Edit Image Info In Pop Up -// - - Show Posts in user account -// - - Publish on stores +// - - Image Page +// - - Storing inuse images in plant folder +// = = Show Posts in user account +// - - Publish on stores (API REFACTOR TO ALLOW FOR THIS) // - Database // - - Use better wrapper // - - Remove postgres +// - - Ids on backend values on api end // - Plant Updates // - - New Creation Mode // - - Publishing diff --git a/website/src/pages/media/components/cards.tsx b/website/src/pages/media/components/cards.tsx index 610daa5..4502689 100644 --- a/website/src/pages/media/components/cards.tsx +++ b/website/src/pages/media/components/cards.tsx @@ -283,6 +283,9 @@ export function UserCard(props: UserCardProps) { const dataFetch = useRef(props.id); useEffect(() => { + + if(props.id == 0) return; + if(props.id == dataFetch.current) return; dataFetch.current = props.id; fetchData(); diff --git a/website/src/pages/media/new.tsx b/website/src/pages/media/new.tsx index 2d2c505..b1b3fe5 100644 --- a/website/src/pages/media/new.tsx +++ b/website/src/pages/media/new.tsx @@ -4,12 +4,12 @@ import React, {useEffect, useRef, useState} from "react"; import { DropdownInput, FilteredSearchInput, - PlantSelector, + PlantSelector, SimpleTextArea, SmallInput, ValidationState } from "@/components/input_sections"; import {makeCachedRequest, makeRequestWithToken} from "@/lib/api_tools"; -import {getNamesInPreference, macronCodeToChar, numberDictionary} from "@/lib/plant_data"; +import {getNamesInPreference, macronCodeToChar, numberDictionary, PostData} from "@/lib/plant_data"; import {Loading} from "@/components/loading"; import {useSession} from "next-auth/react"; import {RongoaUser} from "@/lib/users"; @@ -25,6 +25,10 @@ export default function Post(){ const [postValidation, setPostValidation] = useState("normal") const [postError, setPostError] = useState("") + const [postDescription, setPostDescription] = useState(''); + const [descriptionValidation, setDescriptionValidation] = useState("normal") + const [descriptionError, setDescriptionError] = useState("") + const [plant, setPlant] = useState(''); const [currentPlant, setCurrentPlant] = useState(0); @@ -94,13 +98,20 @@ export default function Post(){ return } + // Check if there is a description + if(postDescription == "" || postDescription == undefined || postDescription.length < 10){ + setDescriptionValidation("error") + setDescriptionError("Please enter a description") + return + } + const user = session?.user as RongoaUser if(user == null) return const userID = user.database.id const userName = user.database.user_name // Upload the image - await postImage(image, postTitle, currentPlant, userID, userName, setLoading) + await postImage(image, postTitle, postDescription, currentPlant, userID, userName, setLoading) setLoading("") // Redirect to the post @@ -154,6 +165,16 @@ export default function Post(){ changeEventHandler={setPostTitle}/>
+
+ +
+
void, inUse ?: boolean ) => { +export const postImage = async (image: File, postTitle: string, postDescription: string, currentPlant: number, userID: number, userName: string, setLoadingMessage: (message: string) => void, inUse ?: boolean ) => { setLoadingMessage("Compressing Image...") const options = { @@ -204,7 +225,7 @@ export const postImage = async (image: File, postTitle: string, currentPlant: nu const plant_image = cleanInput(compressedImage.name) // Send the post data to the server - const response = await makeRequestWithToken('post', '/api/posts/new?title=' + post_title + '&plant=' + post_plant_id + '&image=' + plant_image + '&inUse=' + inUse); + const response = await makeRequestWithToken('post', '/api/posts/new?title=' + post_title + '&plant=' + post_plant_id + '&image=' + plant_image + '&inUse=' + inUse + '&description=' + postDescription); // Get the post id const newId = response.data.id @@ -257,7 +278,8 @@ export const postImage = async (image: File, postTitle: string, currentPlant: nu post_date: Date.now(), post_approved: true, post_in_use: inUse, - id: newId + id: newId, + post_description: postDescription } return newpost } \ No newline at end of file diff --git a/website/src/pages/plants/[id].tsx b/website/src/pages/plants/[id].tsx index b0be9ae..d94bf4f 100644 --- a/website/src/pages/plants/[id].tsx +++ b/website/src/pages/plants/[id].tsx @@ -26,7 +26,12 @@ export default function PlantPage() { // Store the plant data const [plantData, setPlantData] = React.useState(null) const [plantNames, setPlantNames] = React.useState(["Loading...", "Loading...", "Loading..."]) - const [images, setImages] = React.useState<{url: string, name: string, credits: string, description: string}[]>([]) + const [images, setImages] = React.useState<{url: string, name: string, credits: string, description: string}[]>([{ + url: "/media/images/default_noImage.png", + name: "No Image", + credits: "", + description: "" + }]) const [showMainImage, setShowMainImage] = React.useState(false) @@ -152,9 +157,8 @@ export default function PlantPage() { if(!plantData) return; - const hasImage = plantData.display_images.length > 0 - const images = hasImage ? - plantData.display_images.map((image: any) => { + if(!(plantData.display_images.length > 0)) return; + const images = plantData.display_images.map((image: any) => { return { url: getPostImage(image), name: image.post_title, @@ -162,12 +166,7 @@ export default function PlantPage() { description: image.post_title } }) - : [{ - url: "/media/images/default_noImage.png", - name: "No Image", - credits: "", - description: "" - }] + setImages(images) }, [plantData]); diff --git a/website/src/pages/plants/create.tsx b/website/src/pages/plants/create.tsx index 7c31d0d..005fb28 100644 --- a/website/src/pages/plants/create.tsx +++ b/website/src/pages/plants/create.tsx @@ -36,7 +36,7 @@ import {FontAwesomeIcon} from "@fortawesome/react-fontawesome"; import {faCloudArrowUp, faFile} from "@fortawesome/free-solid-svg-icons"; import {globalStyles} from "@/lib/global_css"; import {RongoaUser} from "@/lib/users"; -import {createToken, makeRequestWithToken} from "@/lib/api_tools"; +import {createToken, makeCachedRequest, makeRequestWithToken} from "@/lib/api_tools"; import axios from "axios"; import {Layout} from "@/components/layout"; import {cleanInput, getPostImage} from "@/lib/data"; diff --git a/website/src/styles/components/modal.module.css b/website/src/styles/components/modal.module.css index 56145e2..62c562c 100644 --- a/website/src/styles/components/modal.module.css +++ b/website/src/styles/components/modal.module.css @@ -252,4 +252,17 @@ align-items: center; opacity: 1 !important; box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.3); +} + +.myImage{ + margin-left: -2%; + margin-top: 3%; + display: grid; + grid-template-columns: 0.1fr 0.9fr; + margin-bottom: 20px; +} + +.myImage label{ + margin-left: 10px; + cursor: pointer; } \ No newline at end of file