Fixing styling, and removing strict from tsconfig
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { useRef, useEffect, useState, ReactNode } from 'react';
|
import { useRef, useEffect, useState, ReactNode, MutableRefObject } from 'react';
|
||||||
import { createPortal } from 'react-dom';
|
import { createPortal } from 'react-dom';
|
||||||
|
|
||||||
interface Props {
|
interface Props {
|
||||||
@@ -7,7 +7,7 @@ interface Props {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default function ClientOnlyPortal({ children, selector }: Props) {
|
export default function ClientOnlyPortal({ children, selector }: Props) {
|
||||||
const ref = useRef();
|
const ref = useRef<HTMLDivElement>(null);
|
||||||
const [mounted, setMounted] = useState(false);
|
const [mounted, setMounted] = useState(false);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
@@ -1,14 +1,88 @@
|
|||||||
import { createPortal } from "react-dom";
|
import Image from "next/image";
|
||||||
|
import { Pie } from "react-chartjs-2";
|
||||||
|
import { Chart as ChartJS, ArcElement, Tooltip, Legend } from "chart.js";
|
||||||
|
|
||||||
|
ChartJS.register(ArcElement, Tooltip, Legend);
|
||||||
|
|
||||||
import ClientOnlyPortal from "./ClientOnlyPortal";
|
import ClientOnlyPortal from "./ClientOnlyPortal";
|
||||||
|
import { forwardRef, MutableRefObject, Ref, RefObject, useEffect } from "react";
|
||||||
|
|
||||||
|
interface ModalProps {
|
||||||
|
modalOpen: boolean
|
||||||
|
toggleModal: Function
|
||||||
|
card: any
|
||||||
|
}
|
||||||
|
|
||||||
|
const Modal = forwardRef<HTMLDivElement, ModalProps>(({modalOpen, toggleModal, card}, ref) => {
|
||||||
|
const data = {
|
||||||
|
labels: ["Power", "Toughness"],
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
label: "Card Power and Toughness",
|
||||||
|
data: [card.power, card.toughness],
|
||||||
|
backgroundColor: [
|
||||||
|
"rgba(255, 99, 132, 0.2)",
|
||||||
|
"rgba(54, 162, 235, 0.2)"
|
||||||
|
],
|
||||||
|
borderColor: [
|
||||||
|
"rgba(255, 99, 132, 1)",
|
||||||
|
"rgba(54, 162, 235, 1)"
|
||||||
|
],
|
||||||
|
borderWidth: 1,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if( (ref as MutableRefObject<HTMLDivElement>).current ) {
|
||||||
|
(ref as MutableRefObject<HTMLDivElement>).current.scrollTo(0, 0);
|
||||||
|
}
|
||||||
|
}, [card])
|
||||||
|
|
||||||
export default function Modal({open}: { open: Function }) {
|
|
||||||
return (
|
return (
|
||||||
<ClientOnlyPortal selector="#modal-root">
|
<ClientOnlyPortal selector="#modal-root">
|
||||||
<div className='fixed bottom-0 container left-0 rounded-md modal'>
|
<div ref={ref}
|
||||||
Hello
|
className={`fixed container rounded-t-3xl p-8 modal overflow-y-auto mt-4 ${
|
||||||
<button onClick={() => open(false)}>Close</button>
|
modalOpen ? "open" : ""
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<div className="flex">
|
||||||
|
<div className="w-1/2">
|
||||||
|
{card &&
|
||||||
|
<Image
|
||||||
|
className="w-full"
|
||||||
|
src={card.image_uris?.png}
|
||||||
|
width={100}
|
||||||
|
height={100}
|
||||||
|
alt={`${card.name} Card`}
|
||||||
|
/>}
|
||||||
|
</div>
|
||||||
|
<div className="w-full pl-4">
|
||||||
|
<h1 className="text-3xl font-bold mb-4">{card?.name}</h1>
|
||||||
|
<p className="whitespace-pre-line">{card.oracle_text}</p>
|
||||||
|
<p className="italic">{card.flavor_text}</p>
|
||||||
|
<div className="w-1/2">
|
||||||
|
<Pie data={data} options={{
|
||||||
|
plugins: {
|
||||||
|
legend: {
|
||||||
|
onClick: e => null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}} />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button
|
||||||
|
onClick={() => {
|
||||||
|
toggleModal(false);
|
||||||
|
document.body.classList.remove("prevent-scroll");
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Close
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</ClientOnlyPortal>
|
</ClientOnlyPortal>
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
|
|
||||||
|
export default Modal;
|
||||||
|
|||||||
27
package-lock.json
generated
27
package-lock.json
generated
@@ -13,9 +13,11 @@
|
|||||||
"@types/node": "18.11.9",
|
"@types/node": "18.11.9",
|
||||||
"@types/react": "18.0.24",
|
"@types/react": "18.0.24",
|
||||||
"@types/react-dom": "18.0.8",
|
"@types/react-dom": "18.0.8",
|
||||||
|
"chart.js": "^3.9.1",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"next": "13.0.1",
|
"next": "13.0.1",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
|
"react-chartjs-2": "^4.3.1",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
"typescript": "4.8.4"
|
"typescript": "4.8.4"
|
||||||
},
|
},
|
||||||
@@ -649,6 +651,11 @@
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"node_modules/chart.js": {
|
||||||
|
"version": "3.9.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-3.9.1.tgz",
|
||||||
|
"integrity": "sha512-Ro2JbLmvg83gXF5F4sniaQ+lTbSv18E+TIf2cOeiH1Iqd2PGFOtem+DUufMZsCJwFE7ywPOpfXFBwRTGq7dh6w=="
|
||||||
|
},
|
||||||
"node_modules/chokidar": {
|
"node_modules/chokidar": {
|
||||||
"version": "3.5.3",
|
"version": "3.5.3",
|
||||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
|
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
|
||||||
@@ -1311,6 +1318,15 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/react-chartjs-2": {
|
||||||
|
"version": "4.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-4.3.1.tgz",
|
||||||
|
"integrity": "sha512-5i3mjP6tU7QSn0jvb8I4hudTzHJqS8l00ORJnVwI2sYu0ihpj83Lv2YzfxunfxTZkscKvZu2F2w9LkwNBhj6xA==",
|
||||||
|
"peerDependencies": {
|
||||||
|
"chart.js": "^3.5.0",
|
||||||
|
"react": "^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-dom": {
|
"node_modules/react-dom": {
|
||||||
"version": "18.2.0",
|
"version": "18.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
|
||||||
@@ -1905,6 +1921,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001429.tgz",
|
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001429.tgz",
|
||||||
"integrity": "sha512-511ThLu1hF+5RRRt0zYCf2U2yRr9GPF6m5y90SBCWsvSoYoW7yAGlv/elyPaNfvGCkp6kj/KFZWU0BMA69Prsg=="
|
"integrity": "sha512-511ThLu1hF+5RRRt0zYCf2U2yRr9GPF6m5y90SBCWsvSoYoW7yAGlv/elyPaNfvGCkp6kj/KFZWU0BMA69Prsg=="
|
||||||
},
|
},
|
||||||
|
"chart.js": {
|
||||||
|
"version": "3.9.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/chart.js/-/chart.js-3.9.1.tgz",
|
||||||
|
"integrity": "sha512-Ro2JbLmvg83gXF5F4sniaQ+lTbSv18E+TIf2cOeiH1Iqd2PGFOtem+DUufMZsCJwFE7ywPOpfXFBwRTGq7dh6w=="
|
||||||
|
},
|
||||||
"chokidar": {
|
"chokidar": {
|
||||||
"version": "3.5.3",
|
"version": "3.5.3",
|
||||||
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
|
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz",
|
||||||
@@ -2335,6 +2356,12 @@
|
|||||||
"loose-envify": "^1.1.0"
|
"loose-envify": "^1.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"react-chartjs-2": {
|
||||||
|
"version": "4.3.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-chartjs-2/-/react-chartjs-2-4.3.1.tgz",
|
||||||
|
"integrity": "sha512-5i3mjP6tU7QSn0jvb8I4hudTzHJqS8l00ORJnVwI2sYu0ihpj83Lv2YzfxunfxTZkscKvZu2F2w9LkwNBhj6xA==",
|
||||||
|
"requires": {}
|
||||||
|
},
|
||||||
"react-dom": {
|
"react-dom": {
|
||||||
"version": "18.2.0",
|
"version": "18.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz",
|
||||||
|
|||||||
@@ -16,9 +16,11 @@
|
|||||||
"@types/node": "18.11.9",
|
"@types/node": "18.11.9",
|
||||||
"@types/react": "18.0.24",
|
"@types/react": "18.0.24",
|
||||||
"@types/react-dom": "18.0.8",
|
"@types/react-dom": "18.0.8",
|
||||||
|
"chart.js": "^3.9.1",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"next": "13.0.1",
|
"next": "13.0.1",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
|
"react-chartjs-2": "^4.3.1",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
"typescript": "4.8.4"
|
"typescript": "4.8.4"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -3,9 +3,7 @@ import { Html, Head, Main, NextScript } from 'next/document';
|
|||||||
export default function Document() {
|
export default function Document() {
|
||||||
return (
|
return (
|
||||||
<Html>
|
<Html>
|
||||||
<Head>
|
<Head />
|
||||||
<title>Magic Card Valuator</title>
|
|
||||||
</Head>
|
|
||||||
<body>
|
<body>
|
||||||
<Main />
|
<Main />
|
||||||
{/* Here we will mount our modal portal */}
|
{/* Here we will mount our modal portal */}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import Head from 'next/head';
|
|||||||
import { invoke } from '@tauri-apps/api/tauri';
|
import { invoke } from '@tauri-apps/api/tauri';
|
||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
import styles from '../styles/Home.module.css';
|
import styles from '../styles/Home.module.css';
|
||||||
import React, { useEffect, useState, useMemo } from 'react';
|
import { useEffect, useState, useMemo, useRef, MutableRefObject, RefObject } from 'react';
|
||||||
import { debounce } from 'lodash';
|
import { debounce } from 'lodash';
|
||||||
|
|
||||||
import Modal from '../components/modal';
|
import Modal from '../components/modal';
|
||||||
@@ -11,11 +11,12 @@ export default function Home() {
|
|||||||
|
|
||||||
const [search, setSearch] = useState('');
|
const [search, setSearch] = useState('');
|
||||||
const [selectedCard, setSelectedCard] = useState({});
|
const [selectedCard, setSelectedCard] = useState({});
|
||||||
const [cards, setCards] = useState([]);
|
const [cards, setCards] = useState<any>([]);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [error, setError] = useState(false);
|
const [error, setError] = useState(false);
|
||||||
const [queryParams, setQueryParams] = useState('');
|
const [queryParams, setQueryParams] = useState('');
|
||||||
const [modalOpen, setModalOpen] = useState(false);
|
const [modalOpen, setModalOpen] = useState(false);
|
||||||
|
const modalRef = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
const searchForCard = async (event: React.ChangeEvent<HTMLInputElement>) => {
|
const searchForCard = async (event: React.ChangeEvent<HTMLInputElement>) => {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
@@ -40,6 +41,9 @@ export default function Home() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
<Head>
|
||||||
|
<title>Magic Card Valuator</title>
|
||||||
|
</Head>
|
||||||
|
|
||||||
<div className="absolute bg-red-800 w-96 bg-red-800 right-0 top-0 rounded-md mr-4 mt-4 p-4">
|
<div className="absolute bg-red-800 w-96 bg-red-800 right-0 top-0 rounded-md mr-4 mt-4 p-4">
|
||||||
{error}
|
{error}
|
||||||
@@ -53,17 +57,20 @@ export default function Home() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<main className="container my-4">
|
<main className="container my-4">
|
||||||
{ cards?.length === 0 || !cards ?
|
{ cards.length === 0 || !cards ?
|
||||||
<div>Please search for a card</div>
|
<div>Please search for a card</div>
|
||||||
:
|
:
|
||||||
<section className="flex flex-wrap justify-center items-center">
|
<section className="flex flex-wrap justify-center items-center">
|
||||||
{loading && search !== "" ?
|
{loading && search !== "" ?
|
||||||
<div className="spinner mx-auto"></div>
|
<div className="spinner mx-auto"></div>
|
||||||
:
|
:
|
||||||
cards && cards.map( (card: any) => <Image onClick={() => {
|
cards && cards.map( (card: any) =>
|
||||||
|
<Image onClick={() => {
|
||||||
setSelectedCard(card);
|
setSelectedCard(card);
|
||||||
setModalOpen(true);
|
setModalOpen(true);
|
||||||
}} className="cursor-pointer hover:scale-110 transition-transform duration-150 ease-in-out w-full sm:w-1/2 md:w-1/3 lg:w-1/4 p-2" key={card.id} alt={`${card.name} Card`} src={card.image_uris?.png || "https://via.placeholder.com/150" } width={100} height={100} /> )
|
document.body.classList.toggle('prevent-scroll');
|
||||||
|
}} className="cursor-pointer hover:scale-110 transition-transform duration-150 ease-in-out w-full sm:w-1/2 md:w-1/3 lg:w-1/4 p-2" key={card.id} alt={`${card.name} Card`} src={card.image_uris?.png || "https://via.placeholder.com/150" } width={100} height={100} />
|
||||||
|
)
|
||||||
}
|
}
|
||||||
</section>
|
</section>
|
||||||
}
|
}
|
||||||
@@ -78,9 +85,7 @@ export default function Home() {
|
|||||||
</a>
|
</a>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
{modalOpen ?
|
<Modal ref={modalRef} modalOpen={modalOpen} toggleModal={setModalOpen} card={selectedCard} />
|
||||||
<Modal open={setModalOpen} />
|
|
||||||
: null}
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -12,10 +12,25 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#modal-root {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prevent-scroll {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
.modal {
|
.modal {
|
||||||
background: #1d1d1c;
|
background: #1d1d1c;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
top: 100%;
|
||||||
|
transition: top 150ms cubic-bezier(0.4, 0, 0.2, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal.open {
|
||||||
|
top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.spinner {
|
.spinner {
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
"lib": ["dom", "dom.iterable", "esnext"],
|
"lib": ["dom", "dom.iterable", "esnext"],
|
||||||
"allowJs": true,
|
"allowJs": true,
|
||||||
"skipLibCheck": true,
|
"skipLibCheck": true,
|
||||||
"strict": true,
|
|
||||||
"forceConsistentCasingInFileNames": true,
|
"forceConsistentCasingInFileNames": true,
|
||||||
"noEmit": true,
|
"noEmit": true,
|
||||||
"esModuleInterop": true,
|
"esModuleInterop": true,
|
||||||
|
|||||||
Reference in New Issue
Block a user