diff --git a/.babelrc b/.babelrc
new file mode 100644
index 0000000..5877e72
--- /dev/null
+++ b/.babelrc
@@ -0,0 +1,12 @@
+{
+ "presets": [
+ [
+ "@babel/preset-env",
+ {
+ "targets": {
+ "browsers": ["last 2 versions", "ie >= 9"]
+ }
+ }
+ ]
+ ]
+}
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b3107b3
--- /dev/null
+++ b/.gitignore
@@ -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
\ No newline at end of file
diff --git a/.gitmodules b/.gitmodules
new file mode 100644
index 0000000..99cd617
--- /dev/null
+++ b/.gitmodules
@@ -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
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..ea0ad7f
--- /dev/null
+++ b/Makefile
@@ -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
+
+
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..e69de29
diff --git a/copy_lib.js b/copy_lib.js
new file mode 100644
index 0000000..4cc6932
--- /dev/null
+++ b/copy_lib.js
@@ -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);
+ });
+});
diff --git a/lib_list.txt b/lib_list.txt
new file mode 100644
index 0000000..6127584
--- /dev/null
+++ b/lib_list.txt
@@ -0,0 +1,3 @@
+node_modules/normalize.css/normalize.css
+node_modules/@webcomponents/webcomponentsjs
+node_modules/@webcomponents/html-imports/src/html-imports.js
\ No newline at end of file
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..3cddfa8
--- /dev/null
+++ b/package.json
@@ -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"
+ }
+}
diff --git a/server.js b/server.js
new file mode 100644
index 0000000..7637428
--- /dev/null
+++ b/server.js
@@ -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,
+});
diff --git a/src/dependencies.pug b/src/dependencies.pug
new file mode 100644
index 0000000..f0cbd56
--- /dev/null
+++ b/src/dependencies.pug
@@ -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&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")
diff --git a/src/index.pug b/src/index.pug
new file mode 100644
index 0000000..10d9265
--- /dev/null
+++ b/src/index.pug
@@ -0,0 +1,36 @@
+include variables.pug
+
+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
\ No newline at end of file
diff --git a/src/menu.pug b/src/menu.pug
new file mode 100644
index 0000000..b1613a0
--- /dev/null
+++ b/src/menu.pug
@@ -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/`)
\ No newline at end of file
diff --git a/src/pages/channel-chat.pug b/src/pages/channel-chat.pug
new file mode 100644
index 0000000..2e54d66
--- /dev/null
+++ b/src/pages/channel-chat.pug
@@ -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='')
\ No newline at end of file
diff --git a/src/pages/channel-create.pug b/src/pages/channel-create.pug
new file mode 100644
index 0000000..5e7b303
--- /dev/null
+++ b/src/pages/channel-create.pug
@@ -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/`
+ )
diff --git a/src/pages/channel-edit.pug b/src/pages/channel-edit.pug
new file mode 100644
index 0000000..9244226
--- /dev/null
+++ b/src/pages/channel-edit.pug
@@ -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=''
+ )
diff --git a/src/pages/channel-profile.pug b/src/pages/channel-profile.pug
new file mode 100644
index 0000000..b7dad0b
--- /dev/null
+++ b/src/pages/channel-profile.pug
@@ -0,0 +1,38 @@
+script.
+ document.addEventListener('WebComponentsReady', function(event) {
+ document.addEventListener("HTMLImportsLoaded", function(event) {
+ class HDAppMember extends SIBWidget {
+ get template() {
+ return `
+
+
+
+ `;
+ }
+
+ 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=''
+ )
+
diff --git a/src/pages/channel.pug b/src/pages/channel.pug
new file mode 100644
index 0000000..e91ee19
--- /dev/null
+++ b/src/pages/channel.pug
@@ -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
diff --git a/src/pages/channels.pug b/src/pages/channels.pug
new file mode 100644
index 0000000..70d99f5
--- /dev/null
+++ b/src/pages/channels.pug
@@ -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'
+ )
diff --git a/src/pages/job-offers.pug b/src/pages/job-offers.pug
new file mode 100644
index 0000000..8835bce
--- /dev/null
+++ b/src/pages/job-offers.pug
@@ -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'
+ )
\ No newline at end of file
diff --git a/src/pages/member-chat.pug b/src/pages/member-chat.pug
new file mode 100644
index 0000000..92f71ee
--- /dev/null
+++ b/src/pages/member-chat.pug
@@ -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='')
diff --git a/src/pages/member-edit.pug b/src/pages/member-edit.pug
new file mode 100644
index 0000000..598a586
--- /dev/null
+++ b/src/pages/member-edit.pug
@@ -0,0 +1,97 @@
+// script.
+ class LDPFormImgUpload extends SIBWidget {
+ get template() {
+ return `
+ `;
+ }
+
+ 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();
+ });
diff --git a/src/pages/member-profile.pug b/src/pages/member-profile.pug
new file mode 100644
index 0000000..a8ace40
--- /dev/null
+++ b/src/pages/member-profile.pug
@@ -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=''
+ )
diff --git a/src/pages/member.pug b/src/pages/member.pug
new file mode 100644
index 0000000..d815b25
--- /dev/null
+++ b/src/pages/member.pug
@@ -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
diff --git a/src/pages/members.pug b/src/pages/members.pug
new file mode 100644
index 0000000..27ac9fa
--- /dev/null
+++ b/src/pages/members.pug
@@ -0,0 +1 @@
+div member
\ No newline at end of file
diff --git a/src/pages/project-chat.pug b/src/pages/project-chat.pug
new file mode 100644
index 0000000..e2aebf9
--- /dev/null
+++ b/src/pages/project-chat.pug
@@ -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='')
diff --git a/src/pages/project-create.pug b/src/pages/project-create.pug
new file mode 100644
index 0000000..69a9607
--- /dev/null
+++ b/src/pages/project-create.pug
@@ -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/`
+ )
diff --git a/src/pages/project-edit.pug b/src/pages/project-edit.pug
new file mode 100644
index 0000000..dd6c902
--- /dev/null
+++ b/src/pages/project-edit.pug
@@ -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=''
+ )
diff --git a/src/pages/project-profile.pug b/src/pages/project-profile.pug
new file mode 100644
index 0000000..2ac5023
--- /dev/null
+++ b/src/pages/project-profile.pug
@@ -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=''
+ )
diff --git a/src/pages/project.pug b/src/pages/project.pug
new file mode 100644
index 0000000..3b873d3
--- /dev/null
+++ b/src/pages/project.pug
@@ -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
diff --git a/src/pages/projects.pug b/src/pages/projects.pug
new file mode 100644
index 0000000..ea6fd6d
--- /dev/null
+++ b/src/pages/projects.pug
@@ -0,0 +1,29 @@
+script.
+ document.addEventListener('WebComponentsReady', function(event) {
+ document.addEventListener("HTMLImportsLoaded", function(event) {
+ class HDAppClient extends SIBWidget {
+ get template() {
+
+ return ``;
+ }
+
+ 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'
+ )
diff --git a/src/scripts/hd-app.js b/src/scripts/hd-app.js
new file mode 100644
index 0000000..a38a099
--- /dev/null
+++ b/src/scripts/hd-app.js
@@ -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 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');
+ });
+});
diff --git a/src/scripts/index.js b/src/scripts/index.js
new file mode 100644
index 0000000..482a879
--- /dev/null
+++ b/src/scripts/index.js
@@ -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');
+ });
+});
diff --git a/src/styles/functions.scss b/src/styles/functions.scss
new file mode 100644
index 0000000..e69de29
diff --git a/src/styles/icons.scss b/src/styles/icons.scss
new file mode 100644
index 0000000..434251a
--- /dev/null
+++ b/src/styles/icons.scss
@@ -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};
+}
\ No newline at end of file
diff --git a/src/styles/index.scss b/src/styles/index.scss
new file mode 100644
index 0000000..ebca3ee
--- /dev/null
+++ b/src/styles/index.scss
@@ -0,0 +1,10 @@
+@charset "UTF-8";
+@import
+ 'icons',
+ 'variables',
+ 'functions',
+ 'mixins',
+ 'main';
+
+@import 'menu'
+
diff --git a/src/styles/main.scss b/src/styles/main.scss
new file mode 100644
index 0000000..2ad4686
--- /dev/null
+++ b/src/styles/main.scss
@@ -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;
+}
\ No newline at end of file
diff --git a/src/styles/menu.scss b/src/styles/menu.scss
new file mode 100644
index 0000000..499979f
--- /dev/null
+++ b/src/styles/menu.scss
@@ -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;
+ }
+}
diff --git a/src/styles/mixins.scss b/src/styles/mixins.scss
new file mode 100644
index 0000000..9f2722d
--- /dev/null
+++ b/src/styles/mixins.scss
@@ -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;
+ }
+ }
+}
diff --git a/src/styles/variables.scss b/src/styles/variables.scss
new file mode 100644
index 0000000..ed98ad7
--- /dev/null
+++ b/src/styles/variables.scss
@@ -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;
+}
\ No newline at end of file
diff --git a/src/variables.pug b/src/variables.pug
new file mode 100644
index 0000000..dd28afe
--- /dev/null
+++ b/src/variables.pug
@@ -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'
\ No newline at end of file