見出し画像

さらなる仕上げ

アンケート提出完了後の表示


英語になってるんのもあるけど、提出したのか提出してないのかわかり辛いのもあるから、完了日時でも出しときますか。

まず翻訳ストリング

まずShow Detailsは「詳細」くらいにしときますか?

    "Show Details": "詳細",


完了日時

app/Http/Controllers/DashboardController.php

class DashboardController extends Controller
{
    public function index(): Response
    {
        $surveys = Survey::latest()->get()->map(function ($survey) {
            $response = $survey->responses()->where('user_id', auth()->id())->first();
            $survey->response_id = $response ? $response->id : null;
            $survey->response_created_at = $response ? $response->created_at : null;  // 追加された行
            return $survey;
        });

        return Inertia::render('Dashboard', [
            'surveys' => $surveys
        ]);
    }
}

で、response_created_at を渡している

でまあもうちょい拡張
resources/js/Pages/Dashboard.jsx

                  {survey.response_id ? (
                    <>
                      <PrimaryButton href={route('surveys.responses.show', {survey: survey.id, response: survey.response_id})}>
                        <VscEye className="mr-2" /> {t('Show Details')}
                      </PrimaryButton>
                      <p className="text-sm text-gray-700 mt-2 p-2 border border-blue-300 bg-blue-100 rounded">
                        {t("Submitted At")}:
                        {dayjs(survey.response_created_at).format('YYYY/MM/DD HH:mm:ss')}
                        <small className="ml-2">({dayjs(survey.response_created_at).fromNow()})</small>
                      </p>
                    </>
                  ) : (
                    <PrimaryButton href={route('surveys.take', survey.id)}>
                      <VscChecklist className="mr-2" /> {t('Take The Survey')}
                    </PrimaryButton>
                  )}


デザインはまだチューニングのしようがあるかもしれない。とりあえずSecondaryButtonの方がいいかもなー

完了と未完了でボタンの色を変更する

これに関して元々の仕様ではこう

一般ユーザーと管理者だけのシンプルな権限設定
survey自体の作成は管理者が行う
surveyが作成されたら各ユーザーは誰でも受けることができる
一度受けたsurveyは再度はできない結果は即座に公開され自信の回答を見る事ができる。
何らかの集計viewを作成する

https://note.com/mocotech/n/n4b73f7d94c28?magazine_key=m67ebb7f03751

実は「何らかの集計view」の事も考えないといけないんだけど、それはまたちょっとこのコードがfreezeしてからでいいと思う。

breadcrumb

今、「詳細」を押すと出ていないので。

Breadcrumbs::for('surveys.take', function(BreadcrumbTrail $trail, Survey $survey)
{
    $trail->parent('dashboard');
    $trail->push($survey->title, route('surveys.take', $survey));
});
Breadcrumbs::for('surveys.responses.show', function(BreadcrumbTrail $trail, Survey $survv
ey, SurveyResponse $response)
{
    $trail->parent('dashboard');
    $trail->push($survey->title, route('surveys.responses.show', [$survey, $response]));
});


「ダミーの質問」が表示された。

formリクエスト

今surveyの作成時においてバリデーションが極めて適当である。

    public function store(Request $request, SurveyService $surveyService): RedirectResponse
    {
        $data = $request->all();
        $data['settings'] = [];
        // TODO: 本来はvalidationをかける
        $surveyQuestionSetId = $request->survey_question_set_id;
        $surveyStructure = SurveyQuestion::findOrFail($surveyQuestionSetId)->question_data;

        DB::beginTransaction();
        $survey = Survey::create($data);
        $surveyService->createSurveyPage($survey, $surveyStructure);
        DB::commit();
        return redirect(route('surveys.index'))
            ->with(['success' => __('New Survey Created')])
        ;
    }

これを何とかしていこう。てか何とかしないといけない所多すぎぃ

質問セットを選択してくださいとかその辺を一気にやっていくぞっと。

リクエスト側


