tissue/resources/assets/js/components/CheckinForm.tsx
2020-11-08 15:38:54 +09:00

195 lines
9.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import React, { useState, useEffect } from 'react';
import classNames from 'classnames';
import { format } from 'date-fns';
import { CheckBox } from './CheckBox';
import { FieldError, StandaloneFieldError } from './FieldError';
import { TagInput } from './TagInput';
import { MetadataPreview } from './MetadataPreview';
type CheckinFormProps = {
initialState: any;
};
export const CheckinForm: React.FC<CheckinFormProps> = ({ initialState }) => {
const mode = initialState.mode;
const [date, setDate] = useState<string>(initialState.fields.date || '');
const [time, setTime] = useState<string>(initialState.fields.time || '');
const [tags, setTags] = useState<string[]>(initialState.fields.tags || []);
const [link, setLink] = useState<string>(initialState.fields.link || '');
const [linkForPreview, setLinkForPreview] = useState(link);
const [note, setNote] = useState<string>(initialState.fields.note || '');
const [isRealtime, setRealtime] = useState<boolean>(mode === 'create' && initialState.fields.is_realtime);
const [isPrivate, setPrivate] = useState<boolean>(!!initialState.fields.is_private);
const [isTooSensitive, setTooSensitive] = useState<boolean>(!!initialState.fields.is_too_sensitive);
const [discardElapsedTime, setDiscardElapsedTime] = useState<boolean>(!!initialState.fields.discard_elapsed_time);
useEffect(() => {
if (mode === 'create' && isRealtime) {
const id = setInterval(() => {
const now = new Date();
setDate(format(now, 'yyyy/MM/dd'));
setTime(format(now, 'HH:mm'));
}, 500);
return () => clearInterval(id);
}
}, [mode, isRealtime]);
return (
<>
<div className="form-row">
{mode === 'create' && (
<div className="col-sm-12 mb-2">
<CheckBox
id="isRealtime"
name="is_realtime"
checked={isRealtime}
onChange={(v) => setRealtime(v)}
>
</CheckBox>
</div>
)}
<div className="form-group col-sm-6">
<label htmlFor="date">
<span className="oi oi-calendar" />
</label>
<input
type="text"
id="date"
name="date"
className={classNames({
'form-control': true,
'is-invalid': initialState.errors?.date || initialState.errors?.datetime,
})}
pattern="^20[0-9]{2}/(0[1-9]|1[0-2])/(0[1-9]|[12][0-9]|3[01])$"
required
value={date}
onChange={(e) => setDate(e.target.value)}
disabled={isRealtime}
/>
<FieldError errors={initialState.errors?.date} />
</div>
<div className="form-group col-sm-6">
<label htmlFor="time">
<span className="oi oi-clock" />
</label>
<input
type="text"
id="time"
name="time"
className={classNames({
'form-control': true,
'is-invalid': initialState.errors?.time || initialState.errors?.datetime,
})}
pattern="^([01][0-9]|2[0-3]):[0-5][0-9]$"
required
value={time}
onChange={(e) => setTime(e.target.value)}
disabled={isRealtime}
/>
<FieldError errors={initialState.errors?.time} />
</div>
<StandaloneFieldError errors={initialState.errors?.datetime} />
</div>
<div className="form-row">
<div className="form-group col-sm-12">
<label htmlFor="tagInput">
<span className="oi oi-tags" />
</label>
<TagInput
id="tagInput"
name="tags"
values={tags}
isInvalid={!!initialState.errors?.tags}
onChange={(v) => setTags(v)}
/>
<small className="form-text text-muted">Tab, Enter, </small>
<FieldError errors={initialState.errors?.tags} />
</div>
</div>
<div className="form-row">
<div className="form-group col-sm-12">
<label htmlFor="link">
<span className="oi oi-link-intact" />
</label>
<input
type="text"
id="link"
name="link"
autoComplete="off"
className={classNames({ 'form-control': true, 'is-invalid': initialState.errors?.link })}
placeholder="http://..."
value={link}
onChange={(e) => setLink(e.target.value)}
onBlur={() => setLinkForPreview(link)}
/>
<small className="form-text text-muted">URLを貼り付けて登録することができます</small>
<FieldError errors={initialState.errors?.link} />
</div>
</div>
<MetadataPreview link={linkForPreview} tags={tags} onClickTag={(v) => setTags(tags.concat(v))} />
<div className="form-row">
<div className="form-group col-sm-12">
<label htmlFor="note">
<span className="oi oi-comment-square" />
</label>
<textarea
id="note"
name="note"
className={classNames({ 'form-control': true, 'is-invalid': initialState.errors?.note })}
rows={4}
value={note}
onChange={(e) => setNote(e.target.value)}
/>
<small className="form-text text-muted"> 500 </small>
<FieldError errors={initialState.errors?.note} />
</div>
</div>
<div className="form-row mt-4">
<p></p>
<div className="form-group col-sm-12">
<CheckBox
id="isPrivate"
name="is_private"
className="mb-3"
checked={isPrivate}
onChange={(v) => setPrivate(v)}
>
<span className="oi oi-lock-locked" />
</CheckBox>
<CheckBox
id="isTooSensitive"
name="is_too_sensitive"
className="mb-3"
checked={isTooSensitive}
onChange={(v) => setTooSensitive(v)}
>
<span className="oi oi-warning" />
</CheckBox>
<CheckBox
id="discardElapsedTime"
name="discard_elapsed_time"
className="mb-3"
checked={discardElapsedTime}
onChange={(v) => setDiscardElapsedTime(v)}
>
<span className="oi oi-timer" />
<br />
<small className="form-text text-muted">
使
<ul className="pl-3">
<li></li>
<li></li>
</ul>
</small>
</CheckBox>
</div>
</div>
<div className="text-center">
<button className="btn btn-primary" type="submit">
</button>
</div>
</>
);
};