Files
threetwo/src/client/components/ComicDetail/EditMetadataPanel.tsx
Rishi Ghan dba520b4c1 🧸 Zustand and Tanstack Query (#96)
* ↪️ Removed node-sass, added sass

* 🏗️ Refactoring Navbar to read from zustand store

* ⬆️ Bumped deps

* 🏗️ Refactored AirDC++ session status indicator

* 🏗️ Refactored Import page to read from global state

* 🏗 Wired up the event emit correctly

* 🏗️ Added import queue related state

* 🏗 Implemented setQueueAction

* 🏗️ Wired up job queue control methods

* 🏗️ Added null check and removed useless deps

* 🏗️ Refactored the Import page

* ↪️ Added cache invalidation to job statistics query

* 🏗️ Refactoring the Library page

* 🏗️ Fixed pagination and disabled states

* ✏️ Changed page to offset

To better reflect what we are doing with the pagination controls

* 🏗️ Refactoring ComicDetail page and its children

* 🏗️ Refactored ComicDetailContainer with useQuery

* 🔧 Fixed the error check on Library page

* 🏗️ Refactoring AcquisitionPanel

* 🏗️ Refactoring the AirDC++ Forms

* 🦃 Thanksgiving Day bug fixes

* ⬆️ Bumped up Vite to 5.0

* 🔧 Refactoring AcquisitionPanel

* 🏗️ Wiring up the DC++ search method

* 🏗️ Refactoring AirDC++ search method

* 🔎 Added some validation to ADC++ Hubs settings form

* 🏗️ Fixed the ADC++ search results

* 🏗️ Cleanup of the search results pane
2023-11-28 22:54:45 -05:00

343 lines
12 KiB
TypeScript

import React, { ReactElement, useCallback, useEffect, useState } from "react";
import { Form, Field } from "react-final-form";
import arrayMutators from "final-form-arrays";
import { FieldArray } from "react-final-form-arrays";
import AsyncSelectPaginate from "./AsyncSelectPaginate/AsyncSelectPaginate";
import TextareaAutosize from "react-textarea-autosize";
export const EditMetadataPanel = (props): ReactElement => {
const validate = async () => {};
const onSubmit = async () => {};
const AsyncSelectPaginateAdapter = ({ input, ...rest }) => {
return (
<AsyncSelectPaginate
{...input}
{...rest}
onChange={(value) => input.onChange(value)}
/>
);
};
const TextareaAutosizeAdapter = ({ input, ...rest }) => {
return (
<TextareaAutosize
{...input}
{...rest}
onChange={(value) => input.onChange(value)}
/>
);
};
// const rawFileDetails = useSelector(
// (state: RootState) => state.comicInfo.comicBookDetail.rawFileDetails.name,
// );
return (
<>
<Form
onSubmit={onSubmit}
validate={validate}
mutators={{
...arrayMutators,
}}
render={({
handleSubmit,
form: {
mutators: { push, pop },
}, // injected from final-form-arrays above
pristine,
form,
submitting,
values,
}) => (
<form onSubmit={handleSubmit}>
{/* Issue Name */}
<div className="field is-horizontal">
<div className="field-label is-normal">
<label className="label">Issue Details</label>
</div>
<div className="field-body">
<div className="field">
<p className="control is-expanded has-icons-left">
<Field
name="issue_name"
component="input"
className="input"
initialValue={rawFileDetails}
placeholder={"Issue Name"}
/>
<span className="icon is-small is-left">
<i className="fa-solid fa-user-ninja"></i>
</span>
</p>
</div>
</div>
</div>
{/* Issue Number and year */}
<div className="field is-horizontal">
<div className="field-label"></div>
<div className="field-body">
<div className="field">
<p className="control has-icons-left">
<Field
name="issue_number"
component="input"
className="input"
placeholder="Issue Number"
/>
<span className="icon is-small is-left">
<i className="fa-solid fa-hashtag"></i>
</span>
</p>
<p className="help">Do not enter the first zero</p>
</div>
{/* year */}
<div className="field">
<p className="control">
<Field
name="issue_year"
component="input"
className="input"
/>
</p>
</div>
</div>
</div>
{/* page count */}
<div className="field is-horizontal">
<div className="field-label"></div>
<div className="field-body">
<div className="field">
<p className="control has-icons-left">
<Field
name="page_count"
component="input"
className="input"
placeholder="Page Count"
/>
<span className="icon is-small is-left">
<i className="fa-solid fa-note-sticky"></i>
</span>
</p>
</div>
</div>
</div>
{/* Description */}
<div className="field is-horizontal">
<div className="field-label is-normal">
<label className="label">Description</label>
</div>
<div className="field-body">
<div className="field">
<p className="control is-expanded has-icons-left">
<Field
name={"description"}
className="textarea"
component={TextareaAutosizeAdapter}
placeholder={"Description"}
/>
</p>
</div>
</div>
</div>
<hr size="1" />
<div className="field is-horizontal">
<div className="field-label">
<label className="label">Distributor Info</label>
</div>
<div className="field-body">
<div className="field is-expanded">
<div className="field">
<p className="control has-icons-left">
<Field
name="distributor_sku"
component="input"
className="input"
placeholder="SKU"
/>
<span className="icon is-small is-left">
<i className="fa-solid fa-barcode"></i>
</span>
</p>
</div>
</div>
{/* UPC code */}
<div className="field">
<p className="control has-icons-left">
<Field
name="upc_code"
component="input"
className="input"
placeholder="UPC Code"
/>
<span className="icon is-small is-left">
<i className="fa-solid fa-box"></i>
</span>
</p>
</div>
</div>
</div>
<hr size="1" />
{/* Publisher */}
<div className="field is-horizontal">
<div className="field-label is-normal">
<label className="label">Publisher</label>
</div>
<div className="field-body">
<div className="field">
<p className="control is-expanded has-icons-left">
<Field
name={"publisher"}
component={AsyncSelectPaginateAdapter}
placeholder={
<div>
<i className="fas fa-print mr-2"></i> Publisher
</div>
}
metronResource={"publisher"}
/>
</p>
</div>
</div>
</div>
{/* Arc */}
<div className="field is-horizontal">
<div className="field-label is-normal">
<label className="label">Story Arc</label>
</div>
<div className="field-body">
<div className="field">
<p className="control is-expanded has-icons-left">
<Field
name={"story_arc"}
component={AsyncSelectPaginateAdapter}
placeholder={
<div>
<i className="fas fa-book-open mr-2"></i> Story Arc
</div>
}
metronResource={"arc"}
/>
</p>
</div>
</div>
</div>
{/* series */}
<div className="field is-horizontal">
<div className="field-label is-normal">
<label className="label">Series</label>
</div>
<div className="field-body">
<div className="field">
<p className="control is-expanded has-icons-left">
<Field
name={"series"}
component={AsyncSelectPaginateAdapter}
placeholder={
<div>
<i className="fas fa-layer-group mr-2"></i> Series
</div>
}
metronResource={"series"}
/>
</p>
</div>
</div>
</div>
<hr size="1" />
{/* team credits */}
<div className="field is-horizontal">
<div className="field-label is-normal">
<label className="label">Team Credits</label>
</div>
<div className="field-body mt-4">
<div className="field">
<div className="buttons">
<button
type="button"
className="button is-small"
onClick={() => push("credits", undefined)}
>
Add credit
</button>
<button
type="button"
className="button is-small"
onClick={() => pop("credits")}
>
Remove credit
</button>
</div>
</div>
</div>
</div>
<FieldArray name="credits">
{({ fields }) =>
fields.map((name, index) => (
<div className="field is-horizontal" key={name}>
<div className="field-label is-normal">
<label></label>
</div>
<div className="field-body">
<div className="field">
<p className="control">
<Field
name={`${name}.creator`}
component={AsyncSelectPaginateAdapter}
placeholder={
<div>
<i className="fa-solid fa-ghost"></i> Creator
</div>
}
metronResource={"creator"}
/>
</p>
</div>
<div className="field">
<p className="control">
<Field
name={`${name}.role`}
metronResource={"role"}
placeholder={
<div>
<i className="fa-solid fa-key"></i> Role
</div>
}
component={AsyncSelectPaginateAdapter}
/>
</p>
</div>
<span
className="icon is-danger mt-2"
onClick={() => fields.remove(index)}
style={{ cursor: "pointer" }}
>
<i className="fas fa-times"></i>
</span>
</div>
</div>
))
}
</FieldArray>
<pre>{JSON.stringify(values, undefined, 2)}</pre>
</form>
)}
/>
</>
);
};
export default EditMetadataPanel;