Sweet dashboard for self-hosted services has just arrived

This commit is contained in:
Daniel 2023-01-13 22:59:03 +01:00
commit 635689e7fb
15 changed files with 412 additions and 0 deletions

240
css/main.css Normal file
View File

@ -0,0 +1,240 @@
@font-face {
font-family: 'Material Symbols Rounded';
font-style: normal;
font-weight: 500;
src: url(../font/MaterialSymbolsRounded.woff2) format('woff2');
}
body {
background: #DDD;
color: #222;
margin: 0;
font-family: Quicksand;
font-weight: bold;
user-select: none;
font-size: 14px;
-webkit-tap-highlight-color: transparent;
}
::-webkit-scrollbar {
display: none;
}
a {
color: #44F;
}
.icon {
font-family: 'Material Symbols Rounded';
font-weight: normal;
font-style: normal;
font-size: 24px;
line-height: 1;
letter-spacing: normal;
text-transform: none;
display: inline-block;
white-space: nowrap;
word-wrap: normal;
direction: ltr;
-webkit-font-feature-settings: 'liga';
-webkit-font-smoothing: antialiased;
}
.background, #background {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
object-fit: cover;
transition: all .45s;
}
#background.scaled {
transform: scale(1.14);
}
.unloaded {
opacity: 0;
}
.main {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
}
.appicon {
width: 192px;
height: 192px;
object-fit: cover;
}
.page {
position: fixed;
top: 0;
left: 50%;
width: 100%;
max-width: 920px;
height: 100vh;
transform: translateX(-50%);
overflow-y: scroll;
transition: all .4s;
}
.home.page {
top: 50%;
left: 50%;
width: 100%;
height: auto;
overflow: hidden;
transform: translate(-50%, -50%);
}
.page.hidden {
top: 320px;
visibility: hidden;
opacity: 0;
}
.home.page.hidden {
top: calc(50% - 72px);
}
.wrapper {
box-shadow: 2px 2px 8px #0003;
background: #FFF8;
padding: 3px;
backdrop-filter: blur(16px);
border-radius: 24px;
margin: -4px 12px 16px;
text-align: center;
overflow: hidden;
min-width: 340px;
}
.home .wrapper {
box-shadow: none;
background: #FFF0;
backdrop-filter: none;
}
.appname {
font-size: 48px;
}
.appdesc {
opacity: .7;
margin: 2px 12px;
}
.appname.about {
font-size: 36px;
}
.buttons {
box-shadow: 2px 2px 8px #0002;
display: flex;
margin: 16px auto 0;
backdrop-filter: blur(16px);
border-radius: 24px;
max-width: 480px;
background: #FFF8;
padding: 2px;
justify-content: space-between;
}
.buttons > div {
padding: 16px;
margin: 2px;
cursor: pointer;
border-radius: 20px;
width: calc(100% / 2);
transition: all .2s;
}
.buttons > div:hover {
background: #0001;
}
.buttons .text {
margin-top: -2px;
}
.back {
box-shadow: 2px 2px 8px #0002;
position: relative;
width: 64px;
height: 64px;
border-radius: 24px;
background: #FFF8;
margin: 20px;
backdrop-filter: blur(16px);
}
.back .icon {
margin: 4px;
width: 56px;
height: 56px;
cursor: pointer;
border-radius: 20px;
transition: all .2s;
}
.back .icon:hover {
background: #0001;
}
.back .icon:after {
content: "chevron_left";
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
.boxes {
display: flex;
flex: 1 1 0;
flex-wrap: wrap;
}
.static {
margin: 24px 6px 16px;
}
.static .box:hover {
background: transparent;
}
.box {
min-width: 292px;
flex: 1;
margin: 2px;
border-radius: 20px;
padding: 8px;
display: flex;
align-items: center;
text-align: left;
text-decoration: none;
color: inherit;
transition: all .2s;
}
.box:hover {
background: #0001;
}
.box .icon {
font-size: 24px;
padding: 20px;
background: hsl(var(--color), 100%, 90%);
color: hsl(var(--color), 100%, 35%);
border-radius: 100px;
margin: 2px 12px 2px 2px;
}
a.box {
cursor: pointer;
padding: 14px;
}
.box img {
width: 64px;
height: 64px;
object-fit: cover;
margin-right: 12px;
}
.box .name {
font-size: 18px;
}
.box .desc {
opacity: .65;
}
.header {
display: flex;
align-items: center;
margin: 20px 20px 16px;
}
.header .icon {
margin-top: 1px;
margin-right: 10px;
}
.header .text {
font-size: 26px;
}

Binary file not shown.

BIN
img/appicon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
img/background.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 KiB

BIN
img/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
img/preview/caldav.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

BIN
img/preview/files.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.7 KiB

BIN
img/preview/gallery.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
img/preview/git.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

BIN
img/preview/mail.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
img/preview/music.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

BIN
img/preview/notes.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

141
index.html Normal file
View File

@ -0,0 +1,141 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<title>honey</title>
<link rel="icon" href="img/icon.png">
<link rel="stylesheet" type="text/css" href="css/main.css">
<script type="text/javascript" src="js/dom.js"></script>
<script type="text/javascript" src="js/main.js"></script>
</head>
<body onload="onload()">
<div class="background">
<img src="img/background.jpg" id="background" class="unloaded" onload="load_img(this)">
</div>
<div class="main">
<div class="page home hidden" id="page-home">
<div class="wrapper">
<div class="home">
<img src="img/icon.png" class="appicon">
<div class="appname">honey</div>
<div class="appdesc">Nice and sweet place for all your self-hosted services.</div>
</div>
<div class="buttons">
<div onclick="show('page-services')">
<div class="icon">apps</div>
<div class="text">Services</div>
</div>
<div onclick="show('page-about')">
<div class="icon">info</div>
<div class="text">About</div>
</div>
</div>
</div>
</div>
<div class="page hidden" id="page-services">
<div class="back"><div class="icon"></div></div>
<div class="wrapper">
<div class="header">
<div class="icon">apps</div>
<div class="text">Services</div>
</div>
<div class="boxes">
<a class="box" href="caldav">
<img src="img/preview/caldav.png">
<div>
<div class="name">CalDav</div>
<div class="desc">Simple CalDav server for calendar sync between various devices.</div>
</div>
</a>
<a class="box" href="files">
<img src="img/preview/files.png">
<div>
<div class="name">Files</div>
<div class="desc">Fancy file manager for the web.</div>
</div>
</a>
<a class="box" href="gallery">
<img src="img/preview/gallery.png">
<div>
<div class="name">Gallery</div>
<div class="desc">Photo & video gallery syncable with multiple Android devices.</div>
</div>
</a>
<a class="box" href="git">
<img src="img/preview/git.png">
<div>
<div class="name">Git</div>
<div class="desc">Self-hosted, painless, secure place for your repositories.</div>
</div>
</a>
<a class="box" href="mail">
<img src="img/preview/mail.png">
<div>
<div class="name">E-Mail</div>
<div class="desc">Feature-rich, decentralized and secure E-Mail server.</div>
</div>
</a>
<a class="box" href="music">
<img src="img/preview/music.png">
<div>
<div class="name">Music</div>
<div class="desc">Beautiful, moody music streaming app.</div>
</div>
</a>
<a class="box" href="notes">
<img src="img/preview/notes.png">
<div>
<div class="name">Notes</div>
<div class="desc">Sweet & lightweight app for taking notes.</div>
</div>
</a>
</div>
</div>
</div>
<div class="page hidden" id="page-about">
<div class="back"><div class="icon"></div></div>
<div class="wrapper">
<div class="header">
<div class="icon">info</div>
<div class="text">About</div>
</div>
<img src="img/appicon.png" class="appicon">
<div class="appname about">honey</div>
<div class="appdesc">Nice and sweet place for all your self-hosted services.</div>
<div class="appdesc">Source: <a href="https://gitlab.com/dani3l0/honey" target="_blank">gitlab.com/dani3l0/honey</a></div>
<div class="boxes static">
<div class="box">
<div class="icon" style="--color: 0deg">code</div>
<div>
<div class="name">Open Source</div>
<div class="desc">Code is publicly available. Download, modify, collaborate, whatever.</div>
</div>
</div>
<div class="box">
<div class="icon" style="--color: 144deg">mop</div>
<div>
<div class="name">Simple & Clean</div>
<div class="desc">Interface is meant to be uncomplicated and pleasant in sight.</div>
</div>
</div>
<div class="box">
<div class="icon" style="--color: 240deg">language</div>
<div>
<div class="name">Static</div>
<div class="desc">Requires no dynamic backend as it's built with plain HTML/CSS/JS.</div>
</div>
</div>
<div class="box">
<div class="icon" style="--color: 36deg">auto_awesome</div>
<div>
<div class="name">Responsive</div>
<div class="desc">Layout is automatically adjusted depending on device you are using.</div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>

12
js/dom.js Normal file
View File

@ -0,0 +1,12 @@
function get(id) {
return document.getElementById(id);
}
function for_all(class_name, func) {
let a = document.getElementsByClassName(class_name);
for (let i = 0; i < a.length; i++) {
func(a[i]);
}
}
function load_img(img) {
img.classList.remove("unloaded");
}

19
js/main.js Normal file
View File

@ -0,0 +1,19 @@
function onload() {
for_all("back", (btn) => {
btn.onclick = back;
});
back();
}
function show(id) {
for_all("page", (page) => {
page.classList.add("hidden");
});
get(id).classList.remove("hidden");
get(id).scrollTop = 0;
get("background").classList.remove("scaled");
}
function back() {
show("page-home");
get("background").classList.add("scaled");
}