refactoring

This commit is contained in:
Clément 2018-09-28 21:20:15 +02:00
parent 874a8c636f
commit 324a5aa347
40 changed files with 1249 additions and 0 deletions

12
.babelrc Normal file
View File

@ -0,0 +1,12 @@
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"browsers": ["last 2 versions", "ie >= 9"]
}
}
]
]
}

8
.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
/node_modules
/www/index.html
/www/styles/
/www/scripts/
/www/lib
!/www/lib/sib-core
!/www/lib/sib-router
!/www/lib/sib-chat

9
.gitmodules vendored Normal file
View File

@ -0,0 +1,9 @@
[submodule "www/lib/sib-core"]
path = www/lib/sib-core
url = git@git.happy-dev.fr:startinblox/sib-core.git
[submodule "www/lib/sib-router"]
path = www/lib/sib-router
url = git@git.happy-dev.fr:startinblox/sib-router.git
[submodule "www/lib/sib-chat"]
path = www/lib/sib-chat
url = git@git.happy-dev.fr:startinblox/sib-chat.git

56
Makefile Normal file
View File

@ -0,0 +1,56 @@
SCRIPT_SRC := $(wildcard src/scripts/*.js)
SCRIPT_DEST := $(SCRIPT_SRC:src/%=www/%)
default: build
clean:
git clean -fXd
install: node_modules copy_lib submodules
submodules:
git submodule init
git submodule update
build: www/index.html www/styles/index.css $(SCRIPT_DEST)
watch:
@echo 'watching for change'
@echo 'press Ctrl+C to stop'
@while true; do \
$(MAKE) --silent build; \
sleep 0.5; \
done
serve:
node server
# npm
node_modules:
npm install
# vendor lib
copy_lib:
@node copy_lib.js
# pug
www/index.html: src/index.pug $(wildcard src/*.pug src/*/*.pug)
@echo pug: $< ➜ $@
@node_modules/.bin/pug --pretty $< --out $(dir $@) || touch $@
# sass
www/styles/index.css: src/styles/index.scss $(wildcard src/*.scss src/*/*.scss)
@echo sass: $< ➜ $@
@node_modules/.bin/node-sass $< $@ --source-map true || touch $@
# babel
www/%.js: src/%.js
@echo babel: $< ➜ $@
@mkdir -p $(dir $@)
@node_modules/.bin/babel $< --out-file $@ --source-maps || touch $@
.PHONY: default install submodules copy_lib build watch serve clean

0
README.md Normal file
View File

20
copy_lib.js Normal file
View File

@ -0,0 +1,20 @@
const { basename, join, resolve } = require('path');
const { readFileSync, lstatSync } = require('fs');
const { exec } = require('child_process');
const distDir = 'www/lib';
const filelist = readFileSync('lib_list.txt', 'utf-8').split(/\r?\n/);
exec(`mkdir -p ${distDir}`, () => {
filelist.forEach(path => {
path = resolve(path);
const filename = basename(path);
const dest = lstatSync(path).isDirectory()
? distDir
: join(distDir, filename);
const cmd = `rsync -ru ${path} ${dest}`;
console.log(cmd);
exec(cmd);
});
});

3
lib_list.txt Normal file
View File

@ -0,0 +1,3 @@
node_modules/normalize.css/normalize.css
node_modules/@webcomponents/webcomponentsjs
node_modules/@webcomponents/html-imports/src/html-imports.js

20
package.json Normal file
View File

@ -0,0 +1,20 @@
{
"name": "hd-app",
"version": "1.0.0",
"license": "ISC",
"devDependencies": {
"@babel/core": "^7.1.0",
"@babel/preset-env": "^7.1.0",
"@babel/cli": "^7.1.0",
"node-sass": "^4.9.3",
"pug-cli": "^1.0.0-alpha6",
"browser-sync": "^2.24.7",
"express": "^4.16.3"
},
"dependencies": {
"@webcomponents/html-imports": "^1.2.0",
"@webcomponents/webcomponentsjs": "^1.2.7",
"normalize.css": "^8.0.0",
"simple-line-icons": "^2.4.1"
}
}

22
server.js Normal file
View File

