How to paginate in react using inertia on laravel? - javascript

How to paginate in react using inertia on laravel?
pulling the paginated data:
$contacts = Contact::orderBy('name', 'asc')->paginate(10);
return Inertia::render('Contacts/index', [
'contacts' => $contacts
]);
I know how to render the links in blade ({{ $contacts->links() }}) but is there a way to do it like that on inertia or do I need to make my own component for pagination links?

The easiest way is to create your own component with the links (those are still there)
This is an example in vue, but should be easy to port to react:
<template>
<div>
<div class="flex flex-wrap -mb-1">
<template v-for="(link, key) in links" :key="key">
<div v-if="link.url === null" class="mr-1 mb-1 px-4 py-3 text-sm leading-4 text-gray-400 border rounded"
v-html="link.label" />
<inertia-link v-else
class="mr-1 mb-1 px-4 py-3 text-sm leading-4 border rounded hover:bg-white focus:border-indigo-500 focus:text-indigo-500"
:class="{ 'bg-blue-700 text-white': link.active }" :href="link.url" v-html="link.label" />
</template>
</div>
</div>
</template>
<script>
export default {
props: {
links: Array
},
}
</script>

You can Try This for better result for react :-
import DataTable from "react-data-table-component";
<DataTable
style={{ background: "transparent" }}
title="User"
columns={columns}
data={allData}
defaultSortFieldId={1}
sortIcon={<ArrowUpwardIcon />}
pagination
/>

Related

How to map an array inside JSON object using typescript?

I'm trying to get an array from a JSON object and then, map it in order to get the data.
Here is the data returned from an API:
{
project: [
{
_createdAt: '2022-12-15T16:45:57Z',
_id: 'cb39338d-4e6d-4c28-9a79-499afca392e6',
_rev: '974wCYB6EQ3xW9LGNZhQvU',
_type: 'project',
_updatedAt: '2022-12-27T04:55:54Z',
image: [Object],
linkToBuild: 'https://github.com/Arotiana137-51/charitty_to_portfolio_jsp',
summary: "This is a project I've done for learning purpose at the University. I've learned the basics of web programing with Java Server Pages ,Servelet ,....", technologies: [Array],
title: 'Charity '
}
]
}
And I wish to map this array in order to get elements from it inside this JSX element :
import React from "react";
import {motion} from 'framer-motion';
import { Project } from "../typing";
import { urlFor } from "../sanity";
type Props = {
projects:Project[];
};
function Projects({projects}: Props) {
console.log(projects);
return (
<motion.div
initial={{opacity:0}}
whileInView={{opacity:1}}
transition={{duration:1.5}}
className="h-screen relative flex overflow-hidden flex-col text-left md:flex-row max-w-full justify-evenly mx-auto items-center z-0">
<h3 className="absolute top-24 uppercase tracking-widest text-teal-400 text-2xl ">
Projects
</h3>
<div className="relative w-full flex overflow-x-scroll overflow-y-hidden snap-x snap-mandatory z-20">
{/*----------- HERE I TRY TO ACCESS THE ARRAY AND MAP IT DIRECTLY, LIKE IN JS-----------------------------------*/}
{ projects.project.map((project,i) => (
<div className="w-screen flex-shrink-0 snap-center flex flex-col space-y-5 items-center justify-center p-20 md:p-44 h-screen">
<motion.img
initial ={{
y: -300,
opacity:0
}}
transition={{duration: 1.2}}
whileInView = {{opacity:1 , y:0 }}
viewport={{ once: true}}
src={urlFor(project.image).url()}
alt="#"/>
<div className=" space-y-10 px-0 md:px-10 max-w-6xl ">
<h4 className="text-4xl font-semibold text-center">
Case study {i+1} of{projects.length}: <span className="underline decoration-teal-700"> {project?.title}</span>
</h4>
<div className="flex items-center space-x-2 justify-center">
{
project?.technologies.map((technology)=>(
<img
className="h-10 w-10"
key={technology._id}
src={urlFor(technology?.image).url()}
alt=""
/>
))
}
</div>
<p>{project?.summary}</p>
</div>
</div>
))}
</div>
<div className="w-full absolute top-[30%] bg-teal-800 left-0 h-[500px] -skew-y-12">
</div>
</motion.div>
);
}
export default Projects;
This normally works on js but my compiler return:
Server Error
TypeError: Cannot read properties of undefined (reading 'map')
because it still considers the prop as an object, even if I try to access the array at the code above, how can i solve it?
You are trying to do project?.technologies.map, but as i see at the JSON above , there is simply no "technologies" key.

