Dec 10, 2023
0
Level 8
Can you help improve my code ReactJS
Basically, All variables should be set in the top page and passed down, making table completely reusable for any data. Things I need to take into account:
- What is present on the modal and what is present on the table should be different since the user may not want to view specific data on the table but would be required to have an input for that data on the modal.
- The variables should be much neater. Cannot think on how I should do it. I should have some type of structure to be passed through but I cannot think for the life of me.
Please help in pointing out anything that you would consider a problem.
import React, { useEffect } from 'react';
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout';
import { Head } from '@inertiajs/react';
import Table from '@/Components/Table';
export default function User({ auth, objects }) {
// const objects = ['name', 'email', 'password'];
const excludes = ['id', 'email_verified_at', 'created_at', 'updated_at'];
const includes = [''];
const bold = ['name'];
const url = "/admin/users";
const type = ['text', 'email', 'password'];
const maxLength = ['30', '30', '20'];
const minLength = ['1', '1', '8'];
const attribute = ['required', 'required', 'required'];
const css = ['font-bold', '', ''];
useEffect(() => {
});
return (
<AuthenticatedLayout
user={auth.user}
header={<h2 className="font-semibold text-xl text-gray-800 leading-tight ml-6">Dashboard</h2>}
>
<Head title="Dashboard" />
<Table
objects={objects}
excludes={excludes}
includes={includes}
bold={bold}
url={url}
type={type}
maxLength={maxLength}
minLength={minLength}
attribute={attribute}
css={css}
/>
</AuthenticatedLayout>
)
}
import React, { useState, useEffect } from 'react';
import { Link } from '@inertiajs/react';
import ModalCreate from '@/Components/ModalCreate';
import ModalUpdate from '@/Components/ModalUpdate';
import ModalDelete from '@/Components/ModalDelete';
import { FaArrowAltCircleRight } from "react-icons/fa";
export default function Table({
objects,
excludes,
includes,
bold,
url,
type,
maxLength,
minLength,
attribute,
css
}) {
// Modal data
const [showCreate, setShowCreate] = useState(false);
const [showUpdate, setShowUpdate] = useState(false);
// Other
const keys = Object.keys(objects[0] || {});
const [toggle, setToggle] = useState(
localStorage.getItem('toggleTable') === 'true' || false
);
useEffect(() => {
localStorage.setItem('toggleTable', toggle);
}, [toggle]);
return (
<div>
<ModalCreate
show={showCreate}
setShow={setShowCreate}
url={url}
keys={keys}
excludes={excludes}
includes={includes}
type={type}
maxLength={maxLength}
minLength={minLength}
attribute={attribute}
css={css}
/>
<div className="py-12">
<div className="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div className="bg-white overflow-hidden shadow-sm sm:rounded-lg">
<div className="flex items-center justify-between p-6 w-full">
<div className="flex">
<img
src="/images/icons/icons8-iphone-se-100.png"
onClick={() => setToggle(true)}
className="hover:scale-110 duration-300 w-10 h-10 md:h-20 md:w-20"
/>
<img
src="/images/icons/icons8-desktop-100.png"
onClick={() => setToggle(false)}
className="hover:scale-110 duration-300 w-10 h-10 md:h-20 md:w-20"
/>
</div>
<div className="flex">
<img
src="/images/icons/icons8-create-100.png"
onClick={() => setShowCreate(true)}
className="hover:scale-110 duration-300 w-10 h-10 md:h-20 md:w-20"
/>
<img
src="/images/icons/icons8-settings-100.png"
className="hover:scale-110 duration-300 w-10 h-10 md:h-20 md:w-20 ml-auto"
/>
<img
src="/images/icons/icons8-back-100.png"
onClick={() => window.history.go(-1)}
className="hover:scale-110 duration-300 w-10 h-10 md:h-20 md:w-20 ml-auto"
/>
</div>
</div>
<div className="p-6">
{toggle ?
<div className="grid md:grid-cols-2 gap-4">
{objects.map((obj, index) => (
<Link href={`/admin/users/${obj.id}`}>
<div key={index} className="p-4 border rounded-lg hover:shadow-md transition-shadow duration-300">
<div className="flex flex-row">
<div>
{Object.keys(obj).map(key => (
// Check if the key is in the excludes array
excludes.includes(key) ? null : (
<div key={key}>
{
bold.includes(key) ?
<p><strong>{obj[key]}</strong></p>
:
<p>{obj[key]}</p>
}
</div>
)
))}
</div>
<div className="ml-auto flex items-center justify-center">
<FaArrowAltCircleRight />
</div>
</div>
<hr className="my-2" />
<div className="flex items-center justify-left">
<img src="/images/icons/icons8-edit-100.png" className="hover:scale-110 duration-300 w-12 h-12" />
<img src="/images/icons/icons8-delete-100.png" className="hover:scale-110 duration-300 w-12 h-12" />
</div>
</div>
</Link>
))}
</div>
:
<table className="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
<thead>
<tr>
{keys.map(key => (
// Check if the key is NOT in the excludes array
excludes.includes(key) ? null : (
<td key={key} className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">
<strong>{key}</strong>
</td>
)
))}
<td className="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase">actions</td>
</tr>
</thead>
<tbody className="divide-y divide-gray-200 dark:divide-gray-700">
{objects.map((obj, index) => (
<tr key={index}>
{Object.keys(obj).map(key => (
// Check if the key is NOT in the excludes array
excludes.includes(key) ? null : (
<td key={key} className="px-6 py-4 whitespace-nowrap text-sm text-gray-800 dark:text-gray-200">
{
bold.includes(key) ?
<strong><Link href={`/admin/users/${obj.id}`}>{obj[key]}</Link></strong>
:
<Link href={`/admin/users/${obj.id}`}>{obj[key]}</Link>
}
</td>
)
))}
<td className="flex items-center justify-end">
<img src="/images/icons/icons8-edit-100.png" className="hover:scale-110 duration-300 w-12 h-12" />
<img src="/images/icons/icons8-delete-100.png" className="hover:scale-110 duration-300 w-12 h-12" />
</td>
</tr>
))}
</tbody>
</table>
}
</div>
<hr />
<div className="font-serif flex justify-end items-center p-6 text-sm">
Table v1 by Joshua Heathcote
</div>
</div>
</div>
</div>
</div>
)
}
import React, { useState } from 'react'
import { router } from '@inertiajs/react'
import Modal from '@/Components/Modal';
import PrimaryButton from '@/Components/PrimaryButton';
import SecondaryButton from '@/Components/SecondaryButton';
import { IoIosCloseCircleOutline } from "react-icons/io";
export default function Create({
show,
setShow,
url,
keys,
excludes,
includes,
type,
maxLength,
minLength,
attribute,
css
}) {
const mergedKeys = [...keys, ...includes];
const deducted = mergedKeys.filter(key => !excludes.includes(key));
const initialValues = deducted.map((key, index) => {
return {
[key]: ''
};
});
const initialObject = Object.assign({}, ...initialValues);
const [values, setValues] = useState(initialObject);
function handleChange(e) {
const key = e.target.id;
const value = e.target.value
setValues(values => ({
...values,
[key]: value,
}))
}
function validationCheck() {
// You have check through the values against the validations
}
function handleSubmit(e) {
e.preventDefault();
router.post(url, values, { preserveScroll: true });
setShow(false);
}
const localCss = 'peer p-4 my-4 block w-full border-gray-200 rounded-lg text-sm placeholder:text-transparent focus:border-blue-500 focus:ring-blue-500 disabled:opacity-50 disabled:pointer-events-none dark:bg-slate-900 dark:border-gray-700 dark:text-gray-400 dark:focus:ring-gray-600';
return (
<Modal show={show}>
<form onSubmit={handleSubmit}>
<div>
<div className="flex items-center justify-between p-6 w-full">
<div className="flex">
<div className="text-2xl">Create</div>
</div>
<div className="flex">
<IoIosCloseCircleOutline onClick={() => setShow(false)} className="text-2xl" />
</div>
</div>
<hr />
<div className="p-6">
{deducted.map((key, index) => (
<div key={key}>
{
key == '' ?
null
:
<div key={index}>
<div className="uppercase text-sm text-gray-800" htmlFor={key}>{key}</div>
<input
value={values.key}
onChange={handleChange}
className={`${localCss} ${css[index]}`}
type={type[index]}
id={key}
name={key}
maxLength={maxLength[index]}
minLength={minLength[index]}
required />
</div>
}
</div>
))}
</div>
<hr />
<div className="p-6">
<div className="flex gap-4 justify-end items-center">
<SecondaryButton onClick={() => setShow(false)}>Close</SecondaryButton>
<PrimaryButton>Create</PrimaryButton>
</div>
</div>
</div>
</form>
</Modal>
)
}
Please or to participate in this conversation.