@ -0,0 +1,22 @@
const port = 9000;
const distPath = 'www';
// express server
const { join } = require('path');
const express = require('express');
const app = express();
app
.use(express.static(distPath))
.use('/src', express.static(join(__dirname, 'src')))
.get(/^[^.]*$/, (req, rep) =>
rep.sendFile(join(__dirname, distPath, '/index.html')),
)
.listen(port);
// browser sync
const bs = require('browser-sync').create();
bs.init({
files: [distPath + '/**/*'],
proxy: `http://localhost:${port}`,
open: false,
notify: false,
//tunnel: true,
});

27
src/dependencies.pug Normal file
View File

@ -0,0 +1,27 @@
// Scripts
script(src="lib/webcomponentsjs/webcomponents-loader.js")
//- script(src="lib/html-imports.js")
//- script(src="https://unpkg.com/@webcomponents/webcomponentsjs@1.2.7/webcomponents-loader.js")
script(src="scripts/index.js")
// Stylesheets
link(rel='stylesheet', href='lib/normalize.css')
link(rel='stylesheet', href="styles/index.css")
link(
rel='stylesheet'
href='https://fonts.googleapis.com/css?family=Open+Sans:400,400i,700,700i&amp;subset=latin-ext'
)
// Web components
//- local
link(rel='import', href='lib/sib-core/sib-display.html')
link(rel='import', href='lib/sib-router/sib-router.html')
//-link(rel='import', href='lib/sib-chat/sib-chat.html')
//- cdn
link(rel='import', href="https://cdn.happy-dev.fr/sib-core/sib-display.html")
link(rel='import', href="https://cdn.happy-dev.fr/sib-router/sib-router.html")
//- link(rel='import', href="https://cdn.happy-dev.fr/sib-chat/sib-chat.html")

36
src/index.pug Normal file
View File

@ -0,0 +1,36 @@
include variables.pug
<!DOCTYPE html>
html(lang="en")
head
meta(charset="UTF-8")
title HD App
meta(name="viewport", content="width=device-width, initial-scale=1.0")
meta(http-equiv="X-UA-Compatible", content="ie=edge")
include dependencies.pug
body
header#header
#logo
img(src="img/logo.png" width=166/2 height=48/2)
#subContainer
include menu.pug
main#mainContainer
//- #dashboard(hidden)
include pages/dashboard.pug
#members(hidden)
include pages/members.pug
#member(hidden)
div include pages/member.pug
#job-offers(hidden)
include pages/job-offers.pug
#projects(hidden)
include pages/projects.pug
#project(hidden)
include pages/project.pug
//- #client-creation(hidden)
include pages/client-creation.pug
#channels(hidden)
include pages/channels.pug
#channel(hidden)
include pages/channel.pug
//- #search(hidden)
include pages/search.pug

27
src/menu.pug Normal file
View File

@ -0,0 +1,27 @@
.btn-toggle
div
nav#navbar
sib-router#navbar-router(default-route='members')
div(hidden)
div#menu-items
sib-route(name='members')
div.icon-people Membres
sib-route(hidden, name='member', id-prefix=`${sdn}/members/`)
sib-route(name='job-offers')
div.icon-briefcase Job offers
div
div.icon-folder-alt Projets
sib-display(
data-src=`${sdn}/projects/`,
data-fields='name',
next='project'
)
sib-route(hidden, name='project', id-prefix=`${sdn}/projects/`)
div
div.icon-bubbles Channels
sib-display(
data-src=`${sdn}/channels/`,
data-fields='name',
next='channel'
)
sib-route(hidden, name='channel', id-prefix=`${sdn}/channels/`)

View File

@ -0,0 +1,2 @@
#channel-chat.chat-view(style='display: none', bind-resources='')
sib-chat(data-authentication='login', data-auto-login='true', data-bosh-service-url='https://jabber.happy-dev.fr/http-bind/', data-debug='false', data-locales-url='en', bind-resources='')

View File

@ -0,0 +1,7 @@
#channel-create(style='display: none')
sib-form(
data-src=`${sdn}/channels/`,
range-owner=`${sdn}/members/`,
widget-members='sib-form-multiple-dropdown',
range-members=`${sdn}/members/`
)

View File

@ -0,0 +1,7 @@
#channel-edit(style='display: none')
sib-form(
range-owner=`${sdn}/members/`,
widget-members='sib-form-multiple-dropdown',
range-members=`${sdn}/members/`,
bind-resources=''
)

