<!DOCTYPE html> <html lang="en"> {{ template "head.tpl.html" . }} <script src="assets/js/components/time-picker.js"></script> <script type="module" src="assets/js/components/summary.js"></script> <body class="relative bg-gray-900 text-gray-700 p-4 pt-10 flex flex-col min-h-screen max-w-screen-xl mx-auto"> {{ template "menu-main.tpl.html" . }} {{ template "alerts.tpl.html" . }} {{ template "time-picker.tpl.html" . }} {{ if .User.HasData }} <div id="summary-page" class="grow" v-scope> <div class="flex justify-end md:space-x-8 mt-12 flex-wrap md:flex-nowrap relative items-center"> {{ if $.UserDataExpiring }} <div class="flex-grow justify-start"> <div class="flex-grow p-4 text-sm border-2 border-orange-500 rounded shadow text-gray-300 align-middle mb-4 md:mb-0"> <span class="iconify inline mr-1" data-icon="emojione-v1:warning"></span> Some of your data is older than this instance's data retention period. This will cause old data to be deleted, unless you opt for a subscription. Go to <a class="font-semibold text-green-700" href="settings#subscription">Settings → Subscription</a> for more details. </div> </div> {{ end }} <div class="flex-shrink-0" v-scope="TimePicker({ fromDate: '{{ .From | simpledate }}', toDate: '{{ .To | ceildate | simpledate }}', timeSelection: '{{ .From | datetime }} - {{ .To | ceildate | datetime }}' })" @vue:mounted="mounted"></div> </div> {{ end }} <main class="flex flex-col items-center mt-10 grow"> {{ if .User.HasData }} {{ if not .IsProjectDetails }} <!-- KPIs --> <div class="flex gap-x-6 gap-y-6 w-full mb-4 flex-wrap"> <div class="flex flex-col space-y-2 w-40 p-4 rounded-md p-4 text-gray-300 bg-gray-850 leading-none border-2 border-green-700"> <span class="text-xs text-gray-500 font-semibold">Total Time</span> <span class="font-semibold text-xl truncate" title="{{ .TotalTime | duration }}">{{ .TotalTime | duration }}</span> </div> <div class="flex flex-col space-y-2 w-40 p-4 rounded-md p-4 text-gray-300 bg-gray-850 leading-none border-2 border-green-700"> <span class="text-xs text-gray-500 font-semibold">Total Heartbeats</span> <span class="font-semibold text-xl truncate" title="{{ .NumHeartbeats }}">{{ .NumHeartbeats }}</span> </div> <div class="flex flex-col space-y-2 w-40 p-4 rounded-md p-4 text-gray-300 bg-gray-850 leading-none border-2 border-green-700"> <span class="text-xs text-gray-500 font-semibold">Top Project</span> <span class="font-semibold text-xl truncate" title="{{ .MaxByToString 0 }}">{{ .MaxByToString 0 }}</span> </div> <div class="flex flex-col space-y-2 w-40 p-4 rounded-md p-4 text-gray-300 bg-gray-850 leading-none border-2 border-green-700"> <span class="text-xs text-gray-500 font-semibold">Top Language</span> <span class="font-semibold text-xl truncate" title="{{ .MaxByToString 1 }}">{{ .MaxByToString 1 }}</span> </div> <div class="flex flex-col space-y-2 w-40 p-4 rounded-md p-4 text-gray-300 bg-gray-850 leading-none border-2 border-green-700"> <span class="text-xs text-gray-500 font-semibold">Top OS</span> <span class="font-semibold text-xl truncate" title="{{ .MaxByToString 3 }}">{{ .MaxByToString 3 }}</span> </div> <div class="flex flex-col space-y-2 w-40 p-4 rounded-md p-4 text-gray-300 bg-gray-850 leading-none border-2 border-green-700"> <span class="text-xs text-gray-500 font-semibold">Top Editor</span> <span class="font-semibold text-xl truncate" title="{{ .MaxByToString 2 }}">{{ .MaxByToString 2 }}</span> </div> </div> {{ else }} <div class="mb-8 w-full"> <h1 class="font-semibold text-3xl text-white">Project "{{ .GetProjectFilter }}"</h1> <div class="flex space-x-4 items-center"> <h4 class="font-semibold text-lg text-gray-500">{{ .TotalTime | duration }}</h4> <div v-cloak v-show="currentInterval"> <img :src="'api/badge/{{ .User.ID }}/interval:' + currentInterval + '/project:{{ .GetProjectFilter }}'" alt="Coding Time Badge"> </div> </div> </div> {{ end }} <div class="grid gap-2 grid-cols-1 md:grid-cols-2 w-full mt-4"> <div class="row-span-2 p-4 px-6 pb-10 bg-gray-850 text-gray-300 rounded-md shadow flex flex-col {{ if .IsProjectDetails }} hidden {{ end }}" id="project-container" style="max-height: 608px; max-width: 100vw"> <div class="flex justify-between"> <span class="font-semibold text-lg w-1/2 flex-1 whitespace-nowrap">Projects</span> <div class="flex justify-end flex-1 text-xs items-center"> <input type="number" min="1" id="project-top-picker" data-entity="0" class="top-picker bg-gray-800 rounded-md text-center w-12" value="10"> </div> </div> <canvas id="chart-projects" class="mt-2"></canvas> <div class="hidden placeholder-container flex items-center justify-center h-full flex-col"> <span class="text-md font-semibold text-gray-500 mt-4">No data</span> </div> </div> <div class="row-span-2 p-4 px-6 pb-10 bg-gray-850 text-gray-300 rounded-md shadow flex flex-col {{ if not .IsProjectDetails }} hidden {{ end }}" id="branch-container" style="max-height: 608px; max-width: 100vw"> <div class="flex justify-between"> <span class="font-semibold text-lg w-1/2 flex-1 whitespace-nowrap">Branches</span> <div class="flex justify-end flex-1 text-xs items-center"> <input type="number" min="1" id="branch-top-picker" data-entity="6" class="top-picker bg-gray-800 rounded-md text-center w-12" value="10"> </div> </div> <canvas id="chart-branches" class="mt-2"></canvas> <div class="hidden placeholder-container flex items-center justify-center h-full flex-col"> <span class="text-md font-semibold text-gray-500 mt-4">No data</span> </div> </div> <div class="p-4 px-6 pb-10 bg-gray-850 text-gray-300 rounded-md shadow flex flex-col" id="language-container" style="max-height: 300px"> <div class="flex justify-between"> <span class="font-semibold text-lg w-1/2 flex-1 whitespace-nowrap">Languages</span> <div class="flex justify-end flex-1 text-xs items-center"> <input type="number" min="1" id="language-top-picker" data-entity="3" class="top-picker bg-gray-800 rounded-md text-center w-12" value="10"> </div> </div> <canvas id="chart-language" class="mt-4"></canvas> <div class="hidden placeholder-container flex items-center justify-center h-full flex-col"> <span class="text-md font-semibold text-gray-500 mt-4">No data</span> </div> </div> <div class="p-4 px-6 pb-10 bg-gray-850 text-gray-300 rounded-md shadow flex flex-col" id="editor-container" style="max-height: 300px"> <div class="flex justify-between"> <span class="font-semibold text-lg w-1/2 flex-1 whitespace-nowrap">Editors</span> <div class="flex justify-end flex-1 text-xs items-center"> <input type="number" min="1" id="editor-top-picker" data-entity="2" class="top-picker bg-gray-800 rounded-md text-center w-12" value="10"> </div> </div> <canvas id="chart-editor" class="mt-4"></canvas> <div class="hidden placeholder-container flex items-center justify-center h-full flex-col"> <span class="text-md font-semibold text-gray-500 mt-4">No data</span> </div> </div> <div class="{{ if .IsProjectDetails }} hidden {{ end }}" style="max-width: 100vw;"> <div class="p-4 px-6 pb-10 bg-gray-850 text-gray-300 rounded-md shadow flex flex-col" id="os-container" style="max-height: 300px"> <div class="flex justify-between"> <div> <span class="font-semibold text-lg w-1/2 flex-1 whitespace-nowrap mr-1 cursor-pointer">Operating Systems</span> <span class="font-semibold text-lg w-1/2 flex-1 whitespace-nowrap ml-1 cursor-pointer text-gray-600" onclick="swapCharts('machine', 'os')">Machines</span> </div> <div class="flex justify-end flex-1 text-xs items-center"> <input type="number" min="1" id="os-top-picker" data-entity="1" class="top-picker bg-gray-800 rounded-md text-center w-12" value="10"> </div> </div> <canvas id="chart-os" class="mt-4"></canvas> <div class="hidden placeholder-container flex items-center justify-center h-full flex-col"> <span class="text-md font-semibold text-gray-500 mt-4">No data</span> </div> </div> </div> <div class="hidden" style="max-width: 100vw;"> <div class="p-4 px-6 pb-10 bg-gray-850 text-gray-300 rounded-md shadow flex flex-col" id="machine-container" style="max-height: 300px"> <div class="flex justify-between"> <div> <span class="font-semibold text-lg w-1/2 flex-1 whitespace-nowrap mr-1 cursor-pointer text-gray-600" onclick="swapCharts('os', 'machine')">Operating Systems</span> <span class="font-semibold text-lg w-1/2 flex-1 whitespace-nowrap ml-1 cursor-pointer">Machines</span> </div> <div class="flex justify-end flex-1 text-xs items-center"> <input type="number" min="1" id="machine-top-picker" data-entity="4" class="top-picker bg-gray-800 rounded-md text-center w-12" value="10"> </div> </div> <canvas id="chart-machine" class="mt-4"></canvas> <div class="hidden placeholder-container flex items-center justify-center h-full flex-col"> <span class="text-md font-semibold text-gray-500 mt-4">No data</span> </div> </div> </div> <div style="max-width: 100vw;"> <div class="p-4 px-6 pb-10 bg-gray-850 text-gray-300 rounded-md shadow flex flex-col {{ if .IsProjectDetails }} hidden {{ end }}" id="label-container" style="max-height: 300px"> <div class="flex justify-between text-lg" style="margin-bottom: -10px"> <span class="font-semibold whitespace-nowrap">Labels</span> <a href="settings#data" class="ml-4 inline p-2 hover:bg-gray-800 rounded" style="margin-top: -5px"> <span class="iconify inline" data-icon="twemoji:gear"></span> </a> <div class="flex justify-end flex-1 text-xs items-center"> <input type="number" min="1" id="label-top-picker" data-entity="5" class="top-picker bg-gray-800 rounded-md text-center w-12" value="10"> </div> </div> <canvas id="chart-label" class="mt-4"></canvas> <div class="hidden placeholder-container flex items-center justify-center h-full flex-col"> <span class="text-md font-semibold text-gray-500 mt-4">No data</span> </div> </div> </div> </div> {{ else }} <div class="max-w-screen-sm flex flex-col items-center mt-12 space-y-8 text-gray-300"> <div class="pb-4"> <img src="assets/images/welcome.svg" width="200px" alt="User welcome illustration"> </div> <h1 class="font-semibold text-3xl text-white m-0 w-full">Welcome to Wakapi!</h1> <p> It looks like there is no data available for the specified time range.<br>If you logged in to Wakapi for the first time, see the setup instructions below on how to get started. </p> <div class="w-full pt-10 flex flex-col space-y-4"> <h1 class="font-semibold text-3xl text-white m-0 mb-2">Setup Instructions</h1> <div class="w-full bg-gray-850 text-left rounded-md py-4 px-8 text-xs font-mono shadow-md"> # <strong>Step 1:</strong> Download WakaTime plugin for your IDE<br> # See: https://wakatime.com/plugins<br><br> # <strong>Step 2:</strong> Set your ~/.wakatime.cfg to this:<br><br> <!-- https://github.com/muety/wakapi/issues/224#issuecomment-890855563 --> [settings]<br> api_url = <span class="with-url-inner">%s/api</span><br> api_key = <span id="api-key-instruction">{{ .ApiKey }}</span><br><br> # <strong>Step 3:</strong> Start coding and then check back here! </div> </div> </div> {{ end }} </main> </div> {{ template "footer.tpl.html" . }} {{ template "foot.tpl.html" . }} <script> const editorColors = {{ .EditorColors | json }} const languageColors = {{ .LanguageColors | json }} const osColors = {{ .OSColors | json }} const wakapiData = {} wakapiData.projects = {{ .Projects | json }} wakapiData.operatingSystems = {{ .OperatingSystems | json }} wakapiData.editors = {{ .Editors | json }} wakapiData.languages = {{ .Languages | json }} wakapiData.machines = {{ .Machines | json }} wakapiData.labels = {{ .Labels | json }} {{ if .IsProjectDetails }} wakapiData.branches = {{ .Branches | json }} {{ else }} wakapiData.branches = [] {{ end }} </script> <script src="assets/js/summary.js"></script> </body> </html>