269 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Svelte
		
	
	
	
	
	
			
		
		
	
	
			269 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Svelte
		
	
	
	
	
	
<script>
 | 
						|
  import { _ } from "svelte-i18n";
 | 
						|
  import AddTrackModal from "./AddTrackModal.svelte";
 | 
						|
  let modal_open = false;
 | 
						|
  import TracksEmptyState from "./TracksEmptyState.svelte";
 | 
						|
  import { TrackService } from "@odit/lfk-client-js";
 | 
						|
  const tracks_promise = TrackService.trackControllerGetAll();
 | 
						|
  import { tracks as tracksstore } from "../../store.js";
 | 
						|
  import toast from "svelte-french-toast";
 | 
						|
  $: trackscache = [];
 | 
						|
  $: deleteTracks = [];
 | 
						|
  $: editTracks = [];
 | 
						|
  tracksstore.subscribe((val) => {
 | 
						|
    trackscache = val;
 | 
						|
  });
 | 
						|
  tracks_promise.then((data) => {
 | 
						|
    tracksstore.set(data);
 | 
						|
  });
 | 
						|
</script>
 | 
						|
 | 
						|
<section class="container p-5">
 | 
						|
  <h4 class="mb-1 text-3xl font-extrabold leading-tight">
 | 
						|
    {$_("tracks")}
 | 
						|
  </h4>
 | 
						|
  <button
 | 
						|
    on:click={() => {
 | 
						|
      modal_open = true;
 | 
						|
    }}
 | 
						|
    type="button"
 | 
						|
    class="w-full inline-flex justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-blue-600 text-base font-medium text-white hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500 sm:w-auto sm:text-sm"
 | 
						|
  >
 | 
						|
    {$_("create-track")}
 | 
						|
  </button>
 | 
						|
  {#await tracks_promise}
 | 
						|
    <div
 | 
						|
      class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2"
 | 
						|
      role="alert"
 | 
						|
    >
 | 
						|
      <p class="font-bold">{$_("track-data-is-being-loaded")}</p>
 | 
						|
      <p class="text-sm">{$_("this-might-take-a-moment")}</p>
 | 
						|
    </div>
 | 
						|
  {:then}
 | 
						|
    {#if trackscache.length === 0}
 | 
						|
      <TracksEmptyState />
 | 
						|
    {:else}
 | 
						|
      <div
 | 
						|
        class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll mt-4"
 | 
						|
      >
 | 
						|
        <table class="divide-y divide-gray-200 w-full">
 | 
						|
          <thead class="bg-gray-50">
 | 
						|
            <tr class="odd:bg-white even:bg-gray-100">
 | 
						|
              <th
 | 
						|
                scope="col"
 | 
						|
                class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
 | 
						|
              >
 | 
						|
                ID
 | 
						|
              </th>
 | 
						|
              <th
 | 
						|
                scope="col"
 | 
						|
                class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
 | 
						|
              >
 | 
						|
                {$_("track-name")}
 | 
						|
              </th>
 | 
						|
              <th
 | 
						|
                scope="col"
 | 
						|
                class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
 | 
						|
              >
 | 
						|
                {$_("distance")}
 | 
						|
              </th>
 | 
						|
              <th
 | 
						|
                scope="col"
 | 
						|
                class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
 | 
						|
              >
 | 
						|
                {$_("minimum-lap-time-in-s")}
 | 
						|
              </th>
 | 
						|
              <th
 | 
						|
                scope="col"
 | 
						|
                class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider"
 | 
						|
              >
 | 
						|
                {$_("action")}
 | 
						|
              </th>
 | 
						|
            </tr>
 | 
						|
          </thead>
 | 
						|
          <tbody class="divide-y divide-gray-200">
 | 
						|
            {#each trackscache as t}
 | 
						|
              <tr
 | 
						|
                class="odd:bg-white even:bg-gray-100"
 | 
						|
                data-rowid="station_{t.id}"
 | 
						|
              >
 | 
						|
                <td class="px-6 py-4 whitespace-nowrap">
 | 
						|
                  <div class="flex items-center">
 | 
						|
                    <div class="ml-4">
 | 
						|
                      <div class="text-sm font-medium text-gray-900">
 | 
						|
                        #{t.id}
 | 
						|
                      </div>
 | 
						|
                    </div>
 | 
						|
                  </div>
 | 
						|
                </td>
 | 
						|
                <td class="px-6 py-4 whitespace-nowrap">
 | 
						|
                  <div class="flex items-center">
 | 
						|
                    <div class="ml-4">
 | 
						|
                      {#if editTracks.findIndex((tr) => tr.id === t.id) !== -1}
 | 
						|
                        <input
 | 
						|
                          class="shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-neutral-800 rounded-md p-0.5"
 | 
						|
                          type="text"
 | 
						|
                          value={t.name}
 | 
						|
                          on:input={(e) => {
 | 
						|
                            const i = editTracks.findIndex(
 | 
						|
                              (tr) => tr.id === t.id
 | 
						|
                            );
 | 
						|
                            editTracks[i].name = e.target.value;
 | 
						|
                          }}
 | 
						|
                        />
 | 
						|
                      {:else}
 | 
						|
                        <div class="text-sm font-medium text-gray-900">
 | 
						|
                          {t.name}
 | 
						|
                        </div>
 | 
						|
                      {/if}
 | 
						|
                    </div>
 | 
						|
                  </div>
 | 
						|
                </td>
 | 
						|
                <td class="px-6 py-4 whitespace-nowrap">
 | 
						|
                  <div class="flex items-center">
 | 
						|
                    <div class="ml-4">
 | 
						|
                      {#if editTracks.findIndex((tr) => tr.id === t.id) !== -1}
 | 
						|
                      <input
 | 
						|
                          class="shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-neutral-800 rounded-md p-0.5"
 | 
						|
                          type="number"
 | 
						|
                          value={t.distance}
 | 
						|
                          on:input={(e) => {
 | 
						|
                            const i = editTracks.findIndex(
 | 
						|
                              (tr) => tr.id === t.id
 | 
						|
                            );
 | 
						|
                            editTracks[i].distance = parseInt(e.target.value);
 | 
						|
                          }}
 | 
						|
                        />
 | 
						|
                      {:else}
 | 
						|
                      <div class="text-sm font-medium text-gray-900">
 | 
						|
                        {t.distance}
 | 
						|
                      </div>
 | 
						|
                      {/if}
 | 
						|
                    </div>
 | 
						|
                  </div>
 | 
						|
                </td>
 | 
						|
                <td class="px-6 py-4 whitespace-nowrap">
 | 
						|
                  <div class="flex items-center">
 | 
						|
                    <div class="ml-4">
 | 
						|
                      {#if editTracks.findIndex((tr) => tr.id === t.id) !== -1}
 | 
						|
                      <input
 | 
						|
                          class="shadow-sm rounded-l-md sm:text-sm border-gray-300 border bg-gray-50 text-neutral-800 rounded-md p-0.5"
 | 
						|
                          type="number"
 | 
						|
                          value={t.minimumLapTime}
 | 
						|
                          on:input={(e) => {
 | 
						|
                            const i = editTracks.findIndex(
 | 
						|
                              (tr) => tr.id === t.id
 | 
						|
                            );
 | 
						|
                            editTracks[i].minimumLapTime = parseInt(e.target.value);
 | 
						|
                          }}
 | 
						|
                        />
 | 
						|
                      {:else}
 | 
						|
                      <div class="text-sm font-medium text-gray-900">
 | 
						|
                        {t.minimumLapTime}
 | 
						|
                      </div>
 | 
						|
                      {/if}
 | 
						|
                    </div>
 | 
						|
                  </div>
 | 
						|
                </td>
 | 
						|
                <td class="px-6 py-4 whitespace-nowrap">
 | 
						|
                  <div class="flex items-center">
 | 
						|
                    {#if deleteTracks.includes(t.id)}
 | 
						|
                      <button
 | 
						|
                        tabindex="0"
 | 
						|
                        on:click={() => {
 | 
						|
                          deleteTracks = deleteTracks.filter((tr) => {
 | 
						|
                            tr.id !== t.id;
 | 
						|
                          });
 | 
						|
                        }}
 | 
						|
                        class="ml-4 text-gray-600 hover:text-gray-900 cursor-pointer"
 | 
						|
                        >{$_("cancel")}</button
 | 
						|
                      >
 | 
						|
                      <button
 | 
						|
                        tabindex="0"
 | 
						|
                        on:click={async () => {
 | 
						|
                          TrackService.trackControllerRemove(t.id);
 | 
						|
                          deleteTracks = deleteTracks.filter((tr) => {
 | 
						|
                            tr.id !== t.id;
 | 
						|
                          });
 | 
						|
                          tracksstore.set(
 | 
						|
                            $tracksstore.filter((tr) => tr.id !== t.id)
 | 
						|
                          );
 | 
						|
                          toast.success($_("track-deleted"));
 | 
						|
                        }}
 | 
						|
                        class="ml-4 text-red-600 hover:text-red-900 cursor-pointer"
 | 
						|
                        >{$_("confirm-delete")}</button
 | 
						|
                      >
 | 
						|
                    {:else if editTracks.findIndex((tr) => tr.id === t.id) !== -1}
 | 
						|
                      <button
 | 
						|
                        tabindex="0"
 | 
						|
                        on:click={() => {
 | 
						|
                          editTracks = editTracks.filter((tr) => {
 | 
						|
                            tr.id !== t.id;
 | 
						|
                          });
 | 
						|
                        }}
 | 
						|
                        class="ml-4 text-gray-600 hover:text-gray-900 cursor-pointer"
 | 
						|
                        >{$_("cancel")}</button
 | 
						|
                      >
 | 
						|
                      <button
 | 
						|
                        tabindex="0"
 | 
						|
                        on:click={async () => {
 | 
						|
                          toast.loading($_("track-is-being-updated"));
 | 
						|
                          const i = editTracks.findIndex(
 | 
						|
                            (tr) => tr.id === t.id
 | 
						|
                          );
 | 
						|
                          const res = await TrackService.trackControllerPut(
 | 
						|
                            t.id,
 | 
						|
                            editTracks[i]
 | 
						|
                          );
 | 
						|
                          tracksstore.set(
 | 
						|
                            $tracksstore.filter((tr) => tr.id !== t.id)
 | 
						|
                          );
 | 
						|
                          $tracksstore.push(res)
 | 
						|
                          editTracks = editTracks.filter((tr) => {
 | 
						|
                            tr.id !== t.id;
 | 
						|
                          });
 | 
						|
                          toast.dismiss();
 | 
						|
                          toast.success($_("track-updated"));
 | 
						|
                        }}
 | 
						|
                        class="ml-4 text-green-600 hover:text-green-900 cursor-pointer"
 | 
						|
                        >{$_("save")}</button
 | 
						|
                      >
 | 
						|
                    {:else}
 | 
						|
                      <button
 | 
						|
                        tabindex="0"
 | 
						|
                        on:click={() => {
 | 
						|
                          editTracks.push(t);
 | 
						|
                          editTracks = editTracks;
 | 
						|
                        }}
 | 
						|
                        class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer"
 | 
						|
                        >{$_("edit")}</button
 | 
						|
                      >
 | 
						|
                      <button
 | 
						|
                        tabindex="0"
 | 
						|
                        on:click={() => {
 | 
						|
                          deleteTracks.push(t.id);
 | 
						|
                          deleteTracks = deleteTracks;
 | 
						|
                        }}
 | 
						|
                        class="ml-4 text-red-600 hover:text-red-900 cursor-pointer"
 | 
						|
                        >{$_("delete")}</button
 | 
						|
                      >
 | 
						|
                    {/if}
 | 
						|
                  </div>
 | 
						|
                </td>
 | 
						|
              </tr>
 | 
						|
            {/each}
 | 
						|
          </tbody>
 | 
						|
        </table>
 | 
						|
      </div>
 | 
						|
    {/if}
 | 
						|
  {:catch error}
 | 
						|
    <div class="text-white px-6 py-4 border-0 rounded relative mb-4 bg-red-500">
 | 
						|
      <span class="inline-block align-middle mr-8">
 | 
						|
        <b class="capitalize">{$_("general_promise_error")}</b>
 | 
						|
        {error}
 | 
						|
      </span>
 | 
						|
    </div>
 | 
						|
  {/await}
 | 
						|
</section>
 | 
						|
<AddTrackModal bind:modal_open />
 |