View File

@ -0,0 +1,38 @@
script.
document.addEventListener('WebComponentsReady', function(event) {
document.addEventListener("HTMLImportsLoaded", function(event) {
class HDAppMember extends SIBWidget {
get template() {
return `
<div name="${this.name}">
<img src="${this.value.avatar}"/>
</div>
`;
}
render() {
store.get(this.value).then( (value) => {
this._value = value;
this.innerHTML = this.template;
});
}
}
customElements.define("hdapp-member", HDAppMember);
});
});
#channel-profile(style='display: none')
sib-display(
data-fields='name, description, owner',
widget-owner='hdapp-member',
bind-resources=''
)
h2.section.skills Participants
sib-display(
id-suffix='members',
data-fields='avatar, user',
widget-avatar='sib-display-img',
widget-user='hdapp-userinfo',
bind-resources=''
)

15
src/pages/channel.pug Normal file
View File

@ -0,0 +1,15 @@
#channel(style='display: none')
sib-router#channel-router(default-route='channel-profile')
sib-route(name='channel-chat')
div Chat
sib-route(name='channel-profile')
div Info
sib-route(name='channel-edit')
div Éditer
sib-route(name='channel-create')
div Nouveau
#network-views-container
include channel-chat.pug
include channel-profile.pug
include channel-edit.pug
include channel-create.pug

7
src/pages/channels.pug Normal file
View File

@ -0,0 +1,7 @@
#channels(style='display: none')
sib-display#channels-list(
data-src=`${sdn}/channels/`,
data-fields='name, description',
search-fields='name, description',
next='channel'
)

40
src/pages/job-offers.pug Normal file
View File

@ -0,0 +1,40 @@
script.
document.addEventListener('WebComponentsReady', function(event) {
document.addEventListener('HTMLImportsLoaded', function(event) {
class HDAppAuthor extends SIBDisplayLookupList {
get parentElement() {
return 'div';
}
getTemplate(value, index) {
var firstname, lastname;
if (typeof value == 'object')
if (Object.keys(value).length > 1) {
firstname = value.user.first_name;
lastname = value.user.last_name;
} else {
store.get(value).then(resource => {
this.value.push(resource);
this.render();
});
if (Array.isArray(this.value))
this.value.splice(this.value.indexOf(value), 1);
else this.value = [];
return '';
}
return `${firstname} ${lastname}`;
}
}
customElements.define('hdapp-author', HDAppAuthor);
});
});
div
h1 Job offers
sib-display#offers-list(
data-src=`${sdn}/job-offers/`,
data-fields='author, title, description, skills',
set-searchset='title, description',
widget-skills='sib-display-lookuplist',
widget-author='hdapp-author',
search-fields='searchset'
)

View File

@ -0,0 +1,2 @@
#member-chat.chat-view(style='display: none', bind-resources='')
sib-chat(data-authentication='login', data-auto-login='true', data-bosh-service-url='https://jabber.happy-dev.fr/http-bind/', data-debug='false', data-locales-url='en', bind-resources='')

97
src/pages/member-edit.pug Normal file
View File