% ./vendor/bin/sail artisan make:request SurveyRequest

   INFO  Request [app/Http/Requests/SurveyRequest.php] created successfully.


    public function rules(): array
    {
        return [
            'title'                  => 'required|string|max:255',
            'description'            => 'nullable|string',
            'survey_question_set_id' => 'required|integer|exists:survey_questions,id',
        ];


これを適用してControllerを更新する

    public function store(SurveyRequest $request, SurveyService $surveyService): RedirectResponse
    {
        $data = $request->validated();
        $data['settings'] = [];
        $surveyQuestionSetId = $request->survey_question_set_id;
        $surveyStructure = SurveyQuestion::findOrFail($surveyQuestionSetId)->question_data;

        DB::beginTransaction();
        $survey = Survey::create($data);
        $surveyService->createSurveyPage($survey, $surveyStructure);
        DB::commit();
        return redirect(route('surveys.index'))
            ->with(['success' => __('New Survey Created')])
        ;
    }

フロントエンドも更新しておく。

resources/js/Pages/Surveys/Create.jsx

import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout';
import { Head, useForm } from '@inertiajs/react';
import { useLaravelReactI18n } from 'laravel-react-i18n';
import InputError from '@/Components/InputError';
import InputLabel from '@/Components/InputLabel';
import PrimaryButton from '@/Components/PrimaryButton';
import TextInput from '@/Components/TextInput';

export default function SurveyCreate({ auth, surveyQuestionSets }) {
  const { t } = useLaravelReactI18n();
  const {
    data, setData, post, errors, processing,
  } = useForm({
    title: '',
    description: '',
    settings: '',
    survey_question_set_id: '',
  });

  const submit = (e) => {
    e.preventDefault();
    post(route('surveys.store'));
  };

  return (
    <AuthenticatedLayout
      user={auth.user}
      header={<h2 className="font-semibold text-xl text-gray-800 leading-tight">{t('Create New Survey')}</h2>}
    >
      <Head title={t('Create New Survey')} />
      <div className="py-12">
        <div className="max-w-7xl mx-auto sm:px-6 lg:px-8 space-y-6">
          <div className="p-4 sm:p-8 bg-white shadow sm:rounded-lg">
            <form onSubmit={submit} className="mt-6 space-y-6">
              <div>
                <InputLabel htmlFor="title" value={t('Title')} />

                <TextInput
                  id="title"
                  className="mt-1 block w-full"
                  value={data.title}
                  onChange={(e) => setData('title', e.target.value)}
                  onSubmit={submit}
                  required
                />

                <InputError className="mt-2" message={errors.title} />
              </div>

              <div className="mt-3">
                <InputLabel htmlFor="description" value={t('Description')} />

                <TextInput
                  id="description"
                  className="mt-1 block w-full"
                  value={data.description}
                  onChange={(e) => setData('description', e.target.value)}
                  onSubmit={submit}
                />

                <InputError className="mt-2" message={errors.description} />
              </div>

              <div className="mt-3">
                <InputLabel htmlFor="survey_question_set_id" value={t('Question Set')} />
                <select
                  id="survey_question_set_id"
                  className="mt-1 block w-full"
                  value={data.survey_question_set_id}
                  onChange={(e) => setData('survey_question_set_id', e.target.value)}
                  required
                >
                  <option value="">
                    -- {t('Select a Question Set')} --
                  </option>

                  {Object.entries(surveyQuestionSets).map(([key, value]) => (
                    <option key={key} value={key}>
                      {value}
                    </option>
                  ))}
                </select>
                <InputError className="mt-2" message={errors.survey_question_set_id} />
              </div>

              <div className="flex items-center gap-4">
                <PrimaryButton disabled={processing}>{t('Save')}</PrimaryButton>
              </div>

            </form>
          </div>
        </div>
      </div>
    </AuthenticatedLayout>
  );
}

続いてEditも更新する

この場合validationがちょっと異なる。survey_question_set_idはcreateのときしか使わないからだ。この場合以下のようにしてもok

    public function rules(): array
    {
        $rules =  [
            'title'                  => 'required|string|max:255',
            'description'            => 'nullable|string',
            'survey_question_set_id' => 'required|integer|exists:survey_questions,id',
            'settings'               => 'nullable|array',
        ];
        if ($this->isMethod('patch') || $this->isMethod('put')) {
            unset($rules['survey_question_set_id']);
        }

        return $rules;
    }

settingsも付けておく。

でController

    public function update(SurveyRequest $request, Survey $survey): RedirectResponse
    {
        $data = $request->validated();
        $survey->update($data);
        return redirect(route('surveys.index', $survey))
            ->with(['success' => __('Survey Settings Updated')]);

    }
'Survey Settings Updated

これの言語も無かったので追加しておく

    "Survey Settings Updated": "アンケート調査の設定を更新しました",





いいなと思ったら応援しよう!