tissue/resources/assets/js/components/CheckinForm.tsx

195 lines
9.1 KiB
TypeScript
Raw Normal View History

import React, { useState, useEffect } from 'react';
2020-08-17 18:17:38 +09:00
import classNames from 'classnames';
import { format } from 'date-fns';
2020-08-17 16:08:35 +09:00
import { CheckBox } from './CheckBox';
import { FieldError, StandaloneFieldError } from './FieldError';
2020-08-17 16:00:04 +09:00
import { TagInput } from './TagInput';
import { MetadataPreview } from './MetadataPreview';
2020-08-17 16:08:35 +09:00
type CheckinFormProps = {
2020-08-17 16:00:04 +09:00
initialState: any;
};
export const CheckinForm: React.FC<CheckinFormProps> = ({ initialState }) => {
const mode = initialState.mode;
2020-08-17 16:00:04 +09:00
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);
2020-08-17 16:00:04 +09:00
const [isPrivate, setPrivate] = useState<boolean>(!!initialState.fields.is_private);
const [isTooSensitive, setTooSensitive] = useState<boolean>(!!initialState.fields.is_too_sensitive);
2020-11-08 15:38:38 +09:00
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]);
2020-08-17 16:00:04 +09:00
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>
)}
2020-08-17 16:00:04 +09:00
<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}
2020-08-17 16:00:04 +09:00
/>
<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}
2020-08-17 16:00:04 +09:00
/>
<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">
2020-08-17 16:08:35 +09:00
<CheckBox
2020-08-17 16:00:04 +09:00
id="isPrivate"
name="is_private"
className="mb-3"
checked={isPrivate}
onChange={(v) => setPrivate(v)}
>
<span className="oi oi-lock-locked" />
2020-08-17 16:08:35 +09:00
</CheckBox>
<CheckBox
2020-08-17 16:00:04 +09:00
id="isTooSensitive"
name="is_too_sensitive"
className="mb-3"
checked={isTooSensitive}
onChange={(v) => setTooSensitive(v)}
>
<span className="oi oi-warning" />
2020-08-17 16:08:35 +09:00
</CheckBox>
2020-11-08 15:38:38 +09:00
<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>
2020-08-17 16:00:04 +09:00
</div>
</div>
<div className="text-center">
<button className="btn btn-primary" type="submit">
</button>
</div>
</>
);
};