@ -0,0 +1,97 @@
// script.
class LDPFormImgUpload extends SIBWidget {
get template() {
return `<label for="${this.name}"><img id="${this.name}-preview" src="${this.value}"/></label>
<input id="${this.name}" type="file" name="${this.name}" value="${this.value}" />`;
}
render() {
store.get(this.value).then( (value) => {
this._value = value;
this.innerHTML = this.template;
});
}
}
customElements.define("ldp-form-img-upload", LDPFormImgUpload);
widget-avatar="ldp-form-img-upload"
#member-edit(style='display: none')
label.d-none(for='avatar-input')
img#avatar-preview(src='', style='width: 100%;')
input#avatar-input.d-none(accept='image/*', name='avatar', value='', type='file')
sib-form.edit-form(
data-fields='user, avatar, bio, cell, jabberID, number, pseudo, skills, website',
widget-user='hdapp-usereditinfo',
range-cell=`${sdn}/cells/`, widget-skills='sib-form-multiple-dropdown',
range-skills=`${sdn}/skills/`,
bind-resources=''
)
#crop-modal
.crop-wrapper
img#crop-preview(src='')
.control-bar
button#cancel-img-cropping.btn.btn-link Annuler
i#rotate-img.fa.fa-undo(aria-hidden='true')
button#crop-img.btn.btn-link Valider
//-script.
// Constant declaration
const avatarPreview = document.querySelector("#avatar-preview");
const avatarInput = document.querySelector("#avatar-input");
const cropModal = document.querySelector("#crop-modal");
const cropPreview = cropModal.querySelector("#crop-preview");
const $cropPreview = $(cropPreview);
// Triggers cropping on image upload
avatarInput.addEventListener("change", function(e) {
var img = avatarInput.files[0];
var reader = new FileReader();
reader.onloadend = function () {
cropPreview.src = reader.result;
cropModal.classList.add("cropping-mode");
}
if (img) {
reader.readAsDataURL(img);//reads the data as a URL
}
});
cropPreview.addEventListener("load", () => {
$cropPreview.cropper({
aspectRatio: 1/1,
viewMode: 3,
zoomable: false,
});
});
// Rotate image
cropModal.querySelector("#rotate-img").addEventListener("click", () => {
$cropPreview.cropper("rotate", -90);
});
// Cancel cropping
cropModal.querySelector("#cancel-img-cropping").addEventListener("click", () => {
closeCropping();
});
// Shortcut
document.querySelector("body").addEventListener("keydown", function(e) {
// Escape key
if (e.keyCode == 27 && cropModal.classList.contains("cropping-mode")) {
closeCropping();
}
});
function closeCropping() {
cropModal.classList.remove("cropping-mode");
avatarInput.value = null;
}
// Validating cropping
cropModal.querySelector("#crop-img").addEventListener("click", () => {
avatarPreview.src = $cropPreview.cropper("getCroppedCanvas").toDataURL()
closeCropping();
});

View File

@ -0,0 +1,13 @@
#member-profile(style='display: none')
sib-display#member-info(
data-fields='header, cell, number, roles, website, skills',
set-header='avatar, user, pseudonym, bio'
set-pseudonym='before-pseudo, pseudo'
widget-avatar='sib-display-img',
widget-user='hdapp-userinfo',
widget-cell='hdapp-usercell',
widget-number='sib-display-tel',
widget-roles='sib-display-lookuplist',
widget-skills='sib-display-lookuplist',
bind-resources=''
)

12
src/pages/member.pug Normal file
View File

@ -0,0 +1,12 @@
#member(style='display: none')
sib-router#member-router(default-route='member-profile')
sib-route(name='member-chat')
div Chat
sib-route(name='member-profile')
div Voir
sib-route(name='member-edit')
div Éditer
#member-views-container
include member-chat.pug
include member-profile.pug
include member-edit.pug

1
src/pages/members.pug Normal file
View File

@ -0,0 +1 @@
div member

View File

@ -0,0 +1,2 @@
#project-chat.chat-view(style='display: none', bind-resources='')
sib-chat(data-authentication='login', data-auto-login='true', data-bosh-service-url='https://jabber.happy-dev.fr/http-bind/', data-debug='false', data-locales-url='en', bind-resources='')

View File

@ -0,0 +1,7 @@
#project-create(style='display: none')
sib-form(
data-src=`${sdn}/projects/`,
range-client=`${sdn}/clients/`,
widget-team='sib-form-multiple-dropdown',
range-team=`${sdn}/members/`
)

View File

@ -0,0 +1,7 @@
#project-edit(style='display: none')
sib-form(
range-client=`${sdn}/clients/`,
widget-team='sib-form-multiple-dropdown',
range-team=`${sdn}/members/`,
bind-resources=''
)

View File

@ -0,0 +1,16 @@
#project-profile(style='display: none')
sib-display(
data-fields='title, description, client',
set-title='number, name'
widget-client='hdapp-client',
bind-resources=''
)
h3 Team
sib-display.members-list-condensed(
id-suffix='team',
data-fields='avatar, user',
widget-avatar='sib-display-img',
widget-user='hdapp-userinfo',
next='member',
bind-resources=''
)

15
src/pages/project.pug Normal file
View File

