📝 Abstracted connection form into a component

This commit is contained in:
2023-09-27 11:48:19 -05:00
parent 538ca61fa8
commit 6cd6612ce1
4 changed files with 114 additions and 185 deletions

View File

@@ -1,5 +1,4 @@
import React, { ReactElement, useCallback, useContext } from "react";
import { Form, Field } from "react-final-form";
import { useDispatch } from "react-redux";
import {
saveSettings,
@@ -7,8 +6,8 @@ import {
} from "../../../actions/settings.actions";
import { AirDCPPSettingsConfirmation } from "./AirDCPPSettingsConfirmation";
import { AirDCPPSocketContext } from "../../../context/AirDCPPSocket";
import { isUndefined, isEmpty, isNil } from "lodash";
import { hostNameValidator } from "../../../shared/utils/validator.utils";
import { isUndefined, isEmpty } from "lodash";
import { ConnectionForm } from "../../shared/ConnectionForm/ConnectionForm";
export const AirDCPPSettingsForm = (): ReactElement => {
const dispatch = useDispatch();
@@ -26,7 +25,7 @@ export const AirDCPPSettingsForm = (): ReactElement => {
airDCPPSettings.setSettings({});
dispatch(deleteSettings());
}, []);
const validate = async () => { };
const initFormData = !isUndefined(
airDCPPSettings.airDCPPState.settings.directConnect,
)
@@ -35,94 +34,8 @@ export const AirDCPPSettingsForm = (): ReactElement => {
return (
<>
<Form
onSubmit={onSubmit}
validate={validate}
initialValues={initFormData}
render={({ handleSubmit }) => (
<form onSubmit={handleSubmit}>
<h2>Configure AirDC++</h2>
<label className="label">AirDC++ Hostname</label>
<div className="field has-addons">
<p className="control">
<span className="select">
<Field name="protocol" component="select">
<option>Protocol</option>
<option value="http">http://</option>
<option value="https">https://</option>
</Field>
</span>
</p>
<div className="control is-expanded">
<Field name="hostname" validate={hostNameValidator}>
{({ input, meta }) => (
<div>
<input
{...input}
type="text"
placeholder="AirDC++ hostname"
className="input"
/>
{meta.error && meta.touched && (
<span className="is-size-7 has-text-danger">
{meta.error}
</span>
)}
</div>
)}
</Field>
</div>
<p className="control">
<Field
name="port"
component="input"
className="input"
placeholder="AirDC++ port"
/>
</p>
</div>
<div className="field">
<label className="label">Credentials</label>
<div className="field-body">
<div className="field">
<p className="control is-expanded has-icons-left">
<Field
name="username"
component="input"
className="input"
placeholder="Username"
/>
<span className="icon is-small is-left">
<i className="fa-solid fa-user-ninja"></i>
</span>
</p>
</div>
<div className="field">
<p className="control is-expanded has-icons-left has-icons-right">
<Field
name="password"
component="input"
type="password"
className="input"
placeholder="Password"
/>
<span className="icon is-small is-left">
<i className="fa-solid fa-lock"></i>
</span>
</p>
</div>
</div>
</div>
<div className="field is-grouped">
<p className="control">
<button type="submit" className="button is-primary">
{!isEmpty(initFormData) ? "Update" : "Save"}
</button>
</p>
</div>
</form>
)}
/>
<ConnectionForm initialData={initFormData} submitHandler={onSubmit} />
{!isEmpty(airDCPPSettings.airDCPPState.socketConnectionInformation) ? (
<AirDCPPSettingsConfirmation
settings={airDCPPSettings.airDCPPState.socketConnectionInformation}

View File

@@ -1,9 +1,8 @@
import React, { ReactElement, useCallback, useEffect } from "react";
import { Form, Field } from "react-final-form";
import { useDispatch, useSelector } from "react-redux";
import { getQBitTorrentClientInfo } from "../../../actions/settings.actions";
import { hostNameValidator } from "../../../shared/utils/validator.utils";
import { saveSettings } from "../../../actions/settings.actions";
import { ConnectionForm } from "../../shared/ConnectionForm/ConnectionForm";
import { isUndefined } from "lodash";
export const QbittorrentConnectionForm = (): ReactElement => {
@@ -34,98 +33,11 @@ export const QbittorrentConnectionForm = (): ReactElement => {
return (
<>
<Form
onSubmit={onSubmit}
// validate={}
initialValues={qBittorrentSettings}
render={({ handleSubmit }) => (
<form className="content" onSubmit={handleSubmit}>
<h2>Configure Qbittorrent</h2>
<label className="label">Qbittorrent Hostname</label>
<div className="field has-addons">
<p className="control">
<span className="select">
<Field name="protocol" component="select">
<option>Protocol</option>
<option value="http">http://</option>
<option value="https">https://</option>
</Field>
</span>
</p>
<div className="control is-expanded">
<Field name="hostname" validate={hostNameValidator}>
{({ input, meta }) => (
<div>
<input
{...input}
type="text"
placeholder="Qbittorrent hostname"
className="input"
/>
{meta.error && meta.touched && (
<span className="is-size-7 has-text-danger">
{meta.error}
</span>
)}
</div>
)}
</Field>
</div>
<p className="control">
<Field
name="port"
component="input"
className="input"
placeholder="Qbittorrent port"
/>
</p>
</div>
<div className="field">
<label className="label">Credentials</label>
<div className="field-body">
<div className="field">
<p className="control is-expanded has-icons-left">
<Field
name="username"
component="input"
className="input"
placeholder="Username"
/>
<span className="icon is-small is-left">
<i className="fa-solid fa-user-ninja"></i>
</span>
</p>
</div>
<div className="field">
<p className="control is-expanded has-icons-left has-icons-right">
<Field
name="password"
component="input"
type="password"
className="input"
placeholder="Password"
/>
<span className="icon is-small is-left">
<i className="fa-solid fa-lock"></i>
</span>
</p>
</div>
</div>
</div>
<div className="field is-grouped">
<p className="control">
<button type="submit" className="button is-primary">
Connect
</button>
</p>
</div>
</form>
)}
<ConnectionForm
initialData={qBittorrentSettings}
submitHandler={onSubmit}
/>
<pre> {JSON.stringify(torrents, null, 4)} </pre>
<pre> {torrents && JSON.stringify(torrents, null, 4)} </pre>
</>
);
};

View File

@@ -0,0 +1,101 @@
import React, { ReactElement } from "react";
import { Form, Field } from "react-final-form";
import { hostNameValidator } from "../../../shared/utils/validator.utils";
import { isEmpty } from "lodash";
export const ConnectionForm = ({
initialData,
submitHandler,
}): ReactElement => {
return (
<>
<Form
onSubmit={submitHandler}
initialValues={initialData}
render={({ handleSubmit }) => (
<form onSubmit={handleSubmit}>
<h2>Configure AirDC++</h2>
<label className="label">AirDC++ Hostname</label>
<div className="field has-addons">
<p className="control">
<span className="select">
<Field name="protocol" component="select">
<option>Protocol</option>
<option value="http">http://</option>
<option value="https">https://</option>
</Field>
</span>
</p>
<div className="control is-expanded">
<Field name="hostname" validate={hostNameValidator}>
{({ input, meta }) => (
<div>
<input
{...input}
type="text"
placeholder="hostname"
className="input"
/>
{meta.error && meta.touched && (
<span className="is-size-7 has-text-danger">
{meta.error}
</span>
)}
</div>
)}
</Field>
</div>
<p className="control">
<Field
name="port"
component="input"
className="input"
placeholder="port"
/>
</p>
</div>
<div className="field">
<label className="label">Credentials</label>
<div className="field-body">
<div className="field">
<p className="control is-expanded has-icons-left">
<Field
name="username"
component="input"
className="input"
placeholder="Username"
/>
<span className="icon is-small is-left">
<i className="fa-solid fa-user-ninja"></i>
</span>
</p>
</div>
<div className="field">
<p className="control is-expanded has-icons-left has-icons-right">
<Field
name="password"
component="input"
type="password"
className="input"
placeholder="Password"
/>
<span className="icon is-small is-left">
<i className="fa-solid fa-lock"></i>
</span>
</p>
</div>
</div>
</div>
<div className="field is-grouped">
<p className="control">
<button type="submit" className="button is-primary">
{!isEmpty(initialData) ? "Update" : "Save"}
</button>
</p>
</div>
</form>
)}
/>
</>
);
};

View File

@@ -17,6 +17,9 @@ const Navbar: React.FunctionComponent = (props) => {
const airDCPPSessionInfo = useSelector(
(state: RootState) => state.airdcpp.airDCPPSessionInfo,
);
const qBittorrentConnectionInfo = useSelector(
(state: RootState) => state.settings.data,
);
const socketDisconnectionReason = useSelector(
(state: RootState) => state.airdcpp.socketDisconnectionReason,
);