React web app : Mapping <Popover.Button> and <Popover.Panel> separately

I want to render this popover panel
<Popover.Panel className="absolute z-10 inset-x-0 transform shadow-xl pb-2 w-max">
<div>
<Dropdown subCategory={mainCatArray}/>
</div>
</Popover.Panel>
same as this popover button render in this below code. Because I want to render a separate popover panel with the popover button, please help me to do that. (I cannot render in one categoryObj because I want to render this popover button horizontally, but if I use a single map for the entire popover component popover button renders it vertically.
(Simply What I want to do is I want to render one <Popover.Panel> to one <Popover.Button>)
import { Fragment, useEffect, useState } from "react";
import { Popover, Transition } from "#headlessui/react";
import Dropdown from "./dropdown";
import { categoryObj } from "../../components/item/categoriesobj";
function classNames(...classes) {
return classes.filter(Boolean).join(" ");
}
const CatDropDown = () => {
const [mainCatArray, setMainCatArray] = useState([]);
return (
<>
<Popover className="z-0 relative">
{({ open }) => (
<>
<div>
<div className=" z-10 bg-white">
<div className="w-2/3 flex gap-5 px-4 py-6 sm:px-6 lg:px-8 ">
{categoryObj.map((singleMainCategory) => (
<Popover.Button
className={classNames(
open ? "text-gray-900" : "text-gray-900",
"group bg-white rounded-md inline-flex items-center text-sm font-susty focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-white"
)}
>
<span
key={singleMainCategory.id}
onClick={() => {
setMainCatArray(singleMainCategory.subCategory);
}}
>
<span>{singleMainCategory.name}</span>
</span>
</Popover.Button>
))}
</div>
</div>
</div>
<Transition
as={Fragment}
enter="transition ease-out duration-200"
enterFrom="opacity-0 -translate-y-1"
enterTo="opacity-100 translate-y-0"
leave="transition ease-in duration-150"
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 -translate-y-1"
>
<Popover.Panel className="absolute z-10 inset-x-0 transform shadow-lg pb-2">
<div>
<Dropdown subCategory={mainCatArray}/>
</div>
</Popover.Panel>
</Transition>
</>
)}
</Popover>
</>
);
};
export default CatDropDown;

How to render SVG component using props?

I'm trying to render an SVG using props of a function. Any help on how to achieve this?
Here is the code:
import React from "react";
import Camera from "../icons/Camera.svg";
export default function Button(props) {
console.log(props.icon);
return (
<button
type="button"
className="mx-auto mb-2.5 flex items-center gap-2 rounded-lg border border-gray-300 px-3.5 py-2 text-sm font-medium text-gray-700 drop-shadow-sm"
>
{props.icon} /* SVG ICONS GOES HERE*/
{props.label}
</button>
);
}
Could try:
import React from "react";
import Camera from "../icons/Camera.svg";
export default function Button({icon, label}) {
return (
<button
type="button"
className="mx-auto mb-2.5 flex items-center gap-2 rounded-lg border border-gray-300 px-3.5 py-2 text-sm font-medium text-gray-700 drop-shadow-sm"
>
{icon && <img src={Camera} alt={label} />}
</button>
);
}
Here is how you can add an Icon
https://codesandbox.io/s/react-playground-forked-x4vsge?file=/index.js
However, a few things when you are creating these components.
If the Icons source is an API (CMS) then you should have some predefined icons and should have your icons library build and pass just icon names.
If you have very limited icons build SVG icons as components and use them
When you use your Button component just use the SVG as a JSX
import Camera from "../icons/Camera.svg";
export default function App() {
return <Button icon={<Camera />} label="Click Me" />;
}

React: How to set up Edit Function in CRUD app to switch out whole components while keeping id

Hey Guys I'm pretty new to React and I'm running into a bit of a pickle here.
I'm making a simple CRUD website creator and I've got the add and delete function created and they work great! but I'm having trouble with the edit function.
I've based this on the this tutorial which works with String data-type
https://www.digitalocean.com/community/tutorials/react-crud-context-hooks
So in my mind this is how it should should work
I've got use state as passing an object with a couple of properties
const [selectedSection, setSelectedSection] = useState({
id: null,
section: {},
});
I've set the id to the current component I'm editing with
const currentSectionId = route.match.params.id;
in my useEffect I'm carrying over the current id with while setting the new compenent skipping the id in the current section
useEffect(() => {
const sectionId = currentSectionId;
const selectedSection = sections.find(
(currentSectionTraversal) => currentSectionTraversal.id === parseInt(sectionId)
);
setSelectedSection(selectedSection);},[currentSectionId, sections]);
const onSubmit = (e) => {
e.preventDefault();
editSection(selectedSection);
history.push("/");
console.log("selectedSection id",selectedSection.section, selectedSection.id)
};
and the button function to spread the selectedSection and change the only the requested value in the button.
const handleOnChange = (userKey, newValue) => setSelectedSection({ ...selectedSection, [userKey]: newValue });
in my render code I've got my button set up like
<button href="/" className="bg-green-400 w-mt hover:bg-green-500 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
value={selectedSection.section}
onChange={() => handleOnChange("section", QuickLinks)}
type="submit"
>Add Section</button>
Now I've tried different things like changing the data-type in the useState Object, having the setSelectedSection in use effect to change the SelectedSection.section
but in the console what I'm noticing is the button is not carrying the data over.
I've imported my compenent as Quicklinks but I'm not sure why it's not passing the component into the selectedSection.section
here is the entire code of the editSection
import React, { useState, useContext, useEffect} from "react";
import { useHistory, Link } from "react-router-dom";
import { GlobalContext } from "./GlobalState";
import QuickLinks from '../components/sections/quick_links/quickLinks';
import QuickLinksPreview from './images/quick-link.jpg';
export const EditSection = (route) => {
let history = useHistory();
const { sections, editSection } = useContext(GlobalContext);
const [selectedSection, setSelectedSection] = useState({
id: null,
section: {},
});
const currentSectionId = route.match.params.id;
useEffect(() => {
const sectionId = currentSectionId;
const selectedSection = sections.find(
(currentSectionTraversal) => currentSectionTraversal.id === parseInt(sectionId)
);
setSelectedSection(selectedSection);
}, [currentSectionId, sections]);
const onSubmit = (e) => {
e.preventDefault();
editSection(selectedSection);
history.push("/");
console.log("selectedSection id",selectedSection.section, selectedSection.id)
};
const handleOnChange = (userKey, newValue) => setSelectedSection({ ...selectedSection, [userKey]: newValue });
if (!selectedSection || !selectedSection.id) {
return <div>Invalid Employee ID.</div>;
}
return (
<React.Fragment>
<div className="w-full container mt-20 mx-auto">
<form onSubmit={onSubmit}>
<table>
<tbody>
{/* ----------------------------Item List Start COPY------------------------ */}
<tr>
<td className="px-6 py-4 whitespace-nowrap">
<div className="flex items-center">
<div className="flex-shrink-0 h-40 w-50 shadow">
<img className="h-40 w-full " src={QuickLinksPreview} alt="" />
</div>
</div>
</td>
<td className="px-6 py-4 whitespace-nowrap">
<div className="text-sm text-gray-900">Quick Links</div>
<div className="text-sm text-gray-500">Multi Card Quick Links<br></br>for Description and links</div>
</td>
<td className="px-6 py-4 whitespace-nowrap">
<span className="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-blue-100 text-white-800"> Beta </span>
{/* Component Development Status
<span className="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-black-800"> Constrution </span>
<span className="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800"> Active </span>
<span className="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-yellow-100 text-black-800"> Testing </span>
*/}
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500">S03-S5</td>
{/* Pricing Levels as Structure
S = Labels that it is sections
02 = is the Template Id for Developers
S = Standard Price
3 = Price level
*/}
<td className="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<button href="/" className="bg-green-400 w-mt hover:bg-green-500 text-white font-bold py-2 px-4 rounded focus:outline-none focus:shadow-outline"
value={selectedSection.section}
onChange={() => handleOnChange("section", QuickLinks)}
type="submit"
>Add Section</button>
</td>
</tr>
{console.log("Selected section", selectedSection.section)}
{/* ----------------------------Item List END COPY------------------------ */}
</tbody>
</table>
<div className="flex items-center justify-between">
<div className="block mt-5 bg-red-400 w-full hover:bg-red-500 text-white font-bold py-2 px-4 rounded focus:text-gray-600 focus:shadow-outline">
<Link to="/">Cancel</Link>
</div>
</div>
</form>
</div>
</React.Fragment>
);
};
Try using onClick instead of onChange for the button. I think onChange is for <input> tags not buttons. Also href is for links, not buttons. Unless this button is in a form type=submit isn't necessary. Also an arrow function isn't required for onClick. onChange={() => handleOnChange("section", QuickLinks)} -> onClick={handleOnChange("section", QuickLinks)}.

404 when visiting page with dynamic route Gatsby

I'm trying to implement dynamic routing on a Gatsby site - I'm fetching launch data from the SpaceXAPI and creating a new page if a launch contains details. These details pages load correctly when you click on the 'View Details' link to view them from the homepage. When you access the page directly by its url, the page information is not found, resulting in a 404.
Why won't pages with this route load on their own? I'm also looking into ways to persist the state that I'm currently passing in to <Link>.
Repository: https://github.com/nikkipeel/gatsby-spacex
I'm not using <Router> or the createPages API...this is my project structure:
Accessing state through location on the page:
[name].js:
import * as React from 'react'
import moment from 'moment'
import Seo from '../../components/seo'
import ScrollToTop from '../../components/scrollToTop'
import Footer from '../../components/footer'
import '../../styles/tailwind.css'
const Launch = ({ location, name }) => (
<>
<main className="h-screen w-full bg-gray-900 text-white mx-auto">
<Seo title={name} />
{name && (
<>
<div className="flex flex-col md:w-3/4 lg:w-1/2 p-12 mx-auto text-base" key={name}>
<h1 className="mission-name tracking-wide font-bold text-2xl my-4">{name}</h1>
<strong className="tracking-wide text-xl my-2">Flight # {location.state.flight_number}</strong>
<div className="flex items-center my-2">
<strong className="text-xl mr-2">Mission: </strong>
<p className="text-base">{location.state.name}</p>
</div>
<div className="flex items-center my-2">
<strong className="text-xl mr-2">Launch Date: </strong>
<p>{moment(location.state.date_local).format('dddd, MMMM Do YYYY, h:mm:ss a')}</p>
</div>
{location.state.details && <p className="my-2">{location.state.details}</p>}
<a
href={location.state.links.wikipedia}
className="my-2 font-bold font-mono bg-clip-text text-transparent bg-gradient-to-t from-blue-500 via-blue-400 to-blue-300 transition duration-500 ease-in-out hover:text-blue-300 hover:underline pr-8"
>
Learn More
</a>
{location.state.links.video_link && (
<a
href={location.statelinks.video_link}
className="my-2 font-bold font-mono bg-clip-text text-transparent bg-gradient-to-t from-blue-500 via-blue-400 to-blue-300 transition duration-500 ease-in-out hover:text-blue-300 hover:underline p-2"
>
View Launch
</a>
)}
</div>
</>
)}
</main>
<ScrollToTop showBelow={250}></ScrollToTop>
<Footer></Footer>
</>
)
export default Launch
Setting state in <Link> in pastLaunches.js:
<Link
to={`/launches/${name}`}
state={{
name: name,
flight_number: flight_number,
date_local: date_local,
links: links,
rocket: rocket,
details: details
}}
className="mt-4 font-bold font-mono bg-clip-text text-transparent bg-gradient-to-t from-blue-500 via-blue-400 to-blue-300 transition duration-500 ease-in-out hover:text-blue-300 hover:underline w-48"
>
View Details
</Link>
Gatsby collection routes: https://www.gatsbyjs.com/docs/reference/routing/file-system-route-api/
Gatsby example client-only paths: https://github.com/gatsbyjs/gatsby/tree/master/examples/client-only-paths
Netlify issue with Gatsby and 404 pages: https://answers.netlify.com/t/gatsby-4-runtime-importmoduleerror-on-404-pages/46608

Categories