@ -0,0 +1,15 @@
#project(style='display: none')
sib-router#project-router(default-route='project-profile')
sib-route(name='project-chat')
div Chat
sib-route(name='project-profile')
div Voir
sib-route(name='project-edit')
div Éditer
sib-route(name='project-create')
div Nouveau
#project-views-container
include project-chat.pug
include project-profile.pug
include project-edit.pug
include project-create.pug

29
src/pages/projects.pug Normal file
View File

@ -0,0 +1,29 @@
script.
document.addEventListener('WebComponentsReady', function(event) {
document.addEventListener("HTMLImportsLoaded", function(event) {
class HDAppClient extends SIBWidget {
get template() {
return `<img name="${this.name}" src="${this.value.logo}"/>`;
}
render() {
store.get(this.value).then( (value) => {
this._value = value;
this.innerHTML = this.template;
});
}
}
customElements.define("hdapp-client", HDAppClient);
});
});
#projects(style='display: none')
h1 Projects
sib-display(
data-src=`${sdn}/projects/`,
data-fields='number, client, name',
widget-client='hdapp-client',
search-fields='number, name',
next='project'
)

61
src/scripts/hd-app.js Normal file
View File

@ -0,0 +1,61 @@
document.addEventListener("DOMContentLoaded", function(event) {
// Constants declaration
const navBar = document.querySelector("#navbar");
const searchBar = document.querySelector("#search-bar");
const searchView = document.querySelector("#search-view");
const searchInput = searchBar.querySelector("#search-input");
const btnToggle = document.querySelector(".btn-toggle");
// Shortcuts
window.addEventListener("keydown", function(e) {
// CTRL + K triggers the search feature
if ((e.keyCode == 75 || e.keyCode == 80) && (e.ctrlKey === true || e.metaKey === true)) {
e.preventDefault();
e.stopPropagation();
openSearchBar();
}
// Escape key
else if (e.keyCode == 27 && navBar.classList.contains("search-mode")) {
closeSearchBar();
}
});
searchBar.querySelector("#close-search-icon").addEventListener("click", emptySearchBar);
function openSearchBar(e) {
navBar.classList.add("search-mode");
searchBar.querySelector("#search-input").focus();
searchView.classList.add("search-mode");
}
function closeSearchBar(e) {
navBar.classList.remove("search-mode");
searchView.classList.remove("search-mode");
}
function emptySearchBar(e) {
searchInput.value = '';
openSearchBar();
searchInput.focus;
}
// Synchronizes the search input with the <ldp-form>s
searchInput.addEventListener("keyup", (e) => {
searchView.querySelectorAll("ldp-form input[type=text]").forEach((el) => {
el.value = searchInput.value;
});
});
btnToggle.addEventListener('click', e => {
navBar.classList.toggle('open');
e.stopPropagation();
});
window.addEventListener('click', e=>{
navBar.classList.remove('open');
});
});

15
src/scripts/index.js Normal file
View File

@ -0,0 +1,15 @@
document.addEventListener('DOMContentLoaded', function(event) {
// Constants declaration
const navBar = document.querySelector('#navbar');
const btnToggle = document.querySelector('.btn-toggle');
if (!navBar || !btnToggle) return;
btnToggle.addEventListener('click', e => {
navBar.classList.toggle('open');
e.stopPropagation();
});
window.addEventListener('click', e => {
navBar.classList.remove('open');
});
});

View File

264
src/styles/icons.scss Normal file
View File

