Skip to content

Commit

Permalink
feature/add CRUD functions for admin merch panel
Browse files Browse the repository at this point in the history
  • Loading branch information
bit-Matt committed Jan 1, 2024
1 parent 5306858 commit a9f113a
Show file tree
Hide file tree
Showing 7 changed files with 3,094 additions and 156 deletions.
94 changes: 94 additions & 0 deletions client/components/EditMerch.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import React, { Fragment, useState } from "react";
import { getErrorMessage } from "@/utils/utilFunctions";
import {Modal, ModalContent, ModalHeader, ModalBody, ModalFooter, Button, useDisclosure} from "@nextui-org/react";


const EditMerch = ({ merch }: any) => {

const [name, setName] = useState<string>(merch.name);
const [description, setDescription] = useState<string>(merch.description);
const [image, setImage] = useState<File | null>(merch.image);
const [price, setPrice] = useState<number>(merch.price);

//edit description function
const updateDescription = async (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
e.preventDefault(); // allows to run code before refreshing
try {
const body = { description };
const response = await fetch(
`http://localhost:3001/admin/admin-merch/${merch.id}`,
{
method: "PUT",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body)
}
);

window.location.href = "/admin/admin-merch";
} catch (err) {
console.error(getErrorMessage(err));
}
}

return (
<Fragment>
<button type="button" className="h-10 w-20 bg-yellow-400 border rounded-md hover:bg-blue-800" data-toggle="modal" data-target={`#id${merch.id}`}>
Edit
</button>

<div
className="modal"
id={`id${merch.id}`}
onClick={() => setDescription(merch.description)}
>
<div className="modal-dialog">
<div className="modal-content">

<div className="modal-header">
<h4 className="modal-title">Edit Merch</h4>
<button
type="button"
className="close"
data-dismiss="modal"
onClick={() => setDescription(merch.description)}
>
&times;
</button>
</div>

<div className="modal-body">
<input
type="text"
className="form-control"
value={description}
onChange={e => setDescription(e.target.value)}
/>
</div>

<div className="modal-footer">
<button
type="button"
className="btn btn-warning"
data-dismiss="modal"
onClick={e => updateDescription(e)}
>
Edit
</button>
<button
type="button"
className="btn btn-danger"
data-dismiss="modal"
onClick={() => setDescription(merch.description)}
>
Close
</button>
</div>

</div>
</div>
</div>
</Fragment>
);
};

export default EditMerch;
95 changes: 95 additions & 0 deletions client/components/InputMerch.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import React, { Fragment, useState, ChangeEvent } from "react";
import { getErrorMessage } from "../utils/utilFunctions";


const InputMerch = () => {
const [name, setName] = useState("");
const [description, setDescription] = useState("");
const [image, setImage] = useState<File | null>(null);
const [price, setPrice] = useState<number | string>("");

const onSubmitForm = async (event: { preventDefault: () => void; }) => {
event.preventDefault();
try {
const body = { name, description, image, price };
const response = await fetch("http://localhost:3001/admin/admin-merch", {
method: "POST",
headers: { "Content-type": "application/json" },
body: JSON.stringify(body)
});

window.location.href = "/admin/admin-merch";
} catch (err) {
console.error(getErrorMessage(err));
}
}

const handleImageChange = (e: ChangeEvent<HTMLInputElement>) => {
const file = e.target.files?.[0];
setImage(file || null);
};

return (
<Fragment>
<h1 className="text-center mt-5">PERN Merch List</h1>
<form className="d-flex mt-5" onSubmit={ onSubmitForm }>
<div className="my-6">
<h1 className="text-black text-3xl underline underline-offset-4">
Create GDSC merch
</h1>
</div>
<div className="flex flex-col space-y-8">
<div>
<p className="text-black text-lg font-semibold mb-1">Merch Name</p>
<input
type="text"
className="text-black h-8 w-64 border border-stone-900"
placeholder="Name"
value={name}
onChange={event => setName(event.target.value)}
/>
</div>
<div>
<p className="text-black text-lg font-semibold mb-1">
Merch Description
</p>
<textarea
typeof="text"
className="text-black h-24 w-1/2 border border-stone-900"
placeholder="Description"
value={description}
onChange={event => setDescription(event.target.value)}
/>
</div>
<div>
<p className="text-black text-lg font-semibold mb-1">Merch Photo</p>
<input
type="file"
className="text-black"
accept="image/png, image/jpeg"
// onChange={handleImageChange}
/>
{/* {image && <img src={URL.createObjectURL(image)} alt="Uploaded" />} */}
</div>
<div>
<p className="text-black text-lg font-semibold mb-1">Merch Price</p>
<input
type="number"
className="text-black h-8 w-64 border border-stone-900"
placeholder="Price"
value={price}
onChange={event => setPrice(Number(event.target.value))}
/>
</div>
<div>
<button className="h-10 w-40 bg-blue-600 border rounded-md hover:bg-blue-800">
Add Merch
</button>
</div>
</div>
</form>
</Fragment>
);
};

export default InputMerch;
88 changes: 88 additions & 0 deletions client/components/ListMerch.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import React, { Fragment, useEffect, useState } from "react";
import { getErrorMessage } from "../utils/utilFunctions";
import EditMerch from "./EditMerch";

type Merch = {
id: number;
name: string;
description: string;
image: File | null;
price: number;
};

const ListMerch = () => {
const [merches, setMerches] = useState<Merch[]>([]);

//delete merch function
const deleteMerch = async (id: number) => {
try {
const deleteMerch = await fetch(`http://localhost:3001/admin/admin-merch/${id}`, {
method: "DELETE"
});

setMerches(merches.filter(merch => merch.id !== id));
} catch (err) {
console.error(getErrorMessage(err));
}
}

//get merch function
const getMerches = async () => {
try {
const response = await fetch("http://localhost:3001/admin/admin-merch");
const jsonData = await response.json();

setMerches(jsonData);
} catch (err) {
console.error(getErrorMessage(err));
}
}

useEffect(() => {
getMerches();
}, [] /* bracket ensures useEffect does not repeatedly request multiple times */);

return (
<Fragment>
<table className="table-auto mt-12 text-center text-black">
<thead>
<tr>
<th className="px-4 py-2">Description</th>
<th className="px-4 py-2">Edit</th>
<th className="px-4 py-2">Delete</th>
</tr>
</thead>
<tbody>
{/*
<tr>
<td>John</td>
<td>Doe</td>
<td>[email protected]</td>
</tr>
*/}
{merches.map(merch => (
<tr key={merch.id}>
<td className="border px-4 py-2">{merch.name}</td>
<td className="border px-4 py-2">{merch.description}</td>
{/* <td className="border px-4 py-2">{merch.image}</td> */}
<td className="border px-4 py-2">P {merch.price}</td>
<td>
<EditMerch merch={merch} />
</td>
<td>
<button
className="h-10 w-20 bg-red-600 border rounded-md hover:bg-blue-800"
onClick={() => deleteMerch(merch.id)}
>
Delete
</button>
</td>
</tr>
))}
</tbody>
</table>
</Fragment>
);
};

export default ListMerch;
Loading

0 comments on commit a9f113a

Please sign in to comment.