1
0
mirror of https://github.com/muety/wakapi.git synced 2023-08-10 21:12:56 +03:00

refactor(wip): redesign settings page

This commit is contained in:
Ferdinand Mütsch 2021-12-16 12:39:41 +01:00
parent 4e7322c985
commit 7b7fa8bdf3
15 changed files with 695 additions and 654 deletions

View File

@ -6,7 +6,7 @@ import (
var securityHeaders = map[string]string{ var securityHeaders = map[string]string{
"Cross-Origin-Opener-Policy": "same-origin", "Cross-Origin-Opener-Policy": "same-origin",
"Content-Security-Policy": "default-src 'self' 'unsafe-inline'; img-src 'self' https: data:; form-action 'self'; block-all-mixed-content;", "Content-Security-Policy": "default-src 'self' 'unsafe-inline' 'unsafe-eval'; img-src 'self' https: data:; form-action 'self'; block-all-mixed-content;",
"X-Frame-Options": "DENY", "X-Frame-Options": "DENY",
"X-Content-Type-Options": "nosniff", "X-Content-Type-Options": "nosniff",
} }

View File

@ -49,18 +49,6 @@ type SummaryItemContainer struct {
Items []*SummaryItem Items []*SummaryItem
} }
type SummaryViewModel struct {
*Summary
*SummaryParams
User *User
AvatarURL string
LanguageColors map[string]string
Error string
Success string
ApiKey string
RawQuery string
}
type SummaryParams struct { type SummaryParams struct {
From time.Time From time.Time
To time.Time To time.Time

View File

@ -8,6 +8,7 @@ type SettingsViewModel struct {
Aliases []*SettingsVMCombinedAlias Aliases []*SettingsVMCombinedAlias
Labels []*SettingsVMCombinedLabel Labels []*SettingsVMCombinedLabel
Projects []string Projects []string
ApiKey string
Success string Success string
Error string Error string
} }

View File

@ -1,8 +1,17 @@
package view package view
import "github.com/muety/wakapi/models"
type SummaryViewModel struct { type SummaryViewModel struct {
Success string *models.Summary
*models.SummaryParams
User *models.User
AvatarURL string
LanguageColors map[string]string
Error string Error string
Success string
ApiKey string
RawQuery string
} }
func (s *SummaryViewModel) WithSuccess(m string) *SummaryViewModel { func (s *SummaryViewModel) WithSuccess(m string) *SummaryViewModel {

View File

@ -682,6 +682,7 @@ func (h *SettingsHandler) buildViewModel(r *http.Request) *view.SettingsViewMode
Aliases: combinedAliases, Aliases: combinedAliases,
Labels: combinedLabels, Labels: combinedLabels,
Projects: projects, Projects: projects,
ApiKey: user.ApiKey,
Success: r.URL.Query().Get("success"), Success: r.URL.Query().Get("success"),
Error: r.URL.Query().Get("error"), Error: r.URL.Query().Get("error"),
} }

View File

@ -4,7 +4,6 @@ import (
"github.com/gorilla/mux" "github.com/gorilla/mux"
conf "github.com/muety/wakapi/config" conf "github.com/muety/wakapi/config"
"github.com/muety/wakapi/middlewares" "github.com/muety/wakapi/middlewares"
"github.com/muety/wakapi/models"
"github.com/muety/wakapi/models/view" "github.com/muety/wakapi/models/view"
su "github.com/muety/wakapi/routes/utils" su "github.com/muety/wakapi/routes/utils"
"github.com/muety/wakapi/services" "github.com/muety/wakapi/services"
@ -61,7 +60,7 @@ func (h *SummaryHandler) GetIndex(w http.ResponseWriter, r *http.Request) {
return return
} }
vm := models.SummaryViewModel{ vm := view.SummaryViewModel{
Summary: summary, Summary: summary,
SummaryParams: summaryParams, SummaryParams: summaryParams,
User: user, User: user,

View File

@ -20,3 +20,4 @@ Iconify.addCollection({"prefix":"fa-solid","icons":{"external-link-alt":{"body":
Iconify.addCollection({"prefix":"simple-icons","icons":{"wakatime":{"body":"<path d=\"M12 0C5.373 0 0 5.373 0 12s5.373 12 12 12s12-5.373 12-12S18.627 0 12 0zm0 2.824a9.176 9.176 0 1 1 0 18.352a9.176 9.176 0 0 1 0-18.352zm5.097 5.058c-.327 0-.61.19-.764.45c-1.025 1.463-2.21 3.162-3.288 4.706l-.387-.636a.897.897 0 0 0-.759-.439a.901.901 0 0 0-.788.492l-.357.581l-1.992-2.943a.897.897 0 0 0-.761-.446c-.514 0-.903.452-.903.96a1 1 0 0 0 .207.61l2.719 3.96c.152.272.44.47.776.47a.91.91 0 0 0 .787-.483c.046-.071.23-.368.314-.504l.324.52c-.035-.047.076.113.087.13c.024.031.054.059.078.085c.019.019.04.036.058.052c.036.033.08.056.115.08c.025.016.052.028.076.04c.029.015.06.024.088.035c.058.025.122.027.18.04c.031.004.064.003.092.005c.29 0 .546-.149.707-.36c1.4-2 2.842-4.055 4.099-5.849A.995.995 0 0 0 18 8.842c0-.508-.389-.96-.903-.96\" fill=\"currentColor\"/>"}},"width":24,"height":24}); Iconify.addCollection({"prefix":"simple-icons","icons":{"wakatime":{"body":"<path d=\"M12 0C5.373 0 0 5.373 0 12s5.373 12 12 12s12-5.373 12-12S18.627 0 12 0zm0 2.824a9.176 9.176 0 1 1 0 18.352a9.176 9.176 0 0 1 0-18.352zm5.097 5.058c-.327 0-.61.19-.764.45c-1.025 1.463-2.21 3.162-3.288 4.706l-.387-.636a.897.897 0 0 0-.759-.439a.901.901 0 0 0-.788.492l-.357.581l-1.992-2.943a.897.897 0 0 0-.761-.446c-.514 0-.903.452-.903.96a1 1 0 0 0 .207.61l2.719 3.96c.152.272.44.47.776.47a.91.91 0 0 0 .787-.483c.046-.071.23-.368.314-.504l.324.52c-.035-.047.076.113.087.13c.024.031.054.059.078.085c.019.019.04.036.058.052c.036.033.08.056.115.08c.025.016.052.028.076.04c.029.015.06.024.088.035c.058.025.122.027.18.04c.031.004.064.003.092.005c.29 0 .546-.149.707-.36c1.4-2 2.842-4.055 4.099-5.849A.995.995 0 0 0 18 8.842c0-.508-.389-.96-.903-.96\" fill=\"currentColor\"/>"}},"width":24,"height":24});
Iconify.addCollection({"prefix":"heroicons-solid","icons":{"light-bulb":{"body":"<g fill=\"none\"><path d=\"M11 3a1 1 0 1 0-2 0v1a1 1 0 1 0 2 0V3z\" fill=\"currentColor\"/><path d=\"M15.657 5.757a1 1 0 0 0-1.414-1.414l-.707.707a1 1 0 0 0 1.414 1.414l.707-.707z\" fill=\"currentColor\"/><path d=\"M18 10a1 1 0 0 1-1 1h-1a1 1 0 1 1 0-2h1a1 1 0 0 1 1 1z\" fill=\"currentColor\"/><path d=\"M5.05 6.464A1 1 0 1 0 6.464 5.05l-.707-.707a1 1 0 0 0-1.414 1.414l.707.707z\" fill=\"currentColor\"/><path d=\"M5 10a1 1 0 0 1-1 1H3a1 1 0 1 1 0-2h1a1 1 0 0 1 1 1z\" fill=\"currentColor\"/><path d=\"M8 16v-1h4v1a2 2 0 1 1-4 0z\" fill=\"currentColor\"/><path d=\"M12 14c.015-.34.208-.646.477-.859a4 4 0 1 0-4.954 0c.27.213.462.519.476.859h4.002z\" fill=\"currentColor\"/></g>"},"server":{"body":"<g fill=\"none\"><path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M2 5a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v2a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5zm14 1a1 1 0 1 1-2 0a1 1 0 0 1 2 0z\" fill=\"currentColor\"/><path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M2 13a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v2a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-2zm14 1a1 1 0 1 1-2 0a1 1 0 0 1 2 0z\" fill=\"currentColor\"/></g>"}},"width":20,"height":20}); Iconify.addCollection({"prefix":"heroicons-solid","icons":{"light-bulb":{"body":"<g fill=\"none\"><path d=\"M11 3a1 1 0 1 0-2 0v1a1 1 0 1 0 2 0V3z\" fill=\"currentColor\"/><path d=\"M15.657 5.757a1 1 0 0 0-1.414-1.414l-.707.707a1 1 0 0 0 1.414 1.414l.707-.707z\" fill=\"currentColor\"/><path d=\"M18 10a1 1 0 0 1-1 1h-1a1 1 0 1 1 0-2h1a1 1 0 0 1 1 1z\" fill=\"currentColor\"/><path d=\"M5.05 6.464A1 1 0 1 0 6.464 5.05l-.707-.707a1 1 0 0 0-1.414 1.414l.707.707z\" fill=\"currentColor\"/><path d=\"M5 10a1 1 0 0 1-1 1H3a1 1 0 1 1 0-2h1a1 1 0 0 1 1 1z\" fill=\"currentColor\"/><path d=\"M8 16v-1h4v1a2 2 0 1 1-4 0z\" fill=\"currentColor\"/><path d=\"M12 14c.015-.34.208-.646.477-.859a4 4 0 1 0-4.954 0c.27.213.462.519.476.859h4.002z\" fill=\"currentColor\"/></g>"},"server":{"body":"<g fill=\"none\"><path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M2 5a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v2a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5zm14 1a1 1 0 1 1-2 0a1 1 0 0 1 2 0z\" fill=\"currentColor\"/><path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M2 13a2 2 0 0 1 2-2h12a2 2 0 0 1 2 2v2a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2v-2zm14 1a1 1 0 1 1-2 0a1 1 0 0 1 2 0z\" fill=\"currentColor\"/></g>"}},"width":20,"height":20});
Iconify.addCollection({"prefix":"ion","icons":{"rocket":{"body":"<path d=\"M328.85 156.79a26.69 26.69 0 1 0 18.88 7.81a26.6 26.6 0 0 0-18.88-7.81z\" fill=\"currentColor\"/><path d=\"M477.44 50.06a.29.29 0 0 1 0-.09a20.4 20.4 0 0 0-15.13-15.3c-29.8-7.27-76.68.48-128.63 21.28c-52.36 21-101.42 52-134.58 85.22A320.7 320.7 0 0 0 169.55 175c-22.33-1-42 2.18-58.57 9.41c-57.74 25.41-74.23 90.44-78.62 117.14a25 25 0 0 0 27.19 29h.13l64.32-7.02c.08.82.17 1.57.24 2.26a34.36 34.36 0 0 0 9.9 20.72l31.39 31.41a34.27 34.27 0 0 0 20.71 9.91l2.15.23l-7 64.24v.13A25 25 0 0 0 206 480a25.25 25.25 0 0 0 4.15-.34C237 475.34 302 459.05 327.34 401c7.17-16.46 10.34-36.05 9.45-58.34a314.78 314.78 0 0 0 33.95-29.55c33.43-33.26 64.53-81.92 85.31-133.52c20.69-51.36 28.48-98.59 21.39-129.53zM370.38 224.94a58.77 58.77 0 1 1 0-83.07a58.3 58.3 0 0 1 0 83.07z\" fill=\"currentColor\"/><path d=\"M161.93 386.44a16 16 0 0 0-11 2.67c-6.39 4.37-12.81 8.69-19.29 12.9c-13.11 8.52-28.79-6.44-21-20l12.15-21a16 16 0 0 0-15.16-24.91A61.25 61.25 0 0 0 72 353.56c-3.66 3.67-14.79 14.81-20.78 57.26A357.94 357.94 0 0 0 48 447.59A16 16 0 0 0 64 464h.4a359.87 359.87 0 0 0 36.8-3.2c42.47-6 53.61-17.14 57.27-20.8a60.49 60.49 0 0 0 17.39-35.74a16 16 0 0 0-13.93-17.82z\" fill=\"currentColor\"/>"}},"width":512,"height":512}); Iconify.addCollection({"prefix":"ion","icons":{"rocket":{"body":"<path d=\"M328.85 156.79a26.69 26.69 0 1 0 18.88 7.81a26.6 26.6 0 0 0-18.88-7.81z\" fill=\"currentColor\"/><path d=\"M477.44 50.06a.29.29 0 0 1 0-.09a20.4 20.4 0 0 0-15.13-15.3c-29.8-7.27-76.68.48-128.63 21.28c-52.36 21-101.42 52-134.58 85.22A320.7 320.7 0 0 0 169.55 175c-22.33-1-42 2.18-58.57 9.41c-57.74 25.41-74.23 90.44-78.62 117.14a25 25 0 0 0 27.19 29h.13l64.32-7.02c.08.82.17 1.57.24 2.26a34.36 34.36 0 0 0 9.9 20.72l31.39 31.41a34.27 34.27 0 0 0 20.71 9.91l2.15.23l-7 64.24v.13A25 25 0 0 0 206 480a25.25 25.25 0 0 0 4.15-.34C237 475.34 302 459.05 327.34 401c7.17-16.46 10.34-36.05 9.45-58.34a314.78 314.78 0 0 0 33.95-29.55c33.43-33.26 64.53-81.92 85.31-133.52c20.69-51.36 28.48-98.59 21.39-129.53zM370.38 224.94a58.77 58.77 0 1 1 0-83.07a58.3 58.3 0 0 1 0 83.07z\" fill=\"currentColor\"/><path d=\"M161.93 386.44a16 16 0 0 0-11 2.67c-6.39 4.37-12.81 8.69-19.29 12.9c-13.11 8.52-28.79-6.44-21-20l12.15-21a16 16 0 0 0-15.16-24.91A61.25 61.25 0 0 0 72 353.56c-3.66 3.67-14.79 14.81-20.78 57.26A357.94 357.94 0 0 0 48 447.59A16 16 0 0 0 64 464h.4a359.87 359.87 0 0 0 36.8-3.2c42.47-6 53.61-17.14 57.27-20.8a60.49 60.49 0 0 0 17.39-35.74a16 16 0 0 0-13.93-17.82z\" fill=\"currentColor\"/>"}},"width":512,"height":512});
Iconify.addCollection({"prefix":"clarity","icons":{"warning-standard-solid":{"body":"<path class=\"clr-i-solid clr-i-solid-path-1\" d=\"M34.6 29.21L20.71 3.65a3.22 3.22 0 0 0-5.66 0L1.17 29.21A3.22 3.22 0 0 0 4 34h27.77a3.22 3.22 0 0 0 2.83-4.75zM16.6 10a1.4 1.4 0 0 1 2.8 0v12a1.4 1.4 0 0 1-2.8 0zM18 29.85a1.8 1.8 0 1 1 1.8-1.8a1.8 1.8 0 0 1-1.8 1.8z\" fill=\"currentColor\"/>"}},"width":36,"height":36});

File diff suppressed because one or more lines are too long

View File

@ -1,3 +1,4 @@
<script src="assets/app.js"></script>
<script src="assets/vendor/iconify.basic.min.js"></script> <script src="assets/vendor/iconify.basic.min.js"></script>
<script src="assets/vendor/seedrandom.min.js"></script> <script src="assets/vendor/seedrandom.min.js"></script>
<script src="assets/vendor/chart.min.js"></script> <script src="assets/vendor/chart.min.js"></script>

View File

@ -17,4 +17,5 @@
<link href="assets/vendor/tailwind.dist.css" rel="stylesheet"> <link href="assets/vendor/tailwind.dist.css" rel="stylesheet">
{{ end }} {{ end }}
<link href="assets/app.css" rel="stylesheet"> <link href="assets/app.css" rel="stylesheet">
<script src="assets/vendor/petite-vue.min.js" defer></script>
</head> </head>

View File

@ -12,7 +12,7 @@
<main class="mt-10 flex-grow flex justify-center w-full"> <main class="mt-10 flex-grow flex justify-center w-full">
<div class="flex-grow max-w-lg mt-10"> <div class="flex-grow max-w-lg mt-10">
<div class="mb-8"> <div class="mb-8">
<h1 class="font-semibold text-2xl text-white m-0">Welcome!</h1> <h1 class="font-semibold text-3xl text-white m-0">Welcome!</h1>
<span class="text-gray-600">Log in to continue using Wakapi</span> <span class="text-gray-600">Log in to continue using Wakapi</span>
</div> </div>
<form action="login" method="post"> <form action="login" method="post">

View File

@ -3,10 +3,10 @@
{{ template "logo.tpl.html" }} {{ template "logo.tpl.html" }}
</div> </div>
<div class="menu-item flex items-center text-sm font-semibold space-x-2 rounded hover:bg-gray-850 py-2 px-4 cursor-pointer"> <a class="menu-item flex items-center text-sm font-semibold space-x-2 rounded hover:bg-gray-850 py-2 px-4 cursor-pointer" href="summary">
<span class="iconify inline text-2xl text-gray-400" data-icon="ic:round-dashboard"></span> <span class="iconify inline text-2xl text-gray-400" data-icon="ic:round-dashboard"></span>
<a class="text-gray-300" href="summary">Dashboard</a> <span class="text-gray-300">Dashboard</span>
</div> </a>
<div class="menu-item flex items-center text-sm font-semibold space-x-2 rounded hover:bg-gray-850 py-2 px-4 cursor-not-allowed"> <div class="menu-item flex items-center text-sm font-semibold space-x-2 rounded hover:bg-gray-850 py-2 px-4 cursor-not-allowed">
<span class="iconify inline text-2xl text-gray-700" data-icon="bi:people-fill"></span> <span class="iconify inline text-2xl text-gray-700" data-icon="bi:people-fill"></span>
@ -32,7 +32,7 @@
<div class="hidden flex bg-gray-850 shadow-md z-10 p-2 absolute top-0 right-0 rounded popup mt-12 w-full" id="resources-menu-dropdown"> <div class="hidden flex bg-gray-850 shadow-md z-10 p-2 absolute top-0 right-0 rounded popup mt-12 w-full" id="resources-menu-dropdown">
<div class="flex-grow flex flex-col"> <div class="flex-grow flex flex-col">
<div class="submenu-item hover:bg-gray-800 rounded p-1 text-right"> <div class="submenu-item hover:bg-gray-800 rounded p-1 text-right">
<a class="flex justify-between w-full text-gray-300 items-center px-2 font-semibold" href="https://github.com/muety/wakapi" rel="noreferrer noopener" onclick="togglePopup(event, 'resources-menu-dropdown')"> <a class="flex justify-between w-full text-gray-300 items-center px-2 font-semibold" href="https://github.com/muety/wakapi" target="_blank" rel="noreferrer noopener" onclick="togglePopup(event, 'resources-menu-dropdown')">
<span class="text-sm">GitHub</span> <span class="text-sm">GitHub</span>
<span class="iconify inline" data-icon="codicon:github-inverted"></span> <span class="iconify inline" data-icon="codicon:github-inverted"></span>
</a> </a>
@ -44,13 +44,13 @@
</a> </a>
</div> </div>
<div class="submenu-item hover:bg-gray-800 rounded p-1 text-right"> <div class="submenu-item hover:bg-gray-800 rounded p-1 text-right">
<a class="flex justify-between w-full text-gray-300 items-center px-2 font-semibold" href="https://wakatime.com" rel="noreferrer noopener" onclick="togglePopup(event, 'resources-menu-dropdown')"> <a class="flex justify-between w-full text-gray-300 items-center px-2 font-semibold" href="https://wakatime.com" target="_blank" rel="noreferrer noopener" onclick="togglePopup(event, 'resources-menu-dropdown')">
<span class="text-sm">WakaTime</span> <span class="text-sm">WakaTime</span>
<span class="iconify inline" data-icon="simple-icons:wakatime"></span> <span class="iconify inline" data-icon="simple-icons:wakatime"></span>
</a> </a>
</div> </div>
<div class="submenu-item hover:bg-gray-800 rounded p-1 text-right"> <div class="submenu-item hover:bg-gray-800 rounded p-1 text-right">
<a class="flex justify-between w-full text-gray-300 items-center px-2 font-semibold" href="https://github.com/sponsors/muety" rel="noreferrer noopener" onclick="togglePopup(event, 'resources-menu-dropdown')"> <a class="flex justify-between w-full text-gray-300 items-center px-2 font-semibold" href="https://github.com/sponsors/muety" target="_blank" rel="noreferrer noopener" onclick="togglePopup(event, 'resources-menu-dropdown')">
<span class="text-sm">Donate</span> <span class="text-sm">Donate</span>
<span class="iconify inline" data-icon="bx:bxs-heart"></span> <span class="iconify inline" data-icon="bx:bxs-heart"></span>
</a> </a>
@ -59,10 +59,10 @@
</div> </div>
</div> </div>
<div class="menu-item flex items-center text-sm font-semibold space-x-2 rounded hover:bg-gray-850 py-2 px-4 cursor-pointer"> <a class="menu-item flex items-center text-sm font-semibold space-x-2 rounded hover:bg-gray-850 py-2 px-4 cursor-pointer" href="settings">
<span class="iconify inline text-2xl text-gray-400" data-icon="ci:settings-filled"></span> <span class="iconify inline text-2xl text-gray-400" data-icon="ci:settings-filled"></span>
<a class="text-gray-400" href="settings">Settings</a> <span class="text-gray-400">Settings</span>
</div> </a>
<div class="flex-grow"></div> <div class="flex-grow"></div>

View File

@ -4,6 +4,25 @@
{{ template "head.tpl.html" . }} {{ template "head.tpl.html" . }}
<script src="assets/timezones.js"></script> <script src="assets/timezones.js"></script>
<script type="module">
const defaultTab = 'account'
PetiteVue.createApp({
$delimiters: ['${', '}'],
activeTab: defaultTab,
updateTab() {
this.activeTab = window.location.hash.slice(1) || defaultTab
},
isActive(tab) {
return this.activeTab === tab
},
mounted() {
this.updateTab()
window.addEventListener('hashchange', () => this.updateTab())
}
}).mount()
</script>
<body class="bg-gray-900 text-gray-700 p-4 pt-10 flex flex-col min-h-screen max-w-screen-xl mx-auto justify-center"> <body class="bg-gray-900 text-gray-700 p-4 pt-10 flex flex-col min-h-screen max-w-screen-xl mx-auto justify-center">
<style> <style>
@ -20,52 +39,71 @@
} }
</style> </style>
{{ template "header.tpl.html" . }} {{ template "menu-main.tpl.html" . }}
<div class="w-full flex justify-center">
<div class="flex items-center justify-between max-w-2xl flex-grow">
<div><a href="" class="text-gray-500 text-sm cursor-pointer">&larr; Go back</a></div>
<div><h1 class="font-semibold text-2xl text-white m-0 border-b-4 border-green-700">Settings</h1></div>
<div>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div>
</div>
</div>
{{ template "alerts.tpl.html" . }} {{ template "alerts.tpl.html" . }}
<main class="mt-4 flex-grow flex justify-center w-full"> <main class="mt-10 flex-grow flex justify-center w-full" v-scope @vue:mounted="mounted">
<div class="flex flex-col flex-grow max-w-2xl mt-8"> <div class="flex flex-col flex-grow mt-10">
<h1 class="font-semibold text-3xl text-white m-0 mb-4">Settings</h1>
<details class="my-8 pb-8 border-b border-gray-700" id="details-account"> <ul class="flex space-x-4 mb-16 text-gray-600">
<summary class="cursor-pointer"> <li class="font-semibold text-2xl" v-bind:class="{ 'text-gray-300': isActive('account'), 'hover:text-gray-500': !isActive('account') }">
<h2 class="font-semibold text-lg text-white m-0 border-b-2 border-green-700 inline-block" <a href="settings#account" @click="updateTab">Account</a>
id="preferences-heading"> </li>
Account Preferences <li class="font-semibold text-2xl" v-bind:class="{ 'text-gray-300': isActive('data'), 'hover:text-gray-500': !isActive('data') }">
</h2> <a href="settings#data" @click="updateTab">Data</a>
</summary> </li>
<div class="w-full"> <li class="font-semibold text-2xl" v-bind:class="{ 'text-gray-300': isActive('permissions'), 'hover:text-gray-500': !isActive('permissions') }">
<form class="mt-10" action="" method="post"> <a href="settings#permissions" @click="updateTab">Permissions</a>
</li>
<li class="font-semibold text-2xl" v-bind:class="{ 'text-gray-300': isActive('integrations'), 'hover:text-gray-500': !isActive('integrations') }">
<a href="settings#integrations" @click="updateTab">Integrations</a>
</li>
<li class="font-semibold text-2xl" v-bind:class="{ 'text-gray-300': isActive('danger_zone'), 'hover:text-gray-500': !isActive('danger_zone') }">
<a href="settings#danger_zone" @click="updateTab">Danger Zone</a>
</li>
</ul>
<div id="account" class="tab flex flex-col space-y-4" v-if="isActive('account')">
<!-- Account Settings -->
<form action="" method="post" class="w-3/4">
<input type="hidden" name="action" value="update_user"> <input type="hidden" name="action" value="update_user">
<div class="mb-8 flex justify-between items-center space-x-4">
<label class="inline-block text-sm text-gray-500 w-1/3" for="select-timezone">Time Zone</label> <div class="flex mb-8">
<div class="w-1/2 mr-4 inline-block">
<label class="font-semibold text-gray-300" for="select-timezone">Time Zone</label>
<span class="block text-sm text-gray-600">Time Zone, which you are located in. Relevant for displaying daily statistics.</span>
</div>
<div class="w-1/2 ml-4">
<select name="location" id="select-timezone" <select name="location" id="select-timezone"
class="shadow appearance-nonshadow appearance-none bg-gray-800 focus:bg-gray-700 text-gray-300 border-green-700 focus:border-gray-500 border rounded flex-grow py-1 px-3 cursor-pointer"> class="appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded py-2 px-4 w-full cursor-pointer">
</select> </select>
</div> </div>
</div>
<div class="mb-8 flex justify-between items-center space-x-4"> <div class="flex mb-8">
<label class="inline-block text-sm text-gray-500 w-1/3" for="email">E-Mail Address</label> <div class="w-1/2 mr-4 inline-block">
<input class="shadow appearance-none bg-gray-800 focus:bg-gray-700 text-gray-300 border-green-700 focus:border-gray-500 border rounded flex-grow py-1 px-3" <label class="font-semibold text-gray-300" for="email">E-Mail Address</label>
<span class="block text-sm text-gray-600">Optional in general, but required for weekly reports and for resetting your password.</span>
</div>
<div class="w-1/2 ml-4">
<input class="appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded py-2 px-4 w-full"
type="email" id="email" type="email" id="email"
name="email" placeholder="Enter your e-mail address" name="email" placeholder="Enter your e-mail address"
value="{{ .User.Email }}"> value="{{ .User.Email }}">
</div> </div>
</div>
{{ if .User.Email }} {{ if .User.Email }}
<div class="flex items-center w-full text-gray-500 text-sm my-2 w-1/3 space-x-4"> <div class="flex mb-8">
<span class="inline-block text-sm text-gray-500 w-1/3">Weekly E-Mail Reports</span> <div class="w-1/2 mr-4 inline-block">
<div class="justify-start"> <label class="font-semibold text-gray-300" for="reports_weekly">Weekly E-Mail Reports</label>
<span class="block text-sm text-gray-600">Opt in to receive a summary of your coding activity once a week.</span>
</div>
<div class="w-1/2 ml-4">
<select autocomplete="off" name="reports_weekly" <select autocomplete="off" name="reports_weekly"
class="cursor-pointer shadow appearance-nonshadow appearance-none bg-gray-800 focus:bg-gray-700 text-gray-300 border-green-700 focus:border-gray-500 border rounded py-1 px-3"> class="appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded py-2 px-4 w-full cursor-pointer">
<option value="false" class="cursor-pointer" {{ if not .User.ReportsWeekly }} selected{{ end }}>Disabled</option> <option value="false" class="cursor-pointer" {{ if not .User.ReportsWeekly }} selected{{ end }}>Disabled</option>
<option value="true" class="cursor-pointer" {{ if .User.ReportsWeekly }} selected {{ end }}>Enabled</option> <option value="true" class="cursor-pointer" {{ if .User.ReportsWeekly }} selected {{ end }}>Enabled</option>
</select> </select>
@ -73,162 +111,164 @@
</div> </div>
{{ end }} {{ end }}
<div class="text-gray-300 text-sm mt-8">E-Mail address is optional, but required for some features
that you cannot use else. Also, if you do not add an e-mail address, you will not be able to
reset your password in case you forget it.
</div>
<div class="flex justify-end mt-4"> <div class="flex justify-end mt-4">
<button type="submit" <button type="submit" class="py-2 px-4 font-semibold rounded bg-green-700 hover:bg-green-800 text-white text-sm">
class="py-1 px-3 rounded bg-green-700 hover:bg-green-800 text-white text-sm self-end">
Save Save
</button> </button>
</div> </div>
</form> </form>
</div>
</details>
<details class="mb-8 pb-8 border-b border-gray-700" id="details-password"> <div class="w-3/4">
<summary class="cursor-pointer"> <hr class="border-t border-gray-800 my-4">
<h2 class="font-semibold text-lg text-white m-0 border-b-2 border-green-700 inline-block" id="password"> </div>
Change Password
</h2> <!-- Password -->
</summary> <form class="w-3/4" action="" method="post">
<div class="w-full">
<form class="mt-10" action="" method="post">
<input type="hidden" name="action" value="change_password"> <input type="hidden" name="action" value="change_password">
<div class="mb-8">
<label class="inline-block text-sm mb-1 text-gray-500" for="password_old">Current <div class="flex mb-8">
Password</label> <div class="w-1/2 mr-4 inline-block">
<input class="shadow appearance-none bg-gray-800 focus:bg-gray-700 text-gray-300 border-green-700 focus:border-gray-500 border rounded w-full py-1 px-3" <label class="font-semibold text-gray-300" for="password_old">Current Password</label>
<span class="block text-sm text-gray-600">Enter your old password for verification.</span>
</div>
<div class="w-1/2 ml-4">
<input class="appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded py-2 px-4 w-full"
type="password" id="password_old" type="password" id="password_old"
name="password_old" placeholder="Enter your old password" minlength="6" required> name="password_old" placeholder="Old password" minlength="6" required>
</div> </div>
<div class="mb-8"> </div>
<label class="inline-block text-sm mb-1 text-gray-500" for="password_new">New Password</label>
<input class="shadow appearance-none bg-gray-800 focus:bg-gray-700 text-gray-300 border-green-700 focus:border-gray-500 border rounded w-full py-1 px-3" <div class="flex mb-8">
<div class="w-1/2 mr-4 inline-block">
<label class="font-semibold text-gray-300" for="password_new">New Password</label>
<span class="block text-sm text-gray-600">Choose a new password. Preferably, it is at least 8 characters long and contains letters, digits and special chars.</span>
</div>
<div class="w-1/2 ml-4">
<input class="appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded py-2 px-4 w-full"
type="password" id="password_new" type="password" id="password_new"
name="password_new" placeholder="Choose a password" minlength="6" required> name="password_new" placeholder="New password" minlength="6" required>
</div> </div>
<div class="mb-8"> </div>
<label class="inline-block text-sm mb-1 text-gray-500" for="password_repeat">And again
...</label> <div class="flex mb-8">
<input class="shadow appearance-none bg-gray-800 focus:bg-gray-700 text-gray-300 border-green-700 focus:border-gray-500 border rounded w-full py-1 px-3" <div class="w-1/2 mr-4 inline-block">
<label class="font-semibold text-gray-300" for="password_repeat">Repeat Password</label>
<span class="block text-sm text-gray-600">Once again ...</span>
</div>
<div class="w-1/2 ml-4">
<input class="appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded py-2 px-4 w-full"
type="password" id="password_repeat" type="password" id="password_repeat"
name="password_repeat" placeholder="Repeat your password" minlength="6" required> name="password_repeat" placeholder="Repeat your password" minlength="6" required>
</div> </div>
<div class="flex justify-between float-right"> </div>
<button type="submit"
class="py-1 px-3 rounded bg-green-700 hover:bg-green-800 text-white text-sm"> <div class="flex justify-end mt-4">
<button type="submit" class="py-2 px-4 font-semibold rounded bg-green-700 hover:bg-green-800 text-white text-sm">
Save Save
</button> </button>
</div> </div>
</form> </form>
</div> </div>
</details>
<details class="mb-8 pb-8 border-b border-gray-700" id="details-aliases"> <div id="data" class="tab flex flex-col space-y-4" v-if="isActive('data')">
<summary class="cursor-pointer"> <!-- Aliases -->
<h2 class="font-semibold text-lg text-white m-0 border-b-2 border-green-700 inline-block"> <div class="w-full">
Aliases <div class="flex mb-8">
</h2> <div class="w-1/3 mr-4 inline-block">
</summary> <span class="font-semibold text-gray-300 text-lg">Aliases</span>
<div class="w-full" id="aliases"> <p class="block text-sm text-gray-600">You can specify aliases for any type of entity. For instance, you can define a rule, that both "myapp-frontend" and "myapp-backend" are combined under a project called "myapp".</p>
<div class="text-gray-300 text-sm mb-4 mt-6">
You can specify aliases for any type of entity. For instance, you can define a rule, that both <span
class="inline-block mb-1 text-gray-500 italic">myapp-frontend</span> and <span
class="inline-block mb-1 text-gray-500 italic">myapp-backend</span> are combined under a
project called <span class="inline-block mb-1 text-gray-500 italic">myapp</span>.
</div> </div>
<div class="w-2/3 ml-4 inline-block">
{{ if .Aliases }} {{ if .Aliases }}
<h3 class="inline-block font-semibold text-md border-b border-green-700 text-white">Rules</h3> <div class="mb-8">
<h3 class="inline-block font-semibold text-gray-300">Rules</h3>
{{ range $i, $alias := .Aliases }} {{ range $i, $alias := .Aliases }}
<div class="flex items-center"> <div class="flex items-center">
<div class="text-gray-500 border-1 w-full border-green-700 inline-block my-1 py-1 text-align text-sm" <div class="text-gray-300 border-1 w-full inline-block my-1 py-1 text-align text-sm"
style="line-height: 1.8"> style="line-height: 1.8">
&#9656;&nbsp; All <span class="underline">{{ $alias.Type | typeName }}s</span> named &#9656;&nbsp; All <span class="font-semibold">{{ $alias.Type | typeName }}s</span> named
{{ range $j, $value := $alias.Values }} {{ range $j, $value := $alias.Values }}
<span class="text-white text-xs bg-gray-900 rounded py-1 px-2 font-mono">{{- $value -}}</span> <span class="text-white text-sm bg-gray-900 rounded py-1 px-2 font-semibold text-green-700">{{- $value -}}</span>
{{ if lt $j (add (len $alias.Values) -2) }} {{ if lt $j (add (len $alias.Values) -2) }}
<span class="-ml-1">{{- ", " | capitalize -}}</span> <span class="-ml-1">{{- ", " | capitalize -}}</span>
{{ else if lt $j (add (len $alias.Values) -1) }} {{ else if lt $j (add (len $alias.Values) -1) }}
<span>{{- "or" -}}</span> <span>{{- "or" -}}</span>
{{ end }} {{ end }}
{{ end }} {{ end }}
are mapped to <span class="underline">{{ $alias.Type | typeName }}</span> <span are mapped to <span class="font-semibold">{{ $alias.Type | typeName }}</span> <span
class="text-white text-xs bg-gray-900 rounded py-1 px-2 font-mono">{{ $alias.Key }}</span>. class="text-white text-sm bg-gray-900 rounded py-1 px-2 font-semibold text-green-700">{{ $alias.Key }}</span>
</div> </div>
<form class="float-right" action="" method="post"> <form class="float-right" action="" method="post">
<input type="hidden" name="action" value="delete_alias"> <input type="hidden" name="action" value="delete_alias">
<input type="hidden" id="delete_alias_key" name="key" required value="{{ $alias.Key }}"> <input type="hidden" id="delete_alias_key" name="key" required value="{{ $alias.Key }}">
<input type="hidden" id="delete_alias_type" name="type" required value="{{ $alias.Type }}"> <input type="hidden" id="delete_alias_type" name="type" required value="{{ $alias.Type }}">
<button type="submit" <button type="submit" class="py-2 px-4 rounded bg-gray-850 hover:bg-gray-800 text-red-600 text-sm" title="Delete rule"></button>
class="py-1 px-3 rounded border border-red-500 hover:border-red-600 text-gray-400 text-sm">
</button>
</form> </form>
</div> </div>
{{end}} {{end}}
<div class="mb-8"></div> </div>
{{end}} {{end}}
<h3 class="inline-block font-semibold text-md border-b border-green-700 text-white mb-2">Add Rule</h3>
<form action="" method="post"> <form action="" method="post">
<h3 class="inline-block font-semibold text-gray-300">Add Rule</h3>
<input type="hidden" name="action" value="add_alias"> <input type="hidden" name="action" value="add_alias">
<div class="flex items-center mt-2 w-full text-gray-500 text-sm"> <div class="flex items-center mt-2 w-full text-gray-500 text-sm">
<span class="mr-2">Map</span> <span class="mr-2">Map</span>
<select name="type" id="select-type" <select name="type" id="select-type"
class="shadow appearance-nonshadow appearance-none bg-gray-800 focus:bg-gray-700 text-gray-300 border-green-700 focus:border-gray-500 border rounded py-1 px-3 cursor-pointer"> class="appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded py-2 px-4 cursor-pointer">
{{ range $i, $t := entityTypes }} {{ range $i, $t := entityTypes }}
<option value="{{ $t }}">{{ $t | typeName | capitalize }}</option> <option value="{{ $t }}">{{ $t | typeName | capitalize }}</option>
{{ end }} {{ end }}
</select> </select>
<span class="mx-2">named</span> <span class="mx-2">named</span>
<input class="shadow appearance-nonshadow appearance-none bg-gray-800 focus:bg-gray-700 text-gray-300 border-green-700 focus:border-gray-500 border rounded py-1 px-3" <input class="flex-grow appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded py-2 px-4"
type="text" id="alias-value" style="width: 130px;" type="text" id="alias-value" style="width: 130px;"
name="value" placeholder="myapp-frontend" minlength="1" required> name="value" placeholder="Original name" minlength="1" required>
<span class="mx-2">to</span> <span class="mx-2">to</span>
<input class="shadow appearance-nonshadow appearance-none bg-gray-800 focus:bg-gray-700 text-gray-300 border-green-700 focus:border-gray-500 border rounded py-1 px-3" <input class="flex-grow appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded py-2 px-4"
type="text" id="alias-key" style="width: 100px" type="text" id="alias-key" style="width: 100px"
name="key" placeholder="myapp" minlength="1" required> name="key" placeholder="Replacement" minlength="1" required>
<div class="flex-grow flex justify-end"> <div class="flex justify-end ml-4">
<button type="submit" <button type="submit" class="py-2 px-4 font-semibold rounded bg-green-700 hover:bg-green-800 text-white text-sm">
class="py-1 px-3 rounded bg-green-700 hover:bg-green-800 text-white text-sm">
Add Add
</button> </button>
</div> </div>
</div> </div>
</form> </form>
</div> </div>
</details> </div>
<details class="mb-8 pb-8 border-b border-gray-700" id="details-labels">
<summary class="cursor-pointer">
<h2 class="font-semibold text-lg text-white m-0 border-b-2 border-green-700 inline-block">
Project Labels
</h2>
</summary>
<div class="w-full" id="project-labels">
<div class="text-gray-300 text-sm mb-4 mt-6">
You can assign labels (aka. tags) to projects to group them together, e.g. by <span class="inline-block mb-1 text-gray-500 italic">private</span> and <span
class="inline-block mb-1 text-gray-500 italic">work</span>.
</div> </div>
<div class="w-full">
<hr class="border-t border-gray-800 my-4">
</div>
<!-- Project Labels -->
<div class="w-full">
<div class="flex mb-8">
<div class="w-1/3 mr-4 inline-block">
<span class="font-semibold text-gray-300 text-lg">Project Labels</span>
<p class="block text-sm text-gray-600">You can assign labels (aka. tags) to projects to group them together, e.g. by "private" and "work".</p>
</div>
<div class="w-2/3 ml-4 inline-block">
{{ if .Labels }} {{ if .Labels }}
<h3 class="inline-block font-semibold text-md border-b border-green-700 text-white">Labels</h3> <div class="mb-8">
<h3 class="inline-block font-semibold text-gray-300">Labels</h3>
{{ range $i, $label := .Labels }} {{ range $i, $label := .Labels }}
<div class="flex items-center" action="" method="post"> <div class="flex items-center" action="" method="post">
<div class="text-gray-500 border-1 w-full border-green-700 inline-block my-1 py-1 text-align text-sm" <div class="text-gray-500 border-1 w-full border-green-700 inline-block my-1 py-1 text-align text-sm"
style="line-height: 1.8"> style="line-height: 1.8">
&#9656;&nbsp;<span class="font-semibold text-white font-mono">{{ $label.Key }}:</span> &#9656;&nbsp;&nbsp;<span class="font-semibold text-gray-300">{{ $label.Key }}:</span>
{{ range $j, $value := $label.Values }} {{ range $j, $value := $label.Values }}
<form action="" method="post" class="text-white text-xs bg-gray-900 rounded-full py-1 px-2 my-1 inline-flex justify-between items-center space-x-2"> <form action="" method="post" class="text-white text-xs bg-gray-900 rounded-full py-1 px-2 my-1 inline-flex justify-between items-center space-x-2">
<input type="hidden" name="action" value="delete_label"> <input type="hidden" name="action" value="delete_label">
<input type="hidden" name="key" value="{{ $label.Key }}"> <input type="hidden" name="key" value="{{ $label.Key }}">
<input type="hidden" name="value" value="{{ $value }}"> <input type="hidden" name="value" value="{{ $value }}">
<span>{{- $value -}}</span> <span>{{- $value -}}</span>
<button type="submit" class="bg-gray-800 text-center hover:bg-gray-700 rounded-full w-4 h-4 leading-none" title="Delete label">x</button> <button type="submit" class="bg-gray-800 text-center hover:bg-gray-700 rounded-full w-4 h-4 leading-none text-red-600" title="Delete label">x</button>
</form> </form>
{{ if lt $j (add (len $label.Values) -1) }} {{ if lt $j (add (len $label.Values) -1) }}
<span class="-ml-1">{{- ", " | capitalize -}}</span> <span class="-ml-1">{{- ", " | capitalize -}}</span>
@ -238,33 +278,23 @@
</div> </div>
{{end}} {{end}}
<div class="mb-8"></div> <div class="mb-8"></div>
{{end}}
{{ if .Projects }} {{ if .Projects }}
<h3 class="inline-block font-semibold text-md border-b border-green-700 text-white mb-2">Add Label</h3> <h3 class="inline-block font-semibold text-gray-300">Add Label</h3>
<form action="" method="post"> <form action="" method="post">
<input type="hidden" name="action" value="add_label"> <input type="hidden" name="action" value="add_label">
<div class="flex flex-col space-y-4"> <div class="flex flex-col space-y-4">
<div class="flex justify-between items-center mt-2 w-full text-gray-500 text-sm space-x-4"> <div class="flex items-center mt-2 w-full text-gray-500 text-sm space-x-4">
<div class="w-1/2 flex flex-col flex-grow">
<span>Project</span>
<select name="key" id="select-project" <select name="key" id="select-project"
class="shadow appearance-nonshadow appearance-none bg-gray-800 focus:bg-gray-700 text-gray-300 border-green-700 focus:border-gray-500 border rounded py-1 px-3 cursor-pointer"> class="flex-grow appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded py-2 px-4 cursor-pointer">
{{ range $i, $p := .Projects }} {{ range $i, $p := .Projects }}
<option value="{{ $p }}">{{ $p }}</option> <option value="{{ $p }}">{{ $p }}</option>
{{ end }} {{ end }}
</select> </select>
</div> <input class="flex-grow appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded py-2 px-4"
<div class="w-1/2 flex flex-col flex-grow">
<span>Label</span>
<input class="shadow appearance-nonshadow appearance-none bg-gray-800 focus:bg-gray-700 text-gray-300 border-green-700 focus:border-gray-500 border rounded py-1 px-3"
type="text" id="label-value" type="text" id="label-value"
name="value" placeholder="work" minlength="1" required> name="value" placeholder="Label" minlength="1" required>
</div> <button type="submit" class="py-2 px-4 font-semibold rounded bg-green-700 hover:bg-green-800 text-white text-sm">
</div>
<div class="flex-grow flex justify-end">
<button type="submit"
class="py-1 px-3 rounded bg-green-700 hover:bg-green-800 text-white text-sm">
Add Add
</button> </button>
</div> </div>
@ -274,68 +304,72 @@
<div class="text-gray-300 text-sm mb-4 mt-6">You don't have any projects, yet. Start out by sending a few heartbeats before you can then assign labels.</div> <div class="text-gray-300 text-sm mb-4 mt-6">You don't have any projects, yet. Start out by sending a few heartbeats before you can then assign labels.</div>
{{ end }} {{ end }}
</div> </div>
</details> {{end}}
</div>
<details class="mb-8 pb-8 border-b border-gray-700" id="details-mappings"> </div>
<summary class="cursor-pointer">
<h2 class="font-semibold text-lg text-white m-0 border-b-2 border-green-700 inline-block"
id="languages">
Custom Mappings
</h2>
</summary>
<div class="w-full">
<div class="text-gray-300 text-sm mb-4 mt-6">
You can specify custom mapping from file extensions to programming languages, for instance a <span
class="inline-block mb-1 text-gray-500 italic">.jsx</span> file could be mapped to the <span
class="inline-block mb-1 text-gray-500 italic">React</span> language.
</div> </div>
<div class="w-full">
<hr class="border-t border-gray-800 my-4">
</div>
<!-- Language Mappings -->
<div class="w-full">
<div class="flex mb-8">
<div class="w-1/3 mr-4 inline-block">
<span class="font-semibold text-gray-300 text-lg">Language Mappings</span>
<p class="block text-sm text-gray-600">You can specify custom mapping from file extensions to programming languages, for instance a ".jsx" file could be mapped to the "React" language.</p>
</div>
<div class="w-2/3 ml-4 inline-block">
{{ if .LanguageMappings }} {{ if .LanguageMappings }}
<h3 class="inline-block font-semibold text-md border-b border-green-700 text-white">Rules</h3> <div class="mb-8">
<h3 class="inline-block font-semibold text-gray-300">Rules</h3>
{{ range $i, $mapping := .LanguageMappings }} {{ range $i, $mapping := .LanguageMappings }}
<div class="flex items-center"> <div class="flex items-center">
<div class="text-gray-500 border-1 w-full border-green-700 inline-block my-1 py-1 text-align text-sm"> <div class="text-gray-300 border-1 w-full inline-block my-1 py-1 text-align text-sm">
&#9656;&nbsp; When filename ends in <span &#9656;&nbsp; When filename ends in <span
class="text-white text-xs bg-gray-900 rounded py-1 px-2 font-mono mr-1">{{ $mapping.Extension }}</span> class="text-green-700 text-sm bg-gray-900 rounded py-1 px-2 font-semibold mr-1">{{ $mapping.Extension }}</span>
then change the <span class="underline">language</span> to <span then change the <span class="font-semibold">language</span> to <span
class="text-white text-xs bg-gray-900 rounded py-1 px-2 font-mono mr-1">{{ $mapping.Language }}</span> class="text-green-700 text-sm bg-gray-900 rounded py-1 px-2 font-semibold mr-1">{{ $mapping.Language }}</span>
</div> </div>
<form class="float-right" action="" method="post"> <form class="float-right" action="" method="post">
<input type="hidden" name="action" value="delete_mapping"> <input type="hidden" name="action" value="delete_mapping">
<input type="hidden" id="mapping_id" name="mapping_id" required value="{{ $mapping.ID }}"> <input type="hidden" id="mapping_id" name="mapping_id" required value="{{ $mapping.ID }}">
<button type="submit" <button type="submit" class="py-2 px-4 rounded bg-gray-850 hover:bg-gray-800 text-red-600 text-sm" title="Delete rule"></button>
class="py-1 px-3 rounded border border-red-500 hover:border-red-600 text-gray-400 text-sm">
</button>
</form> </form>
</div> </div>
{{end}} {{end}}
<div class="mb-8"></div> </div>
{{end}} {{end}}
<h3 class="inline-block font-semibold text-md border-b border-green-700 text-white">Add Rule</h3>
<form action="" method="post"> <form action="" method="post">
<h3 class="inline-block font-semibold text-gray-300">Add Rule</h3>
<input type="hidden" name="action" value="add_mapping"> <input type="hidden" name="action" value="add_mapping">
<div class="flex items-center w-full text-gray-500 text-sm"> <div class="flex items-center w-full text-gray-500 text-sm">
<span class="mr-2">When filename ends in</span> <span class="mr-2">When filename ends in</span>
<input class="shadow appearance-nonshadow appearance-none bg-gray-800 focus:bg-gray-700 text-gray-300 border-green-700 focus:border-gray-500 border rounded py-1 px-3" <input class="flex-grow appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded py-2 px-4 cursor-pointer"
type="text" id="extension" style="width: 70px" type="text" id="extension" style="width: 70px"
name="extension" placeholder=".py" minlength="1" required> name="extension" placeholder=".py" minlength="1" required>
<span class="mx-2">change language to</span> <span class="mx-2">change language to</span>
<input class="shadow appearance-nonshadow appearance-none bg-gray-800 focus:bg-gray-700 text-gray-300 border-green-700 focus:border-gray-500 border rounded py-1 px-3" <input class="flex-grow appearance-none bg-gray-850 focus:bg-gray-800 text-gray-300 outline-none rounded py-2 px-4 cursor-pointer"
type="text" id="language" style="width: 100px" type="text" id="language" style="width: 100px"
name="language" placeholder="Python" minlength="1" required> name="language" placeholder="Python" minlength="1" required>
<div class="flex-grow flex justify-end"> <div class="flex justify-end ml-4">
<button type="submit" <button type="submit" class="py-2 px-4 font-semibold rounded bg-green-700 hover:bg-green-800 text-white text-sm">
class="py-1 px-3 my-3 rounded bg-green-700 hover:bg-green-800 text-white text-sm">
Add Add
</button> </button>
</div> </div>
</div> </div>
</form> </form>
</div> </div>
</details> </div>
</div>
</div>
<div id="permissions" class="tab flex flex-col space-y-4" v-if="isActive('permissions')">
<!-- TODO -->
<details class="mb-8 pb-8 border-b border-gray-700" id="details-public-data"> <details class="mb-8 pb-8 border-b border-gray-700" id="details-public-data">
<summary class="cursor-pointer"> <summary class="cursor-pointer">
<h2 class="font-semibold text-lg text-white m-0 border-b-2 border-green-700 inline-block"> <h2 class="font-semibold text-lg text-white m-0 border-b-2 border-green-700 inline-block">
@ -460,7 +494,10 @@
</form> </form>
</div> </div>
</details> </details>
</div>
<div id="integrations" class="tab flex flex-col space-y-4" v-if="isActive('integrations')">
<!-- TODO -->
<details class="mb-8 pb-8 border-b border-gray-700" id="details-integrations"> <details class="mb-8 pb-8 border-b border-gray-700" id="details-integrations">
<summary class="cursor-pointer"> <summary class="cursor-pointer">
<h2 class="font-semibold text-lg text-white m-0 border-b-2 border-green-700 inline-block" <h2 class="font-semibold text-lg text-white m-0 border-b-2 border-green-700 inline-block"
@ -617,7 +654,10 @@
</div> </div>
</div> </div>
</details> </details>
</div>
<div id="danger_zone" class="tab flex flex-col space-y-4" v-if="isActive('danger_zone')">
<!-- TODO -->
<details class="mb-8 pb-8" id="details-danger-zone"> <details class="mb-8 pb-8" id="details-danger-zone">
<summary class="cursor-pointer"> <summary class="cursor-pointer">
<h2 class="font-semibold text-lg text-white m-0 border-b-2 border-green-700 inline-block" id="danger"> <h2 class="font-semibold text-lg text-white m-0 border-b-2 border-green-700 inline-block" id="danger">
@ -704,6 +744,7 @@
</div> </div>
</details> </details>
</div> </div>
</div>
</main> </main>
<script type="text/javascript"> <script type="text/javascript">

View File

@ -12,7 +12,7 @@
<main class="mt-10 flex-grow flex justify-center w-full"> <main class="mt-10 flex-grow flex justify-center w-full">
<div class="flex-grow max-w-lg mt-10"> <div class="flex-grow max-w-lg mt-10">
<div class="mb-8"> <div class="mb-8">
<h1 class="font-semibold text-2xl text-white m-0 mb-2">Sign up to Wakapi</h1> <h1 class="font-semibold text-3xl text-white m-0 mb-2">Sign up to Wakapi</h1>
<p class="text-sm text-gray-600"> <p class="text-sm text-gray-600">
Welcome to Wakapi! Your first step is to create an account. Welcome to Wakapi! Your first step is to create an account.
Afterwards, make sure to set up the <a href="https://wakatime.com" target="_blank" rel="noopener noreferrer" class="text-gray-300 hover:text-gray-400">WakaTime</a> client tools. Afterwards, make sure to set up the <a href="https://wakatime.com" target="_blank" rel="noopener noreferrer" class="text-gray-300 hover:text-gray-400">WakaTime</a> client tools.

View File

@ -7,6 +7,8 @@
{{ template "menu-main.tpl.html" . }} {{ template "menu-main.tpl.html" . }}
{{ template "alerts.tpl.html" . }}
{{ if .User.HasData }} {{ if .User.HasData }}
<div class="flex justify-end mt-12 relative"> <div class="flex justify-end mt-12 relative">
@ -46,8 +48,6 @@
{{ end }} {{ end }}
{{ template "alerts.tpl.html" . }}
<main class="flex flex-col items-center mt-10 flex-grow"> <main class="flex flex-col items-center mt-10 flex-grow">
{{ if .User.HasData }} {{ if .User.HasData }}
@ -161,7 +161,7 @@
<div class="p-4 px-6 pb-10 bg-gray-850 text-gray-300 rounded-md shadow flex flex-col" id="label-container" style="height: 300px"> <div class="p-4 px-6 pb-10 bg-gray-850 text-gray-300 rounded-md shadow flex flex-col" id="label-container" style="height: 300px">
<div class="flex justify-between text-lg"> <div class="flex justify-between text-lg">
<span class="font-semibold whitespace-no-wrap">Labels</span> <span class="font-semibold whitespace-no-wrap">Labels</span>
<a href="settings#details-labels" class="ml-4 h-8 inline flex-grow"> <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> <span class="iconify inline" data-icon="twemoji:gear"></span>
</a> </a>
<div class="flex justify-end flex-1 text-xs items-center"> <div class="flex justify-end flex-1 text-xs items-center">
@ -182,12 +182,12 @@
<div class="pb-4"> <div class="pb-4">
<img src="assets/images/welcome.svg" width="200px" alt="User welcome illustration"> <img src="assets/images/welcome.svg" width="200px" alt="User welcome illustration">
</div> </div>
<h1 class="font-semibold text-2xl text-white m-0 w-full">Welcome to Wakapi!</h1> <h1 class="font-semibold text-3xl text-white m-0 w-full">Welcome to Wakapi!</h1>
<p> <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. 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> </p>
<div class="w-full pt-10 flex flex-col space-y-4"> <div class="w-full pt-10 flex flex-col space-y-4">
<h1 class="font-semibold text-2xl text-white m-0 mb-2">Setup Instructions</h1> <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"> <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> # <strong>Step 1:</strong> Download WakaTime plugin for your IDE<br>
# See: https://wakatime.com/plugins<br><br> # See: https://wakatime.com/plugins<br><br>
@ -238,8 +238,6 @@
} }
</script> </script>
<script src="assets/app.js"></script>
</body> </body>
</html> </html>