@ -0,0 +1,264 @@
@font-face {
font-family: 'simple-line-icons';
src: url('../fonts/simple-line-icons.eot?23594131');
src: url('../fonts/simple-line-icons.eot?23594131#iefix')
format('embedded-opentype'),
url('../fonts/simple-line-icons.woff2?23594131') format('woff2'),
url('../fonts/simple-line-icons.woff?23594131') format('woff'),
url('../fonts/simple-line-icons.ttf?23594131') format('truetype'),
url('../fonts/simple-line-icons.svg?23594131#simple-line-icons')
format('svg');
font-weight: normal;
font-style: normal;
}
/* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */
/* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */
/*
@media screen and (-webkit-min-device-pixel-ratio:0) {
@font-face {
font-family: 'simple-line-icons';
src: url('../font/simple-line-icons.svg?23594131#simple-line-icons') format('svg');
}
}
*/
%icon,
[class^='icon-']:before,
[class*=' icon-']:before {
font-family: 'simple-line-icons';
font-style: normal;
font-weight: normal;
speak: none;
display: inline-block;
text-decoration: inherit;
width: 1em;
margin-right: 0.2em;
text-align: center;
/* opacity: .8; */
/* For safety - reset parent styles, that can break glyph codes*/
font-variant: normal;
text-transform: none;
/* fix buttons height, for twitter bootstrap */
line-height: 1em;
/* Animation center compensation - margins should be symmetric */
/* remove if not needed */
margin-left: 0.2em;
/* you can be more comfortable with increased icons size */
/* font-size: 120%; */
/* Font smoothing. That was taken from TWBS */
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
/* Uncomment for 3D effect */
// text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3);
}
$icons: (
user-female: '\e000',
people: '\e001',
user-follow: '\e002',
user-following: '\e003',
user-unfollow: '\e004',
user: '\e005',
trophy: '\e006',
speedometer: '\e007',
social-youtube: '\e008',
social-twitter: '\e009',
social-tumblr: '\e00a',
social-facebook: '\e00b',
social-dropbox: '\e00c',
social-dribbble: '\e00d',
shield: '\e00e',
screen-tablet: '\e00f',
screen-smartphone: '\e010',
screen-desktop: '\e011',
plane: '\e012',
notebook: '\e013',
mustache: '\e014',
mouse: '\e015',
magnet: '\e016',
magic-wand: '\e017',
hourglass: '\e018',
graduation: '\e019',
ghost: '\e01a',
game-controller: '\e01b',
fire: '\e01c',
eyeglass: '\e01d',
envelope-open: '\e01e',
envolope-letter: '\e01f',
energy: '\e020',
emotsmile: '\e021',
disc: '\e022',
cursor-move: '\e023',
crop: '\e024',
credit-card: '\e025',
chemistry: '\e026',
bell: '\e027',
badge: '\e028',
anchor: '\e029',
wallet: '\e02a',
vector: '\e02b',
speech: '\e02c',
puzzle: '\e02d',
printer: '\e02e',
present: '\e02f',
playlist: '\e030',
pin: '\e031',
picture: '\e032',
map: '\e033',
layers: '\e034',
handbag: '\e035',
globe-alt: '\e036',
globe: '\e037',
frame: '\e038',
folder-alt: '\e039',
film: '\e03a',
feed: '\e03b',
earphones-alt: '\e03c',
earphones: '\e03d',
drop: '\e03e',
drawar: '\e03f',
docs: '\e040',
directions: '\e041',
direction: '\e042',
diamond: '\e043',
cup: '\e044',
compass: '\e045',
call-out: '\e046',
call-in: '\e047',
call-end: '\e048',
calculator: '\e049',
bubbles: '\e04a',
briefcase: '\e04b',
book-open: '\e04c',
basket-loaded: '\e04d',
basket: '\e04e',
bag: '\e04f',
action-undo: '\e050',
action-redo: '\e051',
wrench: '\e052',
umbrella: '\e053',
trash: '\e054',
tag: '\e055',
support: '\e056',
size-fullscreen: '\e057',
size-actual: '\e058',
shuffle: '\e059',
share-alt: '\e05a',
share: '\e05b',
rocket: '\e05c',
question: '\e05d',
pie-chart: '\e05e',
pencil: '\e05f',
note: '\e060',
music-tone-alt: '\e061',
music-tone: '\e062',
microphone: '\e063',
loop: '\e064',
logout: '\e065',
login: '\e066',
list: '\e067',
like: '\e068',
home: '\e069',
grid: '\e06a',
graph: '\e06b',
equalizer: '\e06c',
dislike: '\e06d',
cursor: '\e06e',
control-start: '\e06f',
control-rewind: '\e070',
control-play: '\e071',
control-pause: '\e072',
control-forward: '\e073',
control-end: '\e074',
calender: '\e075',
bulb: '\e076',
chart: '\e077',
arrow-up-circle: '\e078',
arrow-right-circle: '\e079',
arrow-left-circle: '\e07a',
arrow-down-circle: '\e07b',
ban: '\e07c',
bubble: '\e07d',
camrecorder: '\e07e',
camera: '\e07f',
check: '\e080',
clock: '\e081',
close: '\e082',
cloud-download: '\e083',
cloud-upload: '\e084',
doc: '\e085',
envolope: '\e086',
eye: '\e087',
flag: '\e088',
folder: '\e089',
heart: '\e08a',
info: '\e08b',
key: '\e08c',
link: '\e08d',
lock: '\e08e',
lock-open: '\e08f',
magnifier: '\e090',
magnifier-add: '\e091',
magnifier-remove: '\e092',
paper-clip: '\e093',
paper-plane: '\e094',
plus: '\e095',
location-pin: '\e096',
power: '\e097',
refresh: '\e098',
reload: '\e099',
settings: '\e09a',
star: '\e09b',
symble-female: '\e09c',
symbol-male: '\e09d',
target: '\e09e',
volume-1: '\e09f',
volume-2: '\e0a0',
volume-off: '\e0a1',
phone: '\e600',
menu: '\e601',
options-vertical: '\e602',
options: '\e603',
arrow-down: '\e604',
arrow-left: '\e605',
arrow-right: '\e606',
arrow-up: '\e607',
paypal: '\e608',
social-instagram: '\e609',
social-linkedin: '\e60a',
social-pintarest: '\e60b',
social-github: '\e60c',
social-google: '\e60d',
social-reddit: '\e60e',
social-skype: '\e60f',
social-behance: '\e610',
social-foursqare: '\e611',
social-soundcloud: '\e612',
social-spotify: '\e613',
social-stumbleupon: '\e614',
minus: '\e615',
organization: '\e616',
exclamation: '\e617',
social-vkontakte: '\e618',
event: '\e619',
social-steam: '\e620',
);
@each $name, $code in $icons {
.icon-#{$name} {
&:before {
content: $code;
}
}
}
@mixin icon($code) {
@extend %icon;
@extend .icon-#{$code};
}

