Merge pull request #547 from shikorism/feature/realtime-checkin
日時指定を省略してチェックインする機能
This commit is contained in:
commit
ddb11ee96c
@ -23,6 +23,7 @@ class EjaculationController extends Controller
|
|||||||
|
|
||||||
$errors = $request->session()->get('errors');
|
$errors = $request->session()->get('errors');
|
||||||
$initialState = [
|
$initialState = [
|
||||||
|
'mode' => 'create',
|
||||||
'fields' => [
|
'fields' => [
|
||||||
'date' => old('date') ?? $request->input('date', date('Y/m/d')),
|
'date' => old('date') ?? $request->input('date', date('Y/m/d')),
|
||||||
'time' => old('time') ?? $request->input('time', date('H:i')),
|
'time' => old('time') ?? $request->input('time', date('H:i')),
|
||||||
@ -30,7 +31,8 @@ class EjaculationController extends Controller
|
|||||||
'tags' => $tags,
|
'tags' => $tags,
|
||||||
'note' => old('note') ?? $request->input('note', ''),
|
'note' => old('note') ?? $request->input('note', ''),
|
||||||
'is_private' => old('is_private') ?? $request->input('is_private', 0) == 1,
|
'is_private' => old('is_private') ?? $request->input('is_private', 0) == 1,
|
||||||
'is_too_sensitive' => old('is_too_sensitive') ?? $request->input('is_too_sensitive', 0) == 1
|
'is_too_sensitive' => old('is_too_sensitive') ?? $request->input('is_too_sensitive', 0) == 1,
|
||||||
|
'is_realtime' => old('is_realtime', true)
|
||||||
],
|
],
|
||||||
'errors' => isset($errors) ? $errors->getMessages() : null
|
'errors' => isset($errors) ? $errors->getMessages() : null
|
||||||
];
|
];
|
||||||
@ -43,15 +45,20 @@ class EjaculationController extends Controller
|
|||||||
$inputs = $request->all();
|
$inputs = $request->all();
|
||||||
|
|
||||||
$validator = Validator::make($inputs, [
|
$validator = Validator::make($inputs, [
|
||||||
'date' => 'required|date_format:Y/m/d',
|
'date' => 'required_without:is_realtime|date_format:Y/m/d',
|
||||||
'time' => 'required|date_format:H:i',
|
'time' => 'required_without:is_realtime|date_format:H:i',
|
||||||
'note' => 'nullable|string|max:500',
|
'note' => 'nullable|string|max:500',
|
||||||
'link' => 'nullable|url|max:2000',
|
'link' => 'nullable|url|max:2000',
|
||||||
'tags' => 'nullable|string',
|
'tags' => 'nullable|string',
|
||||||
])->after(function ($validator) use ($request, $inputs) {
|
])->after(function ($validator) use ($request, $inputs) {
|
||||||
// 日時の重複チェック
|
// 日時の重複チェック
|
||||||
if (!$validator->errors()->hasAny(['date', 'time'])) {
|
if (!$validator->errors()->hasAny(['date', 'time'])) {
|
||||||
$dt = $inputs['date'] . ' ' . $inputs['time'];
|
if (isset($inputs['date']) && isset($inputs['time'])) {
|
||||||
|
$dt = Carbon::createFromFormat('Y/m/d H:i', $inputs['date'] . ' ' . $inputs['time']);
|
||||||
|
} else {
|
||||||
|
$dt = now();
|
||||||
|
}
|
||||||
|
$dt = $dt->startOfMinute();
|
||||||
if (Ejaculation::where(['user_id' => Auth::id(), 'ejaculated_date' => $dt])->count()) {
|
if (Ejaculation::where(['user_id' => Auth::id(), 'ejaculated_date' => $dt])->count()) {
|
||||||
$validator->errors()->add('datetime', '既にこの日時にチェックインしているため、登録できません。');
|
$validator->errors()->add('datetime', '既にこの日時にチェックインしているため、登録できません。');
|
||||||
}
|
}
|
||||||
@ -59,13 +66,21 @@ class EjaculationController extends Controller
|
|||||||
});
|
});
|
||||||
|
|
||||||
if ($validator->fails()) {
|
if ($validator->fails()) {
|
||||||
return redirect()->route('checkin')->withErrors($validator)->withInput();
|
return redirect()->route('checkin')
|
||||||
|
->withErrors($validator)
|
||||||
|
->withInput(array_merge(['is_realtime' => false], $request->input()));
|
||||||
}
|
}
|
||||||
|
|
||||||
$ejaculation = DB::transaction(function () use ($request, $inputs) {
|
$ejaculation = DB::transaction(function () use ($request, $inputs) {
|
||||||
|
if (isset($inputs['date']) && isset($inputs['time'])) {
|
||||||
|
$ejaculatedDate = Carbon::createFromFormat('Y/m/d H:i', $inputs['date'] . ' ' . $inputs['time']);
|
||||||
|
} else {
|
||||||
|
$ejaculatedDate = now();
|
||||||
|
}
|
||||||
|
$ejaculatedDate = $ejaculatedDate->startOfMinute();
|
||||||
$ejaculation = Ejaculation::create([
|
$ejaculation = Ejaculation::create([
|
||||||
'user_id' => Auth::id(),
|
'user_id' => Auth::id(),
|
||||||
'ejaculated_date' => Carbon::createFromFormat('Y/m/d H:i', $inputs['date'] . ' ' . $inputs['time']),
|
'ejaculated_date' => $ejaculatedDate,
|
||||||
'note' => $inputs['note'] ?? '',
|
'note' => $inputs['note'] ?? '',
|
||||||
'link' => $inputs['link'] ?? '',
|
'link' => $inputs['link'] ?? '',
|
||||||
'source' => Ejaculation::SOURCE_WEB,
|
'source' => Ejaculation::SOURCE_WEB,
|
||||||
@ -138,6 +153,7 @@ class EjaculationController extends Controller
|
|||||||
|
|
||||||
$errors = $request->session()->get('errors');
|
$errors = $request->session()->get('errors');
|
||||||
$initialState = [
|
$initialState = [
|
||||||
|
'mode' => 'update',
|
||||||
'fields' => [
|
'fields' => [
|
||||||
'date' => old('date') ?? $ejaculation->ejaculated_date->format('Y/m/d'),
|
'date' => old('date') ?? $ejaculation->ejaculated_date->format('Y/m/d'),
|
||||||
'time' => old('time') ?? $ejaculation->ejaculated_date->format('H:i'),
|
'time' => old('time') ?? $ejaculation->ejaculated_date->format('H:i'),
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
import { format } from 'date-fns';
|
||||||
import { CheckBox } from './CheckBox';
|
import { CheckBox } from './CheckBox';
|
||||||
import { FieldError, StandaloneFieldError } from './FieldError';
|
import { FieldError, StandaloneFieldError } from './FieldError';
|
||||||
import { TagInput } from './TagInput';
|
import { TagInput } from './TagInput';
|
||||||
@ -10,18 +11,42 @@ type CheckinFormProps = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const CheckinForm: React.FC<CheckinFormProps> = ({ initialState }) => {
|
export const CheckinForm: React.FC<CheckinFormProps> = ({ initialState }) => {
|
||||||
|
const mode = initialState.mode;
|
||||||
const [date, setDate] = useState<string>(initialState.fields.date || '');
|
const [date, setDate] = useState<string>(initialState.fields.date || '');
|
||||||
const [time, setTime] = useState<string>(initialState.fields.time || '');
|
const [time, setTime] = useState<string>(initialState.fields.time || '');
|
||||||
const [tags, setTags] = useState<string[]>(initialState.fields.tags || []);
|
const [tags, setTags] = useState<string[]>(initialState.fields.tags || []);
|
||||||
const [link, setLink] = useState<string>(initialState.fields.link || '');
|
const [link, setLink] = useState<string>(initialState.fields.link || '');
|
||||||
const [linkForPreview, setLinkForPreview] = useState(link);
|
const [linkForPreview, setLinkForPreview] = useState(link);
|
||||||
const [note, setNote] = useState<string>(initialState.fields.note || '');
|
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 [isPrivate, setPrivate] = useState<boolean>(!!initialState.fields.is_private);
|
||||||
const [isTooSensitive, setTooSensitive] = useState<boolean>(!!initialState.fields.is_too_sensitive);
|
const [isTooSensitive, setTooSensitive] = useState<boolean>(!!initialState.fields.is_too_sensitive);
|
||||||
|
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 (
|
return (
|
||||||
<>
|
<>
|
||||||
<div className="form-row">
|
<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">
|
<div className="form-group col-sm-6">
|
||||||
<label htmlFor="date">
|
<label htmlFor="date">
|
||||||
<span className="oi oi-calendar" /> 日付
|
<span className="oi oi-calendar" /> 日付
|
||||||
@ -38,6 +63,7 @@ export const CheckinForm: React.FC<CheckinFormProps> = ({ initialState }) => {
|
|||||||
required
|
required
|
||||||
value={date}
|
value={date}
|
||||||
onChange={(e) => setDate(e.target.value)}
|
onChange={(e) => setDate(e.target.value)}
|
||||||
|
disabled={isRealtime}
|
||||||
/>
|
/>
|
||||||
<FieldError errors={initialState.errors?.date} />
|
<FieldError errors={initialState.errors?.date} />
|
||||||
</div>
|
</div>
|
||||||
@ -57,6 +83,7 @@ export const CheckinForm: React.FC<CheckinFormProps> = ({ initialState }) => {
|
|||||||
required
|
required
|
||||||
value={time}
|
value={time}
|
||||||
onChange={(e) => setTime(e.target.value)}
|
onChange={(e) => setTime(e.target.value)}
|
||||||
|
disabled={isRealtime}
|
||||||
/>
|
/>
|
||||||
<FieldError errors={initialState.errors?.time} />
|
<FieldError errors={initialState.errors?.time} />
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user