10
src/styles/index.scss Normal file
View File

@ -0,0 +1,10 @@
@charset "UTF-8";
@import
'icons',
'variables',
'functions',
'mixins',
'main';
@import 'menu'

41
src/styles/main.scss Normal file
View File

@ -0,0 +1,41 @@
@import 'variables';
[hidden] {
display: none !important;
}
html {
font-family: Open Sans, sans-serif;
font-size: 13px;
background-color: $color-grey-light;
}
#header {
background-color: $color-white;
position: relative;
@include border-shadow(bottom);
border: solid $color-white;
border-width: 1px 0;
}
#logo {
margin: 1.4em;
}
html,
body {
height: 100%;
}
#subContainer {
display: flex;
min-height: 100%;
}
#mainContainer {
flex: 1 1 0px;
}
h1,h2,h3,h4,h5,h6{
color: $color-black;
}

133
src/styles/menu.scss Normal file
View File

@ -0,0 +1,133 @@
// #navbar{}
// #navbar-router{}
.btn-toggle {
@include icon('menu');
display: none;
position: absolute;
top: 0;
left: 0;
background-color: $color-white;
color: $color-black;
font-size: 2em;
padding: 0.72em;
cursor: pointer;
}
#navbar {
background-color: $color-white;
color: $color-grey;
max-width: 16rem;
position: sticky;
top: 0;
height: 100%;
max-height: 100vh;
&.open {
transform: translateX(0);
}
@include border-shadow(right);
}
@media (max-width: 32rem) {
.btn-toggle {
display: block;
}
#navbar {
transform: translateX(-100%);
transition: transform 0.5s ease;
position: absolute;
top: auto;
z-index: 1;
}
#header {
padding-left: 5rem;
}
}
#menu-items {
> * {
display: block;
border-top: 1px solid $color-grey;
&:last-child {
border-bottom: 1px solid $color-grey;
}
sib-route {
display: block;
cursor: pointer;
}
cursor: pointer;
&[active] {
color: $color-black;
> div:before {
background-color: $color-yellow-light;
transform: perspective(1000px) translateZ(1px) scale(0.8);
}
}
> div {
text-align: center;
text-transform: uppercase;
&:before {
display: block;
margin: -0.5em auto 0;
font-size: 2em;
border-radius: 100%;
padding: 0.7em;
transform: perspective(1000px) translateZ(1px) scale(1);
will-change: transform;
transition:
all .3s ease,
transform .3s cubic-bezier(0.175, 0.885, 0.32, 1.4);
}
width: max-content;
padding: 2em;
}
&[id-prefix] {
display: none;
}
> sib-display {
display: block;
font-size: 0.9em;
color: #aaa;
> div {
margin-bottom: 1.5em;
> sib-display {
cursor: pointer;
display: block;
padding: 0.5em 2em;
}
}
}
}
}
/* sub menu (right menu) */
#mainContainer > div {
display: flex;
flex-direction: row-reverse;
align-items: flex-start;
> sib-router {
display: block;
background-color: #ccc;
sib-route {
display: block;
> div {
position: relative;
padding: 1em 2em;
border-bottom: 1px solid #888;
}
&[active] {
font-weight: bold;
> div:before {
content: '<';
position: absolute;
transform: translateX(-150%);
}
}
}
}
> div {
margin: 0.5em;
flex: 1 1 0px;
}
}

149
src/styles/mixins.scss Normal file
View File

@ -0,0 +1,149 @@
@charset "UTF-8";
@mixin debug {
$hsla: hsla(random(360), 100%, 50%, 0.3);
background-color: $hsla;
}
@mixin log($v) {
font-family: '__log__:#{$v}';
}
@mixin offset($corner: 1, $x: 0, $y: 0) {
// corner:
// 1-----2
// | |
// | |
// 3-----4
position: absolute;
@if ($corner == 1) {
top: $y;
left: $x;
}
@if ($corner == 2) {
top: $y;
right: $x;
}
@if ($corner == 3) {
bottom: $y;
left: $x;
}
@if ($corner == 4) {
bottom: $y;
right: $x;
}
}
@mixin position($top: 0, $right: null, $bottom: null, $left: null) {
// --1--
// | |
// 4 2
// | |
// --3--
@if ($right == null) {
$right: $top;
}
@if ($bottom == null) {
$bottom: $top;
}
@if ($left == null) {
$left: $right;
}
position: absolute;
top: $top;
left: $left;
right: $right;
bottom: $bottom;
}
@mixin pos($pos: 5, $position: absolute) {
//
// 1 2 3
//
//
// 4 5 6
//
//
// 7 8 9
//
$mod: ($pos - 1) % 3;
position: $position;
@if ($pos <= 6) {
top: 0;
}
@if ($mod <= 1) {
left: 0;
}
@if ($mod >= 1) {
right: 0;
}
@if ($pos >= 4) {
bottom: 0;
}
}
@mixin border-shadow($border: top, $size: 4px, $opacity: 0.05, $color: black) {
&:after {
content: '';
position: absolute;
top: if(($border == bottom), auto, 0);
left: if(($border == right), auto, 0);
right: if(($border == left), auto, 0);
bottom: if(($border == top), auto, 0);
background-image: linear-gradient(to #{$border}, $color, transparent);
#{$border}: -$size;
opacity: $opacity;
@if($border == top or $border == bottom) {
height: $size;
}@else{
width: $size;
}
}
}
@mixin align($horizontal: center, $vertical: middle) {
text-align: $horizontal;
white-space: nowrap;
&:after,
> * {
display: inline-block;
vertical-align: $vertical;
}
&:after {
content: '';
height: 100%;
width: 0;
visibility: hidden;
}
> * {
//text-align:left;
white-space: normal;
}
}
@mixin list-reset($deep: 0) {
padding: 0;
margin: 0;
display: block;
list-style: none;
@if ($deep == 0) {
> li {
padding: 0;
margin: 0;
display: block;
list-style: none;
}
} @else {
ul,
ol,
li {
padding: 0;
margin: 0;
display: block;
list-style: none;
}
}
}

17
src/styles/variables.scss Normal file
View File

@ -0,0 +1,17 @@
$color-white: #fff;
$color-black: #36383B;
$color-grey: #898F95;
$color-grey-light: #F0F3F6;
$color-yellow: #FFB700;
$color-yellow-light: #FFD759;
%button{
border-radius: 100em
}
%button-yellow{
@extend %button;
background-color: $color-yellow;
color: $color-white;
}

2
src/variables.pug Normal file
View File

@ -0,0 +1,2 @@
- var sdn = process.env.SDN || 'http://127.0.0.1:8000'
- var cdn = process.env.CDN || 'https://cdn.happy-dev.fr'