# Conflicts:
#	LICENSE
#	app/config/routing.yml
#	app/config/security.yml
#	assets/js/parts/main.js
This commit is contained in:
tykayn 2019-07-04 14:35:00 +02:00
commit f591d2a081
97 changed files with 73321 additions and 2530 deletions

16
.gitlab-ci.yml Executable file
View File

@ -0,0 +1,16 @@
code_quality:
image: docker:stable
variables:
DOCKER_DRIVER: overlay2
allow_failure: true
services:
- docker:stable-dind
script:
- export SP_VERSION=$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/')
- docker run
--env SOURCE_CODE="$PWD"
--volume "$PWD":/code
--volume /var/run/docker.sock:/var/run/docker.sock
"registry.gitlab.com/gitlab-org/security-products/codequality:$SP_VERSION" /code
artifacts:
paths: [gl-code-quality-report.json]

4
.gitmodules vendored
View File

@ -1,3 +1,3 @@
[submodule "caisse-bliss-frontend"] [submodule "caisse-bliss-frontend"]
path = web/caisse-bliss-frontend path = caisse-bliss-frontend
url = https://gitlab.com/tykayn1/caisse-bliss-frontend url = https://framagit.org/tykayn/caisse-bliss-frontend.git

View File

@ -629,8 +629,8 @@ to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found. the "copyright" line and a pointer to where the full notice is found.
fanzine-log caisse-bliss
Copyright (C) 2018 Kayn Ty Copyright (C) 2018 ty kayn
This program is free software: you can redistribute it and/or modify This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published it under the terms of the GNU Affero General Public License as published

View File

@ -1,32 +1,48 @@
Blueprint Cipherbliss
![alt text][logo]
Caisse | Cipher Bliss
==== ====
Self hosted mobile and desktop Cash register and money management for your small business. Made after years of experience in the art of selling home made books and drawings during events like Japan Expo.
![alt_text][screenshot_home]
A Symfony project created on March 23, 2018, 2:09 pm. A Symfony project created on March 23, 2018.
Features: ## Features:
bootstrap, font awesome, user bundle * live selling and stock update on phone and desktop
* multi user registration
* managing products, categories
* forecast of expenses
* events
* statistics about earnings
* history of client purchases
* import and export your products and selling history
* have a look at where your expenses go during selling events
* all in a libre software in PHP/JS
install dependencies: ---
```bash ## [Install](/docs/installation.md)
bash install.sh Have a look at the [Docs to install](/docs/installation.md) your own Caisse. All documentation is in the "docs" folder.
``` Made By Tykayn/CipherBliss under [AGPL Licence](LICENSE).
edit parameters.yml to link to your mysql server ## News
Ipublish news about this app here:
https://www.cipherbliss.com
update schema with doctrine So here is a tag: https://www.cipherbliss.com/tag/caisse/
```bash
php bin/console doctrine:schema:update --dump-sql
php bin/console doctrine:schema:update --force
```
compile front end assets
```bash
yarn run encore dev --watch
```
access the front with your browser You can follow the website with RSS/atom feeds.
```bash https://www.cipherbliss.com/feed/
php bin/console server:run
firefox http://http://127.0.0.1:8000/
```
enjoy!
www.cipherbliss.com
## Where to find help
Join the discussion at the Matrix Channel of CipherBliss:
[#cipherbliss:matrix.org](https://matrix.to/#/!jfoYESqTObXYlKAOVM:matrix.org?via=matrix.org)
Or contact the Author:
[Contact Choices here](https://www.cipherbliss.com/contact)
[logo]: https://www.cipherbliss.com/wp-content/uploads/2016/12/rond.png "Logo of CipherBliss company"
[screenshot_home]: https://www.cipherbliss.com/wp-content/uploads/2018/09/caisse_bliss_descritpion_open_source_cipherbliss-1260x709.png "Screenshot of Caisse Bliss"
Hosted on Framagit.org
https://framagit.org/tykayn/caisse-bliss.git

View File

@ -1,4 +1,4 @@
{% trans_default_domain 'FOSUserBundle' %}
{{ form_start(form, { 'action': path('fos_user_change_password'), 'attr': { 'class': 'fos_user_change_password' } }) }} {{ form_start(form, { 'action': path('fos_user_change_password'), 'attr': { 'class': 'fos_user_change_password' } }) }}
{{ form_widget(form) }} {{ form_widget(form) }}

View File

@ -1,6 +1,5 @@
{% extends "@FOSUser/layout.html.twig" %} {% extends "@FOSUser/layout.html.twig" %}
{% trans_default_domain 'FOSUserBundle' %}
{% block fos_user_content %} {% block fos_user_content %}
<p>{{ 'registration.check_email'|trans({'%email%': user.email}) }}</p> <p>{{ 'registration.check_email'|trans({'%email%': user.email}) }}</p>

View File

@ -1,6 +1,5 @@
{% extends "@FOSUser/layout.html.twig" %} {% extends "@FOSUser/layout.html.twig" %}
{% trans_default_domain 'FOSUserBundle' %}
{% block fos_user_content %} {% block fos_user_content %}
<p>{{ 'registration.confirmed'|trans({'%username%': user.username}) }}</p> <p>{{ 'registration.confirmed'|trans({'%username%': user.username}) }}</p>

View File

@ -1,4 +1,3 @@
{% trans_default_domain 'FOSUserBundle' %}
{% block subject %} {% block subject %}
{%- autoescape false -%} {%- autoescape false -%}
{{ 'registration.email.subject'|trans({'%username%': user.username, '%confirmationUrl%': confirmationUrl}) }} {{ 'registration.email.subject'|trans({'%username%': user.username, '%confirmationUrl%': confirmationUrl}) }}

View File

@ -1,4 +1,3 @@
{% trans_default_domain 'FOSUserBundle' %}
{{ form_start(form, {'method': 'post', 'action': path('fos_user_registration_register'), 'attr': {'class': 'fos_user_registration_register'}}) }} {{ form_start(form, {'method': 'post', 'action': path('fos_user_registration_register'), 'attr': {'class': 'fos_user_registration_register'}}) }}
{{ form_widget(form) }} {{ form_widget(form) }}

View File

@ -1,5 +1,4 @@
{% extends "@FOSUser/layout.html.twig" %} {% extends "@FOSUser/layout.html.twig" %}
{% trans_default_domain 'FOSUserBundle' %}
{% block fos_user_content %} {% block fos_user_content %}
<div class="row"> <div class="row">
<div class="col-xs-6"> <div class="col-xs-6">

View File

@ -1,5 +1,4 @@
{% extends "@FOSUser/layout.html.twig" %} {% extends "@FOSUser/layout.html.twig" %}
{% trans_default_domain 'FOSUserBundle' %}
{% block fos_user_content %} {% block fos_user_content %}
<div class="row"> <div class="row">
<div class="col-xs-12 col-sm-6"> <div class="col-xs-12 col-sm-6">
@ -9,37 +8,6 @@
<i class="fa fa-key"></i> <i class="fa fa-key"></i>
Se connecter Se connecter
</h1> </h1>
{% if error %}
<div class="alert alert-info">{{ error.messageKey|trans(error.messageData, 'security') }}</div>
{% endif %}
<form action="{{ path("fos_user_security_check") }}" method="post">
{% if csrf_token %}
<input type="hidden" name="_csrf_token" value="{{ csrf_token }}"/>
{% endif %}
<div>
<label for="username">{{ 'security.login.username'|trans }}</label>
<input type="text" id="username" name="_username" value="{{ last_username }}" required="required"
autocomplete="username"/>
</div>
<div>
<label for="password">{{ 'security.login.password'|trans }}</label>
<input type="password" id="password" name="_password" required="required"
autocomplete="current-password"/>
</div>
<div>
<input type="checkbox" id="remember_me" name="_remember_me" value="on"/>
<label for="remember_me">{{ 'security.login.remember_me'|trans }}</label>
</div>
<input class="btn btn-success btn-block" type="submit" id="_submit" name="_submit" value="{{ 'security.login.submit'|trans }}"/>
</form>category-listing
</div> </div>
</div> </div>
<div class="col-xs-12 col-sm-6"> <div class="col-xs-12 col-sm-6">
@ -61,7 +29,42 @@
</div> </div>
</div> </div>
</div> </div>
<div class="row">
<div class="col-xs-12">
<div class="padded">
{% if error %}
<div class="alert alert-info">{{ error.messageKey|trans(error.messageData, 'security') }}</div>
{% endif %}
<form action="{{ path("fos_user_security_check") }}" method="post">
{% if csrf_token %}
<input type="hidden" name="_csrf_token" value="{{ csrf_token }}"/>
{% endif %}
<div>
<label for="username">{{ 'security.login.username'|trans }}</label>
<input type="text" id="username" class="input-lg" name="_username" value="{{ last_username }}" required="required"
autocomplete="username"/>
</div>
<div>
<label for="password">{{ 'security.login.password'|trans }}</label>
<input type="password" id="password" class="input-lg" name="_password" required="required"
autocomplete="current-password"/>
</div>
<div class="padded-v">
<input type="checkbox" id="remember_me" name="_remember_me" value="on"/>
<label for="remember_me">{{ 'security.login.remember_me'|trans }}</label>
</div>
<input class="btn btn-success btn-block btn-lg" type="submit" id="_submit" name="_submit" value="{{ 'security.login.submit'|trans }}"/>
</form>
</div>
</div>
</div>
{% endblock %} {% endblock %}

View File

@ -1,5 +1,3 @@
{% trans_default_domain 'FOSUserBundle' %}
{% if error %} {% if error %}
<div>{{ error.messageKey|trans(error.messageData, 'security') }}</div> <div>{{ error.messageKey|trans(error.messageData, 'security') }}</div>
{% endif %} {% endif %}

View File

@ -1,5 +1,4 @@
{% extends 'base.html.twig' %} {% extends 'base.html.twig' %}
{% trans_default_domain 'FOSUserBundle' %}
{% block title %}Caisse{% endblock %} {% block title %}Caisse{% endblock %}
{% block bigMain %} {% block bigMain %}

View File

@ -1,4 +1,3 @@
{% trans_default_domain 'FOSUserBundle' %}
{% extends '@HWIOAuth/layout.html.twig' %} {% extends '@HWIOAuth/layout.html.twig' %}
{% block bigMain %} {% block bigMain %}
{% include 'default/header.html.twig' %} {% include 'default/header.html.twig' %}

View File

@ -5,7 +5,6 @@
<h2>Le login</h2> <h2>Le login</h2>
<div class="row"> <div class="row">
<div class="col-xs-6"> <div class="col-xs-6">
{% trans_default_domain 'FOSUserBundle' %}
{% if error %} {% if error %}
<div>{{ error|trans }}</div> <div>{{ error|trans }}</div>

View File

@ -1,10 +1,11 @@
{% trans_default_domain 'messages' %}
<!DOCTYPE html> <!DOCTYPE html>
<html> <html>
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="google-signin-client_id" <meta name="google-signin-client_id"
content="938689189350-frtrg93bnva4b3p7c1al880mi3ts5i35.apps.googleusercontent.com"> content="938689189350-frtrg93bnva4b3p7c1al880mi3ts5i35.apps.googleusercontent.com">
<title>{% block title %}Fiche de compte dynamique{% endblock %}</title> <title>{% block title %} {% trans %}menu.title{% endtrans %} - Fiche de compte dynamique{% endblock %}</title>
{% block stylesheets %} {% block stylesheets %}
<link rel="stylesheet" href="{{ asset('build/app.css') }}"> <link rel="stylesheet" href="{{ asset('build/app.css') }}">
{% endblock %} {% endblock %}
@ -16,13 +17,14 @@
<div id="bodyland"> <div id="bodyland">
{% block bigMain %} {% block bigMain %}
{% include 'default/header.html.twig' %} {% include 'default/header.html.twig' %}
<div class="container"> <div class="row-fluid">
<div class="col-xs-12 col-sm-9 col-sm-offset-2">
{% block body %} {% block body %}
{% endblock %} {% endblock %}
</div> </div>
{% include 'default/footer.html.twig' %} </div>
{% include 'default/footer.html.twig' %}
{% endblock %} {% endblock %}
</div> </div>
{% block javascripts %} {% block javascripts %}

View File

@ -1,46 +1,48 @@
<div class="product-values marged-v"> <div class="product-values marged-v">
<div class="row"> <div class="row">
<div class="col-xs-12 col-sm-4 text-center product-values-block"> <div class="col-xs-12 col-md-4 text-center product-values-block">
<i class="fa fa-check-circle fa-3x"></i> <i class="fa fa-check-circle fa-3x"></i>
<h2 class="text-center">Gratuit</h2> <h2 class="text-center">{% trans %}home.specs.free{% endtrans %}</h2>
<p>Gérez votre comptabilité de stand en ligne sans dépenser un rond. Plus besoin de transporter un <p>{% trans %}home.specs.free_text{% endtrans %}</p>
inventaire et des feuilles de calcul faites à l'arrache.</p>
</div> </div>
<div class="col-xs-12 col-sm-4 text-center product-values-block"> <div class="col-xs-12 col-md-4 text-center product-values-block">
<i class="fa fa-random fa-3x"></i> <i class="fa fa-random fa-3x"></i>
<h2>Flexible</h2> <h2>{% trans %}home.specs.flex{% endtrans %}</h2>
<p>Modifiez vos produits à la volée, soyez plusieurs à gérer la caisse si vous le souhaitez, changez de <p>{% trans %}home.specs.flex_text{% endtrans %}</p>
responsable en cours de journée. Créez plusieurs produits juste en écrivant leur nom avec l'interface
d'importation simplifiée.</p>
</div> </div>
<div class="col-xs-12 col-sm-4 text-center product-values-block"> <div class="col-xs-12 col-md-4 text-center product-values-block">
<i class="fa fa-truck fa-3x"></i> <i class="fa fa-truck fa-3x"></i>
<h2>Portable</h2> <h2>{% trans %}home.specs.portable{% endtrans %}</h2>
<p>Fait pour être utilisé sur les marchés et les salons. Votre gestion des stocks n'en sera que <p>{% trans %}home.specs.portable_text{% endtrans %}</p>
simplifiée.</p>
</div> </div>
</div> </div>
<div class="row"> <div class="row">
<div class="col-xs-12 col-sm-4 text-center product-values-block"> <div class="col-xs-12 col-md-4 text-center product-values-block">
<i class="fa fa-rotate-left fa-3x"></i> <i class="fa fa-rotate-left fa-3x"></i>
<h2>Open Source</h2> <h2>{% trans %}home.specs.open{% endtrans %}</h2>
<p>Auto hébergeable et modifiable à volonté. Sources disponible sur <p>{% trans %}home.specs.open_text{% endtrans %}
<a href="https://gitlab.com/tykayn1/fanzine-log">gitlab.</a> <ul>
Développé par <li>
<a href="https://www.cipherbliss.com">CipherBliss</a> <a href="https://framagit.org/tykayn/caisse-bliss">gitlab.</a>
. </li>
<li>
<a href="https://www.cipherbliss.com">CipherBliss</a>
</li>
</ul>
</p> </p>
</div> </div>
<div class="col-xs-12 col-sm-4 text-center product-values-block"> <div class="col-xs-12 col-md-4 text-center product-values-block">
<i class="fa fa-pie-chart fa-3x"></i> <i class="fa fa-pie-chart fa-3x"></i>
<h2>Statistiques</h2> <h2>{% trans %}home.specs.stats{% endtrans %}</h2>
<p>Données statistiques et gestion des stocks actualisée au fur et à mesure des ventes.</p> <p>
{% trans %}home.specs.stats_text{% endtrans %}
</p>
</div> </div>
<div class="col-xs-12 col-sm-4 text-center product-values-block"> <div class="col-xs-12 col-md-4 text-center product-values-block">
<i class="fa fa-heart-o fa-3x"></i> <i class="fa fa-heart-o fa-3x"></i>
<h2>Data Love</h2> <h2>{% trans %}home.specs.data{% endtrans %}</h2>
<p>Données exportables et importables en masse librement.</p> <p>{% trans %}home.specs.data_text{% endtrans %}</p>
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,6 +1,6 @@
<footer class="big-footer text-center navbar-inverse navbar-footer "> <footer class="big-footer text-center navbar-inverse navbar-footer ">
<div class="container"> <sub class="footer-note text-center">
<sub class="footer-note text-center"> développé par Tykayn / {% trans %}global.made_by{% endtrans %} Tykayn /
<a href="http://www.cipherbliss.com"> <a href="http://www.cipherbliss.com">
Cipher Bliss Cipher Bliss
</a> </a>
@ -10,5 +10,4 @@
contact contact
</a> </a>
</sub> </sub>
</div>
</footer> </footer>

View File

@ -1,15 +1,11 @@
<div class="header-block "> <div class="header-block">
<div class="nav navbar-inverse padded"> <div class="nav padded">
<div class="container">
<div class="row"> <div class="row">
<div class="col-xs-12"> <div class="col-xs-12">
{% include 'default/login-choices.html.twig' %} {% include 'default/login-choices.html.twig' %}
</div> </div>
</div> </div>
<div class="row-fluid"> <div class="nav-elements">
<div class="col-xs-12">
{% if app.request.hasPreviousSession %} {% if app.request.hasPreviousSession %}
{% for type, messages in app.session.flashBag.all %} {% for type, messages in app.session.flashBag.all %}
@ -27,7 +23,5 @@
</div> </div>
</div> </div>
</div>
</div>
</div> </div>
</div> </div>

View File

@ -1,6 +1,4 @@
{% extends 'base.html.twig' %} {% extends 'base.html.twig' %}
{% trans_default_domain 'FOSUserBundle' %}
{% block bigMain %} {% block bigMain %}
{% include 'default/main-screen.html.twig' %} {% include 'default/main-screen.html.twig' %}

View File

@ -1,4 +1,3 @@
{% trans_default_domain 'FOSUserBundle' %}
{% block loginchoices %} {% block loginchoices %}
<div class="loginland "> <div class="loginland ">
@ -6,13 +5,13 @@
{% if is_granted("IS_AUTHENTICATED_REMEMBERED") %} {% if is_granted("IS_AUTHENTICATED_REMEMBERED") %}
<div class="row"> <div class="row">
<div class="col-xs-9"> <div class="col-xs-12 col-sm-9">
<div id="menu-dashboard"> <div id="menu-dashboard">
<ul class="nav nav-pills pull-right"> <ul class="nav">
<li> <li>
<a href="{{ path('homepage') }}" class="btn btn-default logo-home pull-left"> <a href="{{ path('homepage') }}" class="btn btn-default logo-home">
<i class="fa fa-home"></i> <i class="fa fa-home"></i>
Caisse Bliss {% trans %}menu.title{% endtrans %}
</a> </a>
</li> </li>
<li> <li>
@ -22,7 +21,7 @@
btn-default btn-default
{% endif %}" href="{{ path('dashboard') }}"> {% endif %}" href="{{ path('dashboard') }}">
<i class="fa fa-list"></i> <i class="fa fa-list"></i>
Dashboard {% trans %}menu.dashboard{% endtrans %}
</a> </a>
</li> </li>
<li> <li>
@ -33,8 +32,7 @@
{% endif %} " {% endif %} "
href="{{ path('productcategory_index') }}"> href="{{ path('productcategory_index') }}">
<i class="fa fa-file-archive-o"></i> <i class="fa fa-file-archive-o"></i>
Catégories {% trans %}menu.categories{% endtrans %}
<span class="badge"> <span class="badge">
{{ app.user.categories|length }} {{ app.user.categories|length }}
</span> </span>
@ -49,7 +47,7 @@
href="{{ path('product_index') }}" href="{{ path('product_index') }}"
> >
<i class="fa fa-gears"></i> <i class="fa fa-gears"></i>
Produits {% trans %}menu.products{% endtrans %}
<span class="badge"> <span class="badge">
{{ app.user.products|length }} {{ app.user.products|length }}
</span> </span>
@ -64,12 +62,29 @@
" href='{{ path('festival_index') }}' " href='{{ path('festival_index') }}'
> >
<i class="fa fa-th-large"></i> <i class="fa fa-th-large"></i>
Festivals
{% trans %}menu.festivals{% endtrans %}
<span class="badge"> <span class="badge">
{{ app.user.festivals|length }} {{ app.user.festivals|length }}
</span> </span>
</a> </a>
</li> </li>
<li>
<a class="btn {% if app.request.attributes.get('_route') == 'seriefestival_index' %}
btn-success
{% else %}
btn-default
{% endif %}
" href='{{ path('seriefestival_index') }}'
>
<i class="fa fa-th-large"></i>
{% trans %}menu.series{% endtrans %}
<span class="badge">
{{ app.user.seriesFestivals|length }}
</span>
</a>
</li>
<li> <li>
<a class="btn {% if app.request.attributes.get('_route') == 'history' %} <a class="btn {% if app.request.attributes.get('_route') == 'history' %}
btn-success btn-success
@ -78,7 +93,7 @@
{% endif %}" href="{{ path('history') }}" {% endif %}" href="{{ path('history') }}"
> >
<i class="fa fa-clock-o"></i> <i class="fa fa-clock-o"></i>
Historique {% trans %}menu.history{% endtrans %}
</a> </a>
</li> </li>
<li> <li>
@ -90,7 +105,8 @@
{% endif %}" href="{{ path('import') }}" {% endif %}" href="{{ path('import') }}"
> >
<i class="fa fa-arrow-circle-o-up"></i> <i class="fa fa-arrow-circle-o-up"></i>
Import
{% trans %}menu.import{% endtrans %}
</a> </a>
</li> </li>
<li> <li>
@ -102,14 +118,21 @@
{% endif %}" href="{{ path('previsionnel') }}" {% endif %}" href="{{ path('previsionnel') }}"
> >
<i class="fa fa-arrow-circle-o-up"></i> <i class="fa fa-arrow-circle-o-up"></i>
Prévisionnel
{% trans %}menu.future{% endtrans %}
</a> </a>
</li> </li>
</ul> </ul>
</div> </div>
</div> </div>
<div class="col-xs-3 text-right"> <div class="col-xs-12 col-sm-3 text-sm-left text-md-right">
Bonjour
<button class="btn btn-default visible-xs pull-right" id="menu_button">
<i class="fa fa-bars"></i>
Menu
</button>
{% trans %}user.greet{% endtrans %}
<a href="{{ path('fos_user_profile_edit') }}"> <a href="{{ path('fos_user_profile_edit') }}">
<i class="fa fa-user"></i> <i class="fa fa-user"></i>
@ -118,7 +141,8 @@
</a> </a>
| |
<a class="btn btn-default" href="{{ path('fos_user_security_logout') }}"> <a class="btn btn-default" href="{{ path('fos_user_security_logout') }}">
Déconnexion
{% trans %}layout.logout{% endtrans %}
</a> </a>
</div> </div>
</div> </div>

View File

@ -9,38 +9,34 @@
<div class="bg-shader"> <div class="bg-shader">
<div class="container main-section"> <div class="container main-section">
<div class="row"> <div class="row">
<div class="col-xs-12 col-sm-6 padded-v"> <div class="col-xs-12 padded-v">
<h1> <h1 class="text-center">
{#<i class="fa fa-circle-o-notch logo-main"></i>#} {#<i class="fa fa-circle-o-notch logo-main"></i>#}
Caisse Bliss {% trans %}menu.title{% endtrans %}
</h1> </h1>
</div> </div>
<div class="col-xs-12 col-sm-6 padded-v"> <div class="col-xs-12 col-md-6 padded-v">
<div class="description"> <div class="description">
<strong> Votre caisse mobile dynamique en ligne </strong> Pensé pour les {% trans %}home.main_description{% endtrans %}
exposants et les créateurs divers en festival, cette caisse saura s'adapter à
l'évolution de vos stocks et vous libèrera des affres de la fiche de compte à
faire et compléter soi même.
</div> </div>
<div class="try">
<br> </div>
<div class="row"> <div class="try col-xs-12 col-md-6">
<div class="col-xs-12 col-sm-6 padded text-right"> <br>
<a class="btn btn-primary" <div class="row">
href="{{ path('fos_user_security_login') }}" <div class=" padded text-right">
class="btn btn-primary"> <a class="btn btn-primary"
Essayez dès maintenant href="{{ path('fos_user_security_login') }}"
</a> class="btn btn-primary">
</div> {% trans %}home.try{% endtrans %}
<div class="col-xs-12 col-sm-6"> </a>
<sub> Démonstration en vous connectant avec le login: </div>
<strong>demo</strong> et le mot de passe <strong>demo</strong>. <div class="hint padded">
</sub> <sub>{% trans %}home.demo_hint{% endtrans %}</sub>
</div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
@ -62,21 +58,16 @@
<div class="col-xs-12 col-sm-6"> <div class="col-xs-12 col-sm-6">
<a class="btn btn-primary" href="{{ path('dashboard') }}" <a class="btn btn-primary" href="{{ path('dashboard') }}"
class="btn btn-success"> class="btn btn-success">
Essayez dès maintenant {% trans %}home.try{% endtrans %}
</a> </a>
<p> <p>
Démonstration en vous connectant avec le login: <strong>demo</strong> et le {% trans %}home.demo_hint{% endtrans %}
mot de passe <strong>demo</strong>.
</p> </p>
</div> </div>
<div class="col-xs-12 col-sm-6"> <div class="col-xs-12 col-sm-6">
{#<a class="btn btn-default" href="{{ path('fos_user_security_login') }}">#}
{#<i class="fa fa-key"></i>#}
{#Se connecter#}
{#</a>#}
<a class="btn btn-primary" href="{{ path('fos_user_registration_register') }}"> <a class="btn btn-primary" href="{{ path('fos_user_registration_register') }}">
<i class="fa fa-user"></i> <i class="fa fa-user"></i>
Créer un compte {% trans %}layout.register{% endtrans %}
</a> </a>
</div> </div>
@ -91,10 +82,14 @@
<i class="fa fa-envelope-open-o"></i> <i class="fa fa-envelope-open-o"></i>
contactez-moi pour tout renseignement: contactez-moi pour tout renseignement:
<a href="mailto:contact@cipherbliss.com"> par email</a> <a href="mailto:contact@cipherbliss.com"> par email</a>
, Telegram @tykayn, ou sur Mastodon , Telegram
<a href="https://mamot.fr/@tykayn"> <a href="https://t.me/tykayn">
@tykayn
</a>
, ou sur Mastodon
<a href="https://mastodon.cipherbliss.com/@tykayn">
<img src="https://en.gravatar.com/userimage/53061325/811d383aa2ebb8d2d83baab7da5f4a7b.jpeg" <img src="https://en.gravatar.com/userimage/53061325/811d383aa2ebb8d2d83baab7da5f4a7b.jpeg"
alt="avatar Mastodon" width="50" height="50"> @tykayn@mamot.fr alt="avatar Mastodon" width="50" height="50"> @tykayn
</a> </a>
</div> </div>

View File

@ -1,7 +1,7 @@
{% extends 'base.html.twig' %} {% extends 'base.html.twig' %}
{% block body %} {% block body %}
<div class="row"> <div class="row heading-of-list">
<div class="col-xs-6"> <div class="col-xs-6">
<h1>Festivals</h1></div> <h1>Festivals</h1></div>
<div class="col-xs-6"> <div class="col-xs-6">
@ -62,7 +62,9 @@
<td>{{ festival.chiffreAffaire - (festival.fraisInscription + festival.fraisTransport + festival.fraisRepas + festival.fraisHebergement ) }}</td> <td>{{ festival.chiffreAffaire - (festival.fraisInscription + festival.fraisTransport + festival.fraisRepas + festival.fraisHebergement ) }}</td>
<td> <td>
{% if app.user.activeFestival and (app.user.activeFestival.id == festival.id) %} {% if app.user.activeFestival and (app.user.activeFestival.id == festival.id) %}
<span class="badge badge-success">
Actuel Actuel
</span>
{% else %} {% else %}
<a class="btn btn-success" href="{{ path('set_active_festival', { 'id': festival.id }) }}"> <a class="btn btn-success" href="{{ path('set_active_festival', { 'id': festival.id }) }}">
choisir comme actuel choisir comme actuel

View File

@ -1,103 +1,90 @@
{% verbatim %} <div class="current-selling">
<div class="current-selling" >
<form > <form>
<h2> <div class="row">
<div class="col-xs-12 col-sm-6">
<h2>
<a class="btn " href="{{ path('festival_index') }}">
{% verbatim %}
<i class="fa fa-th-large"></i>
Festival
</a>:
<span class="badge" title="fond de caisse + chiffre d'affaire. veillez à vider votre fond de caisse ailleurs lorsqu'il devient trop important, par exemple au dela de 200€" ng-class="{'badge-warning': activeFestival.fondDeCaisseAvant + activeFestival.chiffreAffaire > 200}">
<i class="fa fa-archive"></i>
{{ activeFestival.fondDeCaisseAvant + activeFestival.chiffreAffaire}} €
</span>
<span class="badge badge-success">
CA {{ activeFestival.chiffreAffaire }}
<span ng-if="sellingOk">
<i class="fa fa-check-circle-o"></i>
</span>
</span>
<span class="badge badge-success">{{ activeFestival.clientsCount }} <i class="fa fa-user"></i></span>
</h2>
</div>
<div class="col-xs-12 col-sm-6">
Festival:
<span class="badge" title="fond de caisse + chiffre d'affaire. veillez à vider votre fond de caisse ailleurs lorsqu'il devient trop important, par exemple au dela de 200€" ng-class="{'badge-warning': activeFestival.fondDeCaisseAvant + activeFestival.chiffreAffaire > 200}">
<i class="fa fa-archive"></i>
{{ activeFestival.fondDeCaisseAvant + activeFestival.chiffreAffaire}} €
</span>
<span class="badge badge-success">CA {{ activeFestival.chiffreAffaire }}
<span ng-if="sellingOk">
<i class="fa fa-check-circle-o"></i>
</span>
</span>
<span class="badge badge-success">{{ activeFestival.clientsCount }} <i class="fa fa-user"></i></span>
</h2>
<input type="text" ng-model="activeFestival.name" placeholder="nom du festival"> <input type="text" ng-model="activeFestival.name" placeholder="nom du festival">
<input type="text" ng-model="activeFestival.commentaire" placeholder="commentaire"> <input class="pull-right" type="text" ng-model="activeFestival.commentaire" placeholder="commentaire">
</div>
</div>
<hr> <hr>
<div>
<div class="row-fluid">
</div>
</div>
</div> </div>
<hr> <div class="new-display">
<div ng-repeat="p in activeSelling track by $index">
<div class="row">
<!-- <div class="col-xs-12 col-sm-6">-->
<!-- <h2>new display without duplicates:</h2>-->
<!-- </div>-->
<div class="col-xs-12 col-sm-6">
<button class="btn btn-warning btn-remove-all" ng-click="removeAll()" ng-disable="!CurrentSellingTotal()">
<i class="fa fa-trash"></i> enlever tout
</button>
</div>
</div>
<div ng-repeat="group in activeSellingFiltered track by $index">
<div class="row"> <div class="row">
<div class="col-xs-12 col-sm-6"> <div class="col-xs-4">
<div class="input-group"> <div class="input-group">
<input type="text" ng-model="p.name"> <input type="text" ng-model="group.name">
<span class="btn btn-warning input-group-addon remove-item"
ng-click="removeProduct(p,$index)">
<i class="fa fa-trash"></i>
</span>
</div> </div>
</div> </div>
<div class="col-xs-12 col-sm-6 text-right"> <div class="col-xs-4 text-right">
<strong>
{{group.unitPrice}}
€ </strong>
<span class="badge badge-default" ng-if="group.count">
<i class="fa fa-times"></i> {{group.count}}
</span>
</div>
<div class="col-xs-4 text-right">
<strong> <strong>
<input type="number" ng-model="p.price"> {{group.totalPrice}}
€ </strong> € </strong>
<span class="btn btn-warning remove-item"
ng-click="removeGroupeProducts(group.groupId)">
<i class="fa fa-trash"></i>
</span>
</div> </div>
</div> </div>
</div> </div>
<div class="text-right"> </div>
<div class="row"> <hr>
<div class="col-xs-12 col-sm-6">
<h3>Total: </h3>
</div>
<div class="col-xs-12 col-sm-6">
<h3>
<strong>
{{ CurrentSellingTotal() }} </strong>€
</h3>
</div>
</div>
<div class="row">
<div class="col-xs-12 col-sm-6">
Le client paie:
</div>
<div class="col-xs-12 col-sm-6">
<input type="number" id="paid_amount" ng-model="paidAmount">
</div>
</div>
<div class="alert alert-success" ng-if="paidAmount && CurrentSellingTotal() - paidAmount <=0">
<h3>Rendu: {{ -1*(CurrentSellingTotal() - paidAmount) }} €</h3>
</div>
<div class="alert alert-warning" ng-if="paidAmount && CurrentSellingTotal() - paidAmount >0">
<h3>il manque: {{ CurrentSellingTotal() - paidAmount }} €</h3>
</div>
</div>
<div class="row">
<div class="col">
{% endverbatim %} {% endverbatim %}
{% include 'logged/angular/validate-button.html.twig' %} {% include 'logged/angular/totals.html.twig' %}
{% verbatim %} {% include 'logged/angular/validate-button.html.twig' %}
</div> {% include 'logged/angular/pause-selling.html.twig' %}
<!--<div class="col">--> {% verbatim %}
<!--<button class="btn btn-default" id="pause_selling" ng-click="pauseSelling()">-->
<!--<i class="fa fa-clock"></i>-->
<!--Pause-->
<!--</button>-->
<!--</div>-->
</div>
</form> </form>
<hr>
</div> </div>
{% endverbatim %} {% endverbatim %}

View File

@ -1,7 +1,7 @@
{% verbatim %} {% verbatim %}
<div class="horizontal-land"> <div class="horizontal-land">
<div class="super-large" style="min-width: {{(1+categories.length) * 400}}px"> <div class="super-large" style="min-width: {{(1+categories.length) * 400}}px">
<div class="category-listing one-category col-xs-4 col-sm-3 " ng-repeat="c in categories" <div class="category-listing one-category col-xs-12 col-sm-4 " ng-repeat="c in categories"
ng-if="! c.hidden"> ng-if="! c.hidden">
<h2 ng-class="{'hidden':c.hidden}"> <h2 ng-class="{'hidden':c.hidden}">
@ -37,4 +37,4 @@
</div> </div>
</div> </div>
{% endverbatim %} {% endverbatim %}

View File

@ -0,0 +1,8 @@
{% verbatim %}
<!--<div class="col">-->
<!--<button class="btn btn-default" id="pause_selling" ng-click="pauseSelling()">-->
<!--<i class="fa fa-clock"></i>-->
<!--Pause-->
<!--</button>-->
<!--</div>-->
{% endverbatim %}

View File

@ -0,0 +1,30 @@
{% verbatim %}
<div class="text-right">
<div class="row clickable" >
<div class="col-xs-12 col-sm-6">
<h3 ng-click="setRightAmountPaid()">Total: </h3>
</div>
<div class="col-xs-12 col-sm-6">
<h3 ng-click="setRightAmountPaid()">
<strong>
{{ CurrentSellingTotal() }}
</strong>€
</h3>
</div>
</div>
<div class="row">
<div class="col-xs-12 col-sm-6">
Le client paie:
</div>
<div class="col-xs-12 col-sm-6">
<input class="text-right" type="number" id="paid_amount" ng-model="paidAmount">
</div>
</div>
<div class="alert alert-success" ng-if="paidAmount && CurrentSellingTotal() - paidAmount <=0">
<h3>Rendu: {{ -1*(CurrentSellingTotal() - paidAmount) }} €</h3>
</div>
<div class="alert alert-warning" ng-if="paidAmount && CurrentSellingTotal() - paidAmount >0">
<h3>il manque: {{ CurrentSellingTotal() - paidAmount }} €</h3>
</div>
</div>
{% endverbatim %}

View File

@ -1,3 +1,4 @@
{% verbatim %}
<button class="btn btn-primary btn-block validate_selling" ng-click="sendForm(event)" <button class="btn btn-primary btn-block validate_selling" ng-click="sendForm(event)"
ng-disabled="!paidAmount"> ng-disabled="!paidAmount">
<i class="fa fa-check"></i> <i class="fa fa-check"></i>
@ -9,3 +10,4 @@
<i class="fa fa-warning"></i> <i class="fa fa-warning"></i>
</span> </span>
</button> </button>
{% endverbatim %}

View File

@ -1,16 +1,18 @@
{% verbatim %} {% verbatim %}
<div id="not_loaded" ng-if="!initLoadDone"> <div id="not_loaded" ng-if="!initLoadDone">
<div class="well"> <div class="well text-center">
<i class="fa fa-refresh fa-spin fa-3x"></i> Chargement en cours de vos produits <i class="fa fa-refresh fa-spin fa-3x"></i> Chargement en cours de vos produits
</div> </div>
</div> </div>
{% endverbatim %} {% endverbatim %}
{% include 'logged/angular/loaded-caisse.html.twig' %} {% include 'logged/angular/loaded-caisse.html.twig' %}
{% verbatim %}
<div class="choice-categories well" ng-if="categories.length"> <div class="choice-categories well" ng-if="categories.length">
<h2> <h2>
<i class="fa-eye fa"></i> <i class="fa-eye fa"></i>
Visibilité des catégories Visibilité des
{{categories.length - categoriesVisibleCount() }} /
{{ categories.length }} catégories
</h2> </h2>
<div ng-repeat="c in categories" <div ng-repeat="c in categories"
@ -18,10 +20,15 @@
<div class="btn btn-block" <div class="btn btn-block"
ng-class="{'btn-success': !c.hidden}" ng-class="{'btn-success': !c.hidden}"
ng-click="c.hidden = !c.hidden"> ng-click="c.hidden = !c.hidden">
{% verbatim %} {{ c.name }} {{ c.name }}
{% endverbatim %}
<span ng-if="c.hidden">(caché)</span> <span ng-if="c.hidden">(caché)</span>
</div> </div>
</div> </div>
</div> </div>
<div class="well" ng-if="!categories.length">
<i class="fa fa-info"></i>
Aucune catégorie enregistrée
</div>
{% endverbatim %}

View File

@ -1,98 +1,100 @@
{% extends 'base.html.twig' %} {% extends 'base.html.twig' %}
{% trans_default_domain 'FOSUserBundle' %}
{% block body %} {% block body %}
<div id="wrapper"> <div id="caisse-now" class="tab-pane fade in active">
<div id="container" class="container"> <div class="caisse-main row-fluid"
<div id="caisse-now" class="tab-pane fade in active"> ng-app="caisse"
<div class="caisse-main row" ng-controller="CaisseCtrl as MainCtrl"
ng-app="caisse" >
ng-controller="CaisseCtrl as MainCtrl" <div class="row marged-v">
> <div class="col-xs-12 col-md-6">
<div class="row marged-v"> <button
<div class="col-xs-12 col-md-12"> title="la vente express vous permet d'enregistrer une vente pour un seul article sans remplir le formulaire de détail"
<button class="btn"
title="la vente express vous permet d'enregistrer une vente pour un seul article sans remplir le formulaire de détail" ng-class="{'btn-success': expressSelling, 'btn-disabled':!expressSelling}"
class="btn" ng-click="expressSelling = !expressSelling">
ng-class="{'btn-success': expressSelling, 'btn-disabled':!expressSelling}" <i class="fa fa-shopping-cart"></i>
ng-click="expressSelling = !expressSelling"> mode vente express
<i class="fa fa-shopping-cart"></i> <span ng-if=expressSelling>
mode vente express
<span ng-if=expressSelling>
<i class="fa fa-check-circle"></i></span> <i class="fa fa-check-circle"></i></span>
</button> </button>
<button <button
title="montrer le nombre d'objets restants dans les stocks" title="montrer le nombre d'objets restants dans les stocks"
class="btn" class="btn"
ng-class="{'btn-success': show_config.stock_count, 'btn-disabled':!show_config.stock_count}" ng-class="{'btn-success': show_config.stock_count, 'btn-disabled':!show_config.stock_count}"
ng-click="show_config.stock_count = !show_config.stock_count"> ng-click="show_config.stock_count = !show_config.stock_count">
<i class="fa fa-shopping-cart"></i> <i class="fa fa-shopping-cart"></i>
stocks stocks
<span ng-if=show_config.stock_count> <span ng-if=show_config.stock_count>
<i class="fa fa-check-circle"></i></span> <i class="fa fa-check-circle"></i></span>
</button> </button>
<button <button
title="montrer le nombre d'objets restants dans les stocks" title="montrer le nombre d'objets restants dans les stocks"
class="btn" class="btn"
ng-class="{'btn-success': show_config.sold, 'btn-disabled':!show_config.sold}" ng-class="{'btn-success': show_config.sold, 'btn-disabled':!show_config.sold}"
ng-click="show_config.sold = !show_config.sold"> ng-click="show_config.sold = !show_config.sold">
<i class="fa fa-shopping-cart"></i> <i class="fa fa-shopping-cart"></i>
vendus vendus
<span ng-if=show_config.sold> <span ng-if=show_config.sold>
<i class="fa fa-check-circle"></i> <i class="fa fa-check-circle"></i>
</span> </span>
</button> </button>
</div> </div>
<div class="col-xs-12 col-md-6"> <div class="col-xs-12 col-md-6">
<div class="row">{% verbatim %}
<div class="client-now text-right padded"> <div class="client-now text-right padded">
<i class="fa fa-user"></i> <div class="col-xs-12">
Client actuel:
{% verbatim %}
{{ activeSelling.length }} produit<span ng-if="activeSelling.length!=1">s</span>
<div class="input-group pull-right">
<input class="input form-control pull-right " type="text" ng-model="sellingComment" placeholder="nom ou commentaire">
<button type="button" class="pull-right deleter" ng-click="sellingComment = ''"> <i class="fa fa-user"></i>
Client actuel:
</div>
<div class="col-xs-10">
<div class="input-group">
<input class="input form-control input-comment" type="text" ng-model="sellingComment" placeholder="nom ou commentaire">
<button type="button" class="deleter" ng-click="sellingComment = ''">
<i class="fa fa-times"></i> <i class="fa fa-times"></i>
</button> </button>
</div> </div>
<div> <div>
{{ activeSelling.length }} produit<span ng-if="activeSelling.length!=1">s</span>
{% endverbatim %} </div>
{#<button class="btn btn-default" ng-click="sellingComment = 'boobbbbbb'">#} <!--états de sauvegarde-->
{#<i class="fa fa-arrow-right"></i>#} <div class="selling-ok alert-success alert block" ng-if="sellingOk" ng-click="sellingOk = false">
{#</button>#} <i class="fa fa-save"></i>
{#<button class="btn btn-default"#} Sauvegardé!
{#ng-click="logger(MainCtrl.sellingComment ) ; logger( sellingComment)">#} </div>
{#<i class="fa fa-arrow-down"></i>#} <div class="selling-ok alert-error alert block" ng-if="sellingError" ng-click="sellingError = false">
{#</button>#} <i class="fa fa-warning"></i>
</div> Problème de sauvegarde (pas de réseau ?)
</div>
{% endverbatim %}
</div> </div>
</div> </div>
</div> </div>
</div>
<div class="row">
{% include 'logged/caisse-main.html.twig' %}
</div>
</div>
</div>
<div id="categories" class="tab-pane fade">
<h2>Catégories</h2>
</div>
<div id="products" class="tab-pane fade">
<h2>Produits</h2>
</div>
<div id="history" class="tab-pane fade">
<h2>Historique</h2>
</div>
</div>
</div> </div>
<div class="row">
{% include 'logged/caisse-main.html.twig' %}
</div>
</div>
<div id="categories" class="tab-pane fade">
<h2>Catégories</h2>
</div>
<div id="products" class="tab-pane fade">
<h2>Produits</h2>
</div>
<div id="history" class="tab-pane fade">
<h2>Historique</h2>
</div>
{#</div>#} {#</div>#}
{#</div>#} {#</div>#}
{% endblock %} {% endblock %}

View File

@ -22,9 +22,9 @@
var dataPointsFestivals = [ var dataPointsFestivals = [
{% for pair in statisticsFestivals %} {% for pair in statisticsFestivals %}
{ {
label: "{{ pair.date|date('Y-m-d') }}", label: "{{ pair.name }} {{ pair.date|date('Y-m-d') }} , {{ pair.chiffreAffaire }}",
y: {{ pair.chiffreAffaire }} , y: {{ pair.chiffreAffaire }} ,
countClients : {{ pair.clients_count }} countClients : "{{ pair.clients_count }} clients"
}, },
{% endfor %} {% endfor %}
]; ];
@ -37,7 +37,7 @@
data: [ data: [
{ {
// Change type to "doughnut", "line", "splineArea", etc. // Change type to "doughnut", "line", "splineArea", etc.
type: "line", type: "column",
dataPoints: dataPointsFestivals dataPoints: dataPointsFestivals
} }
] ]

View File

@ -1,5 +1,4 @@
{% extends 'base.html.twig' %} {% extends 'base.html.twig' %}
{% trans_default_domain 'FOSUserBundle' %}
{% block body %} {% block body %}
<div id="wrapper"> <div id="wrapper">
<div id="container" class="container"> <div id="container" class="container">
@ -15,7 +14,7 @@
<h2> <h2>
<i class="fa fa-users"></i> <i class="fa fa-users"></i>
<span class="chiffre key-figure"> <span class="chiffre key-figure">
{{ allSellings |length }} {{ allSellings }}
</span> </span>
Clients Clients
</h2> </h2>
@ -35,7 +34,7 @@
<i class="fa fa-shopping-cart"></i> <i class="fa fa-shopping-cart"></i>
<span class="chiffre key-figure"> <span class="chiffre key-figure">
{% if allSellings %} {% if allSellings %}
{{ (chiffreAffaires / (allSellings |length))|round }} {{ (chiffreAffaires / (allSellings))|round }}
{% else %} {% else %}
? ?
{% endif %} {% endif %}
@ -73,53 +72,65 @@
</div> </div>
</div> <hr>
<div id="last-sellings">
<h2>
{{ recentSells |length }} Dernières ventes
</h2>
<div class="table">
<div class="row">
<div class="col-xs-3">
date
</div>
<div class="col-xs-3">
commentaire
</div>
<div class="col-xs-3">
produits
</div>
<div class="col-xs-3">
montant
</div>
</div>
</div>
{% for vente in recentSells %}
<div class="row"> <div id="last-sellings">
<div class="col-xs-3"> <div class="row">
{{ vente.date |date('Y-m-d H:i:s') }} <div class="col-xs-12">
</div>
<div class="col-xs-3">
{{ vente.comment }}
</div>
<div class="col-xs-3">
{{ vente.productsSold |length }}
</div>
<div class="col-xs-3">
{{ vente.amount }}
<a href="{{ path('sellrecord_delete',{id: vente.id }) }}" <div class="table">
class="btn btn-warning pull-right"> <div class="row-fluid">
<i class="fa fa-trash"></i> <div class="col-xs-12">
</a> <h2>
{{ recentSells |length }} Dernières ventes
</h2>
</div>
</div>
<table class="table table-striped">
<thead>
<tr>
<td>date</td>
<td>commentaire</td>
<td>produits</td>
<td>montant</td>
<td>Actions</td>
</tr>
</thead>
<tbody>
{% for vente in recentSells %}
<tr>
<td> {{ vente.date |date('Y-m-d H:i:s') }}</td>
<td>{{ vente.comment }}</td>
<td class="text-right">{{ vente.productsSold |length }}</td>
<td class="text-right">
{{ vente.amount }}
</td>
<td>
<a href="{{ path('sellrecord_delete',{id: vente.id }) }}"
class="btn btn-warning pull-right">
<i class="fa fa-trash"></i>
</a>
</td>
</tr> {% endfor %}
</tbody>
</table>
</div>
</div>
</div> </div>
</div> </div>
{% endfor %}
</div> {% include ':logged:history-script.html.twig' %}
{% include ':logged:history-script.html.twig' %} </div>
{% endblock %} {% endblock %}

View File

@ -1,14 +1,13 @@
{% extends 'base.html.twig' %} {% extends 'base.html.twig' %}
{% trans_default_domain 'FOSUserBundle' %}
{% block body %} {% block body %}
<h1>Importation, création en masse</h1> <h1>Importation, création en masse</h1>
<div class="row"> <div class="row">
<div class="col-xs-6 well"> <div class="col-xs-12 col-sm-6 well">
{% include 'logged/mass-register.html.twig' %} {% include 'logged/mass-register.html.twig' %}
</div> </div>
<div class="col-xs-6 well"> <div class="col-xs-12 col-sm-6 well">
<h2> <h2>
Importer votre historique de ventes Importer votre historique de ventes

View File

@ -0,0 +1,8 @@
{% extends 'base.html.twig' %}
{% block body %}
<div id="wrapper">
<h1>Appli angular embarquée</h1>
<script href="{{ asset('/assets/js/build-frontend-submodule/main.js') }}"></script>
<div ng-app="tktest"></div>
</div>
{% endblock %}

View File

@ -1,5 +1,4 @@
{% extends 'base.html.twig' %} {% extends 'base.html.twig' %}
{% trans_default_domain 'FOSUserBundle' %}
{% block body %} {% block body %}
{% verbatim %} {% verbatim %}

View File

@ -1,17 +1,20 @@
{% extends 'base.html.twig' %} {% extends 'base.html.twig' %}
{% block body %} {% block body %}
<div class="row"> <div class="row heading-of-list">
<div class="col-xs-6"> <div class="col-xs-6">
<h1>Produits</h1></div> <h1>Produits</h1></div>
<div class="col-xs-6"> <div class="col-xs-6">
<a class="btn btn-primary pull-right" href="{{ path('product_new') }}">Nouveau produit</a> <a class="btn btn-primary pull-right" href="{{ path('product_new') }}">Nouveau produit</a>
<span class="alert alert-info pull-right"> <span class="hint alert alert-info pull-right">
astuce: Utilisez astuce: Utilisez
<strong>
<a href="{{ path('import') }}"> <a href="{{ path('import') }}">
l'import de masse l'import de masse
</a> </a>
</strong>
pour créer plusieurs produits et catégories à la fois pour créer plusieurs produits et catégories à la fois
</span> </span>
</div> </div>
@ -27,6 +30,7 @@
<th>Image</th> <th>Image</th>
<th>Price</th> <th>Price</th>
<th>Stocks</th> <th>Stocks</th>
<th>Vendus</th>
<th>Comment</th> <th>Comment</th>
<th>Actions</th> <th>Actions</th>
</tr> </tr>
@ -54,6 +58,7 @@
<td>{{ product.image }}</td> <td>{{ product.image }}</td>
<td>{{ product.price }}</td> <td>{{ product.price }}</td>
<td>{{ product.stockCount }}</td> <td>{{ product.stockCount }}</td>
<td>{{ product.productsSold | length }}</td>
<td>{{ product.comment }}</td> <td>{{ product.comment }}</td>
<td> <td>
<a class="btn btn-default" href="{{ path('product_edit', { 'id': product.id }) }}"> <a class="btn btn-default" href="{{ path('product_edit', { 'id': product.id }) }}">

View File

@ -1,7 +1,7 @@
{% extends 'base.html.twig' %} {% extends 'base.html.twig' %}
{% block body %} {% block body %}
<div class="row"> <div class="row heading-of-list">
<div class="col-xs-6"> <div class="col-xs-6">
<h1>Catégorie de produit</h1></div> <h1>Catégorie de produit</h1></div>
<div class="col-xs-6"> <div class="col-xs-6">

View File

@ -1,7 +1,7 @@
{% extends 'base.html.twig' %} {% extends 'base.html.twig' %}
{% block body %} {% block body %}
<h1>Productcategory creation</h1> <h1>Création de catégorie de produit</h1>
{{ form_start(form) }} {{ form_start(form) }}
{{ form_widget(form) }} {{ form_widget(form) }}

View File

@ -1,7 +1,16 @@
{% extends 'base.html.twig' %} {% extends 'base.html.twig' %}
{% block body %} {% block body %}
<h1>Sellrecords list</h1> <div class="row heading-of-list">
<div class="col-xs-6">
<h1>Enregistrements de ventes</h1>
</div>
<div class="col-xs-6">
<a class="btn btn-primary" href="{{ path('sellrecord_new') }}">Nouvel enregistrement</a>
</div>
</div>
<table class="table-responsive table-striped table table-bordered table-light"> <table class="table-responsive table-striped table table-bordered table-light">
<thead> <thead>

View File

@ -0,0 +1,21 @@
{% extends 'base.html.twig' %}
{% block body %}
<h1>Seriefestival edit</h1>
{{ form_start(edit_form) }}
{{ form_widget(edit_form) }}
<input type="submit" value="Edit" />
{{ form_end(edit_form) }}
<ul>
<li>
<a href="{{ path('seriefestival_index') }}">Back to the list</a>
</li>
<li>
{{ form_start(delete_form) }}
<input type="submit" value="Delete">
{{ form_end(delete_form) }}
</li>
</ul>
{% endblock %}

View File

@ -0,0 +1,55 @@
{% extends 'base.html.twig' %}
{% block body %}
<div class="row heading-of-list">
<div class="col-xs-6">
<h1>Série de Festivals</h1>
<div class="well">
une série de festival vous permet d'obtenir des statistiques sur plusieurs évènements à la fois. et de comparer
des coûts et bénéfices d'une édition à une autre.
</div>
</div>
<div class="col-xs-6">
<a class="btn btn-primary" href="{{ path('seriefestival_new') }}">Nouvelle série</a>
</div>
</div>
<table>
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Datecreation</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for serieFestival in serieFestivals %}
<tr>
<td>
<a href="{{ path('seriefestival_show', { 'id': serieFestival.id }) }}">{{ serieFestival.id }}</a>
</td>
<td>{{ serieFestival.name }}</td>
<td>{% if serieFestival.dateCreation %}{{ serieFestival.dateCreation|date('Y-m-d H:i:s') }}{% endif %}</td>
<td>
<ul>
<li>
<a href="{{ path('seriefestival_show', { 'id': serieFestival.id }) }}">show</a>
</li>
<li>
<a href="{{ path('seriefestival_edit', { 'id': serieFestival.id }) }}">edit</a>
</li>
</ul>
</td>
</tr>
{% endfor %}
</tbody>
</table>
<ul>
<li>
<a class="btn btn-primary" href="{{ path('seriefestival_new') }}">Nouvelle série</a>
</li>
</ul>
{% endblock %}

View File

@ -0,0 +1,16 @@
{% extends 'base.html.twig' %}
{% block body %}
<h1>Création de série de festival</h1>
{{ form_start(form) }}
{{ form_widget(form) }}
<input type="submit" value="Create"/>
{{ form_end(form) }}
<ul>
<li>
<a href="{{ path('seriefestival_index') }}">Retour à la liste</a>
</li>
</ul>
{% endblock %}

View File

@ -0,0 +1,36 @@
{% extends 'base.html.twig' %}
{% block body %}
<h1>Seriefestival</h1>
<table>
<tbody>
<tr>
<th>Id</th>
<td>{{ serieFestival.id }}</td>
</tr>
<tr>
<th>Name</th>
<td>{{ serieFestival.name }}</td>
</tr>
<tr>
<th>Datecreation</th>
<td>{% if serieFestival.dateCreation %}{{ serieFestival.dateCreation|date('Y-m-d H:i:s') }}{% endif %}</td>
</tr>
</tbody>
</table>
<ul>
<li>
<a href="{{ path('seriefestival_index') }}">Back to the list</a>
</li>
<li>
<a href="{{ path('seriefestival_edit', { 'id': serieFestival.id }) }}">Edit</a>
</li>
<li>
{{ form_start(delete_form) }}
<input type="submit" value="Delete">
{{ form_end(delete_form) }}
</li>
</ul>
{% endblock %}

View File

@ -1,84 +1,85 @@
imports: imports:
- { resource: parameters.yml } - { resource: parameters.yml }
- { resource: security.yml } - { resource: security.yml }
- { resource: services.yml } - { resource: services.yml }
# Put parameters here that don't need to change on each machine where the app is deployed # Put parameters here that don't need to change on each machine where the app is deployed
# https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration # https://symfony.com/doc/current/best_practices/configuration.html#application-related-configuration
parameters: parameters:
locale: fr locale: fr
framework: framework:
#esi: ~ #esi: ~
translator: { fallbacks: ['%locale%'] } translator: { fallbacks: ['%locale%'] }
secret: '%secret%' secret: '%secret%'
router: router:
resource: '%kernel.project_dir%/app/config/routing.yml' resource: '%kernel.project_dir%/app/config/routing.yml'
strict_requirements: ~ strict_requirements: ~
form: ~ form: ~
csrf_protection: ~ csrf_protection: ~
validation: { enable_annotations: true } validation: { enable_annotations: true }
#serializer: { enable_annotations: true } #serializer: { enable_annotations: true }
default_locale: '%locale%' default_locale: '%locale%'
trusted_hosts: ~ trusted_hosts: ~
session: session:
# https://symfony.com/doc/current/reference/configuration/framework.html#handler-id # https://symfony.com/doc/current/reference/configuration/framework.html#handler-id
handler_id: session.handler.native_file handler_id: session.handler.native_file
save_path: '%kernel.project_dir%/var/sessions/%kernel.environment%' save_path: '%kernel.project_dir%/var/sessions/%kernel.environment%'
fragments: ~ fragments: ~
http_method_override: true http_method_override: true
assets: ~ assets: ~
php_errors: php_errors:
log: true log: true
templating: templating:
engines: ['twig'] engines: ['twig']
# Twig Configuration # Twig Configuration
twig: twig:
debug: '%kernel.debug%' debug: '%kernel.debug%'
strict_variables: '%kernel.debug%' strict_variables: '%kernel.debug%'
# Doctrine Configuration # Doctrine Configuration
doctrine: doctrine:
dbal: dbal:
driver: pdo_mysql driver: pdo_mysql
host: '%database_host%' server_version: '%server_version%'
port: '%database_port%' host: '%database_host%'
dbname: '%database_name%' port: '%database_port%'
user: '%database_user%' dbname: '%database_name%'
password: '%database_password%' user: '%database_user%'
charset: UTF8 password: '%database_password%'
mapping_types: charset: UTF8
enum: string mapping_types:
# if using pdo_sqlite as your database driver: enum: string
# 1. add the path in parameters.yml # if using pdo_sqlite as your database driver:
# e.g. database_path: '%kernel.project_dir%/var/data/data.sqlite' # 1. add the path in parameters.yml
# 2. Uncomment database_path in parameters.yml.dist # e.g. database_path: '%kernel.project_dir%/var/data/data.sqlite'
# 3. Uncomment next line: # 2. Uncomment database_path in parameters.yml.dist
#path: '%database_path%' # 3. Uncomment next line:
#path: '%database_path%'
orm: orm:
auto_generate_proxy_classes: '%kernel.debug%' auto_generate_proxy_classes: '%kernel.debug%'
naming_strategy: doctrine.orm.naming_strategy.underscore naming_strategy: doctrine.orm.naming_strategy.underscore
auto_mapping: true auto_mapping: true
# Swiftmailer Configuration # Swiftmailer Configuration
swiftmailer: swiftmailer:
transport: '%mailer_transport%' transport: '%mailer_transport%'
host: '%mailer_host%' host: '%mailer_host%'
username: '%mailer_user%' username: '%mailer_user%'
password: '%mailer_password%' password: '%mailer_password%'
# spool: { type: memory } # spool: { type: memory }
encryption: '%mailer_encryption%' encryption: '%mailer_encryption%'
port: '%mailer_port%' port: '%mailer_port%'
#fos user bundle #fos user bundle
fos_user: fos_user:
db_driver: orm # other valid values are 'mongodb' and 'couchdb' db_driver: orm # other valid values are 'mongodb' and 'couchdb'
firewall_name: main firewall_name: main
user_class: AppBundle\Entity\User user_class: AppBundle\Entity\User
registration: registration:
confirmation: confirmation:
enabled: true enabled: true
from_email: from_email:
address: "%mailer_user%" address: "%mailer_user%"
sender_name: "%mailer_user%" sender_name: "%mailer_user%"

View File

@ -29,3 +29,5 @@ parameters:
twitter_secret: change_this twitter_secret: change_this
disqus_id: change_this disqus_id: change_this
disqus_secret: change_this disqus_secret: change_this
server_version: '5.6'

View File

@ -1,3 +1,8 @@
app_serie_festival:
resource: "@AppBundle/Controller/SerieFestivalController.php"
type: annotation
fos_user_profile: fos_user_profile:
resource: "@FOSUserBundle/Resources/config/routing/profile.xml" resource: "@FOSUserBundle/Resources/config/routing/profile.xml"
prefix: /profile prefix: /profile

View File

@ -1,40 +1,41 @@
# To get started with security, check out the documentation:# To get started with security, check out the documentation: # To get started with security, check out the documentation:# To get started with security, check out the documentation:
# https://symfony.com/doc/current/security.html # https://symfony.com/doc/current/security.html
security: security:
encoders: encoders:
FOS\UserBundle\Model\UserInterface: bcrypt FOS\UserBundle\Model\UserInterface: bcrypt
# https://symfony.com/doc/current/security.html#b-configuring-how-users-are-loaded # https://symfony.com/doc/current/security.html#b-configuring-how-users-are-loaded
providers: providers:
fos_userbundle: fos_userbundle:
id: fos_user.user_provider.username id: fos_user.user_provider.username
firewalls: firewalls:
dev: dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/ pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false security: false
# https://symfony.com/doc/current/security/form_login_setup.html # https://symfony.com/doc/current/security/form_login_setup.html
# activate different ways to authenticate # activate different ways to authenticate
# https://symfony.com/doc/current/security.html#a-configuring-how-your-users-will-authenticate # https://symfony.com/doc/current/security.html#a-configuring-how-your-users-will-authenticate
http_basic: ~ http_basic: ~
main: main:
pattern: ^/ pattern: ^/
anonymous: ~ anonymous: ~
logout: true logout: true
logout_on_user_change: true logout_on_user_change: true
form_login: form_login:
provider: fos_userbundle provider: fos_userbundle
csrf_token_generator: security.csrf.token_manager csrf_token_generator: security.csrf.token_manager
default_target_path: dashboard default_target_path: dashboard
login_path: fos_user_security_login login_path: fos_user_security_login
check_path: /login_check check_path: /login_check
role_hierarchy: role_hierarchy:
ROLE_ADMIN: ROLE_USER ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_ADMIN ROLE_SUPER_ADMIN: ROLE_ADMIN
access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/dashboard$, role: IS_AUTHENTICATED_REMEMBERED }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/logged, role: IS_AUTHENTICATED_REMEMBERED }
- { path: ^/admin/, role: ROLE_ADMIN }
access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/dashboard$, role: IS_AUTHENTICATED_REMEMBERED }
- { path: ^/logged$, role: IS_AUTHENTICATED_REMEMBERED }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/, role: ROLE_ADMIN }

View File

@ -5,7 +5,7 @@
@import 'split/formulaires'; @import 'split/formulaires';
@import 'split/typo'; @import 'split/typo';
@import 'pages/global'; @import 'pages/global';
//@import 'pages/demo'; @import 'pages/demo';
@import 'pages/home'; @import 'pages/home';
@import 'pages/history'; @import 'pages/history';
@import 'pages/dashboard'; @import 'pages/dashboard';

View File

@ -1,12 +1,4 @@
$brand-primary: darken(#428bca, 20%); $brand-primary: darken(#428bca, 20%);
// the ~ allows you to reference things in node_modules // the ~ allows you to reference things in node_modules
@import '~bootstrap-sass/assets/stylesheets/bootstrap'; @import '~bootstrap-sass/assets/stylesheets/bootstrap';
html, h1, h2, h3, h4, h5, h6 {
font-family: Source Sans, Arial, Helvetica, sans-serif;
}
input {
width: auto;
min-width: 2em;
}

View File

@ -6,10 +6,12 @@
width: 100%; width: 100%;
float: left; float: left;
} }
.product-button { .product-button {
width: 80%; width: 80%;
text-overflow-ellipsis: "..."; text-overflow-ellipsis: "...";
} }
.listing-products { .listing-products {
.btn, button { .btn, button {
@ -22,21 +24,28 @@
border-color: $all-text-color; border-color: $all-text-color;
box-shadow: 5px 3px 10px 2px #ddd; box-shadow: 5px 3px 10px 2px #ddd;
border-width: 0; border-width: 0;
&.btn-primary { &.btn-primary {
background-color: $deepblue; background-color: $deepblue;
} }
&:hover { &:hover {
background: $lightblue; background: $lightblue;
} }
} }
.badge-default { .badge-default {
background: $lightblue; background: $lightblue;
} }
.badge-success { .badge-success {
background: mix(green, $lightblue); background: mix(green, $lightblue);
} }
} }
.input-comment {
width: calc(100% - 40px);
}
} }
// container of categories // container of categories
@ -44,7 +53,7 @@
overflow-x: auto; overflow-x: auto;
overflow-y: hidden; overflow-y: hidden;
//width: 100%; //width: 100%;
height: 80vh; height: 75vh;
background: #ccc; background: #ccc;
padding: 0.5rem; padding: 0.5rem;
} }
@ -54,23 +63,50 @@
background: #dedede; background: #dedede;
width: 350px; width: 350px;
margin: 0 4px; margin: 0 4px;
height: calc(80vh - 1rem); height: calc(74vh - 1rem);
box-sizing: border-box; box-sizing: border-box;
display: inline-block; display: inline-block;
//vertical-align: top; //vertical-align: top;
white-space: nowrap; white-space: nowrap;
//float: left; //float: left;
} }
.category-listing{
.category-listing {
border: solid 1px $grey; border: solid 1px $grey;
padding: 1rem; padding: 1rem;
margin: 0.5rem; margin: 0.5rem;
border-radius: 0.25rem; border-radius: 0.25rem;
} }
.validate_selling { .validate_selling {
margin: 0.25rem; margin: 0.25rem;
} }
.product-listing{
.product-listing {
height: 70vh; height: 70vh;
overflow: auto; overflow: auto;
} }
.sellings {
.remove-item {
margin-left: 1em;
}
}
#not_loaded {
width: 100%;
height: 75vh;
}
.selling-ok {
position: fixed;
bottom: 0;
left: 2em;
z-index: 10;
}
.block{
display: block;
width: calc(100% - 2em);
text-align:center;
}

View File

@ -23,7 +23,7 @@ p {
} }
a { a {
color: #0000F0; color: $primary;
} }
a:hover { a:hover {
@ -40,7 +40,7 @@ code {
#wrapper { #wrapper {
background: #FFF; background: #FFF;
margin: 1em auto; margin: 1em auto;
max-width: 800px; //max-width: 800px;
width: 95%; width: 95%;
} }
@ -48,15 +48,24 @@ code {
padding: 2em; padding: 2em;
} }
#welcome, #status { #homepage{
margin-bottom: 2em; @extend .bigger-text;
h1 span {
display: block;
font-size: 75%;
}
} }
.hint,
#welcome h1 span { .product-values-block{
display: block; @extend .bigger-text;
font-size: 75%; h2{
font-size: 5rem;
}
}
.bigger-text{
font-size: 2rem;
line-height: 3.5rem;
} }
#icon-status, #icon-book { #icon-status, #icon-book {
float: left; float: left;
height: 64px; height: 64px;
@ -105,3 +114,23 @@ code {
animation: fade-in 1s .2s forwards; animation: fade-in 1s .2s forwards;
} }
} }
.header-block{
background: $darkblue;
.btn-default{
color: $grey;
}
.btn{
span{
position: absolute;
right: 2.5em;
top: 1em;
}
}
}
#menu-dashboard .nav .logo-home.btn-default{
background: $darkblue;
height: 52px;
font-size: 1em;
}

View File

@ -7,10 +7,6 @@ body {
line-height: 2rem; line-height: 2rem;
} }
.navbar-inverse {
background-color: rgba(0, 0, 0, 0.25);
border-color: #090909;
}
#wrapper { #wrapper {
min-height: 100vh; min-height: 100vh;
@ -50,9 +46,11 @@ body {
.bg-color { .bg-color {
background: $deepblue; background: $deepblue;
color: $light; color: $light;
a { a {
color: $lightblue; color: $lightblue;
} }
padding: 1rem; padding: 1rem;
} }
@ -66,10 +64,14 @@ body {
height: 4em; height: 4em;
padding: 1em; padding: 1em;
box-sizing: border-box; box-sizing: border-box;
position: static;
width: 100%;
bottom: 0;
display: block;
} }
thead { thead {
background: $dark; background: $darkblue;
color: $light; color: $light;
} }
@ -88,6 +90,7 @@ label {
.padded { .padded {
padding: 1rem; padding: 1rem;
&-v { &-v {
padding: 0; padding: 0;
padding-top: 1rem; padding-top: 1rem;
@ -97,6 +100,7 @@ label {
.marged { .marged {
margin: 1rem; margin: 1rem;
&-v { &-v {
margin: 0; margin: 0;
margin-top: 1rem; margin-top: 1rem;
@ -121,23 +125,165 @@ label {
} }
.previsionnel { .previsionnel {
.config { font-size: 1rem;
font-size: 1.5rem;
}
thead {
font-size: 1.5rem;
}
label { label {
min-width: 220px; min-width: 220px;
} }
.exepanse-table {
font-size: 1.5rem;
}
.examples-depenses {
font-size: 1.5rem;
}
.big-number { .big-number {
font-size: 2.5rem; font-size: 1.85rem;
color: #2B2d42; color: #2B2d42;
} }
} }
html, h1, h2, h3, h4, h5, h6 {
font-family: Source Sans, Arial, Helvetica, sans-serif;
}
input {
width: auto;
min-width: 2em;
}
#menu-dashboard {
background: $dark;
display: flex;
position: fixed;
left: 0;
top: 0;
height: 100vh;
width: 13vw;
min-width: 300px;
overflow-x: auto;
z-index: 10;
.nav {
width: 100%;
min-width: 300px;
display: block;
border-right: solid 2px mix($dark, $grey);
.btn {
color: $light;
}
.btn-default {
color: $light;
&:hover {
background: mix($deepblue, $light);
color: $dark;
font-weight: 600;
}
}
}
i.fa {
float: left;
margin-right: 1em;
color: $light;
}
}
.nav > li > a:hover, .nav > li > a {
&:focus {
background: transparent;
border: none;
color: $lightblue;
}
&:focus {
background: transparent;
border: none;
color: $lightblue;
}
}
.btn {
border: 0;
}
.btn-default {
background: transparent;
}
.btn-success {
background-color: $deepblue;
font-weight: 800;
}
tr {
&.bg-success {
td {
background: greenyellow;
}
}
}
.table {
> div{
&:hover{
background: #ccc;
}
}
}
.table > thead > tr > td,
table td {
padding: 0.5em;
}
.login-fosub {
.padded {
padding: 3em;
}
input[type=submit] {
background: $primary;
color: $light;
display: block;
margin-top: 1em;
padding: 1em;
border: 0;
width: 100%;
&:hover {
background: $lightblue;
}
}
}
#fos_user_profile_form {
div {
margin: 0.5em auto;
}
}
#bodyland {
.container {
min-height: 100vh;
}
table {
margin-top: 2em;
}
}
#menu_button {
z-index: 10;
position: absolute;
right: 1em;
top: -2px;
font-size: 1rem;
}
.heading-of-list {
a {
margin-top: 1em;
}
}
.hint {
margin-top: 1em;
}

View File

@ -27,5 +27,5 @@
h2, h3, h4, h5, h6 { h2, h3, h4, h5, h6 {
color: $light; color: $light;
} }
font-size: 1.25rem; font-size: 1.5rem;
} }

View File

@ -1,22 +1,25 @@
@media all and(max-width: 1200px) { @media all and(max-width: 1200px) {
html,body{ nav {
min-width: auto;
}
html, body {
font-size: 1.2rem; font-size: 1.2rem;
} }
.bg-shader { .bg-shader {
height: 100%; height: 100%;
min-height: 100vh; min-height: 100vh;
} }
.product-values-block { .product-values-block {
padding: 1em; padding: 1em;
} }
#homepage{ #homepage {
.main-section{ .main-section {
padding: 2rem; padding: 2rem;
} }
.btn{
display:block; .btn {
display: block;
width: 100%; width: 100%;
font-size: 1.25em; font-size: 1.25em;
} }
@ -25,9 +28,11 @@
.product-box { .product-box {
width: 100%; width: 100%;
} }
.product-button { .product-button {
min-width: calc(100% - 56px) min-width: calc(100% - 56px)
} }
.listing-products { .listing-products {
.btn, button { .btn, button {
@ -39,12 +44,114 @@
} }
} }
@media all and(max-width: 600px) { @media all and(max-width: 1200px) {
html,body{
font-size: 1.5rem; #bodyland {
.container {
min-height: 100vh;
width: 80vw;
}
} }
.category-listing{ #menu-dashboard {
width: calc(100% - 2rem); font-size: 1rem;
width: 19vw;
min-width: 200px;
.nav {
min-width: 200px;
}
}
form {
margin-top: 3em;
select {
width: 100%;
margin: 1em 0;
}
+ ul {
margin-top: 1em;
list-style-type: none;
a {
display: block;
.fa {
margin-right: 1em;
}
}
}
}
}
@media all and(max-width: 600px) {
html, body {
font-size: 1rem;
}
#menu-dashboard .nav .logo-home.btn-default {
height: auto;
font-size: 2em;
}
#menu-dashboard {
width: 100vw;
visibility: hidden;
&.shown {
visibility: visible;
}
.nav {
min-width: 200px;
height: 100vh;
overflow: auto;
a {
font-size: 2rem;
}
}
}
.main-section > div {
padding-top: 0;
}
.product-values{
padding: 0;
}
.bigger-text, #homepage, .hint, .product-values-block {
font-size: 1.25rem;
line-height: 2rem;
}
.category-listing {
width: calc(100vw - 4rem);
height: 25vh;
min-height: auto;
float: left;
clear: both;
overflow: auto;
}
.sellings, .client-now {
input {
width: 100%;
font-size: 1.5rem;
padding: 0.5rem;
}
}
.big-footer {
font-size: 1rem;
}
#caisse-now .product-box {
margin-bottom: 0.25rem;
}
#caisse-now .listing-products button {
padding: 0.5rem 1rem;
.express-button {
padding: 0.5rem 1rem;
}
} }
} }

View File

@ -1,7 +1,11 @@
$dark: #222; $dark: #222;
$light: #dedede; $light: #dedede;
$deepblue: #1b6d85; $deepblue: #1b6d85;
$darkblue: mix(#000, $deepblue);
$lightblue: lightblue; $lightblue: lightblue;
$grey: #e3e3e3; $grey: #e3e3e3;
$logo-color: mix($deepblue, $light); $logo-color: mix($deepblue, $light);
$all-text-color: mix($deepblue, $light); $all-text-color: mix($deepblue, $light);
$primary: $deepblue;
$btn-primary-bg: $deepblue;

View File

@ -0,0 +1,350 @@
core-js@2.5.7
MIT
Copyright (c) 2014-2018 Denis Pushkarev
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
zone.js@0.8.26
MIT
The MIT License
Copyright (c) 2016-2018 Google, Inc.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
style-loader@0.21.0
MIT
Copyright JS Foundation and other contributors
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@angular/common@6.0.6
MIT
MIT
@angular/compiler@6.0.6
MIT
MIT
@angular/core@6.0.6
MIT
MIT
@angular/platform-browser-dynamic@6.0.6
MIT
MIT
@angular/platform-browser@6.0.6
MIT
MIT
rxjs@6.2.1
Apache-2.0
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright (c) 2015-2018 Google, Inc., Netflix, Inc., Microsoft Corp. and contributors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
tslib@1.9.3
Apache-2.0
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.
"Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:
You must give any other recipients of the Work or Derivative Works a copy of this License; and
You must cause any modified files to carry prominent notices stating that You changed the files; and
You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and
If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.3 KiB

View File

@ -0,0 +1,14 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Appli</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
<script type="text/javascript" src="runtime.js"></script><script type="text/javascript" src="polyfills.js"></script><script type="text/javascript" src="styles.js"></script><script type="text/javascript" src="vendor.js"></script><script type="text/javascript" src="main.js"></script></body>
</html>

View File

@ -0,0 +1,656 @@
(window["webpackJsonp"] = window["webpackJsonp"] || []).push([["main"],{
/***/ "./src/$$_lazy_route_resource lazy recursive":
/*!**********************************************************!*\
!*** ./src/$$_lazy_route_resource lazy namespace object ***!
\**********************************************************/
/*! no static exports found */
/***/ (function(module, exports) {
function webpackEmptyAsyncContext(req) {
// Here Promise.resolve().then() is used instead of new Promise() to prevent
// uncaught exception popping up in devtools
return Promise.resolve().then(function() {
var e = new Error('Cannot find module "' + req + '".');
e.code = 'MODULE_NOT_FOUND';
throw e;
});
}
webpackEmptyAsyncContext.keys = function() { return []; };
webpackEmptyAsyncContext.resolve = webpackEmptyAsyncContext;
module.exports = webpackEmptyAsyncContext;
webpackEmptyAsyncContext.id = "./src/$$_lazy_route_resource lazy recursive";
/***/ }),
/***/ "./src/app/app.component.css":
/*!***********************************!*\
!*** ./src/app/app.component.css ***!
\***********************************/
/*! no static exports found */
/***/ (function(module, exports) {
module.exports = ""
/***/ }),
/***/ "./src/app/app.component.html":
/*!************************************!*\
!*** ./src/app/app.component.html ***!
\************************************/
/*! no static exports found */
/***/ (function(module, exports) {
module.exports = "<!--The content below is only a placeholder and can be replaced.-->\n<div style=\"text-align:center\">\n <h1>\n Welcome to {{ title }}!\n </h1>\n <img width=\"300\" alt=\"Angular Logo\" src=\"data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg==\">\n</div>\n<h2>Here are some links to help you start: </h2>\n<ul>\n <li>\n <h2><a target=\"_blank\" rel=\"noopener\" href=\"https://angular.io/tutorial\">Tour of Heroes</a></h2>\n </li>\n <li>\n <h2><a target=\"_blank\" rel=\"noopener\" href=\"https://github.com/angular/angular-cli/wiki\">CLI Documentation</a></h2>\n </li>\n <li>\n <h2><a target=\"_blank\" rel=\"noopener\" href=\"https://blog.angular.io/\">Angular blog</a></h2>\n </li>\n</ul>\n\n"
/***/ }),
/***/ "./src/app/app.component.ts":
/*!**********************************!*\
!*** ./src/app/app.component.ts ***!
\**********************************/
/*! exports provided: AppComponent */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AppComponent", function() { return AppComponent; });
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ "./node_modules/@angular/core/fesm5/core.js");
var __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var AppComponent = /** @class */ (function () {
function AppComponent() {
this.title = 'app';
}
AppComponent = __decorate([
Object(_angular_core__WEBPACK_IMPORTED_MODULE_0__["Component"])({
selector: 'app-root',
template: __webpack_require__(/*! ./app.component.html */ "./src/app/app.component.html"),
styles: [__webpack_require__(/*! ./app.component.css */ "./src/app/app.component.css")]
})
], AppComponent);
return AppComponent;
}());
/***/ }),
/***/ "./src/app/app.module.ts":
/*!*******************************!*\
!*** ./src/app/app.module.ts ***!
\*******************************/
/*! exports provided: AppModule */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "AppModule", function() { return AppModule; });
/* harmony import */ var _angular_platform_browser__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/platform-browser */ "./node_modules/@angular/platform-browser/fesm5/platform-browser.js");
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/core */ "./node_modules/@angular/core/fesm5/core.js");
/* harmony import */ var _app_component__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./app.component */ "./src/app/app.component.ts");
/* harmony import */ var _dashboard_dashboard_component__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./dashboard/dashboard.component */ "./src/app/dashboard/dashboard.component.ts");
/* harmony import */ var _paiement_resume_paiement_resume_component__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(/*! ./paiement-resume/paiement-resume.component */ "./src/app/paiement-resume/paiement-resume.component.ts");
/* harmony import */ var _product_list_product_list_component__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(/*! ./product-list/product-list.component */ "./src/app/product-list/product-list.component.ts");
/* harmony import */ var _dashboard_options_dashboard_options_component__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(/*! ./dashboard-options/dashboard-options.component */ "./src/app/dashboard-options/dashboard-options.component.ts");
/* harmony import */ var _sell_pause_sell_pause_component__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(/*! ./sell-pause/sell-pause.component */ "./src/app/sell-pause/sell-pause.component.ts");
/* harmony import */ var _festival_festival_component__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(/*! ./festival/festival.component */ "./src/app/festival/festival.component.ts");
/* harmony import */ var _client_info_client_info_component__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(/*! ./client-info/client-info.component */ "./src/app/client-info/client-info.component.ts");
var __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var AppModule = /** @class */ (function () {
function AppModule() {
}
AppModule = __decorate([
Object(_angular_core__WEBPACK_IMPORTED_MODULE_1__["NgModule"])({
declarations: [
_app_component__WEBPACK_IMPORTED_MODULE_2__["AppComponent"],
_dashboard_dashboard_component__WEBPACK_IMPORTED_MODULE_3__["DashboardComponent"],
_paiement_resume_paiement_resume_component__WEBPACK_IMPORTED_MODULE_4__["PaiementResumeComponent"],
_product_list_product_list_component__WEBPACK_IMPORTED_MODULE_5__["ProductListComponent"],
_dashboard_options_dashboard_options_component__WEBPACK_IMPORTED_MODULE_6__["DashboardOptionsComponent"],
_sell_pause_sell_pause_component__WEBPACK_IMPORTED_MODULE_7__["SellPauseComponent"],
_festival_festival_component__WEBPACK_IMPORTED_MODULE_8__["FestivalComponent"],
_client_info_client_info_component__WEBPACK_IMPORTED_MODULE_9__["ClientInfoComponent"]
],
imports: [
_angular_platform_browser__WEBPACK_IMPORTED_MODULE_0__["BrowserModule"]
],
providers: [],
bootstrap: [_app_component__WEBPACK_IMPORTED_MODULE_2__["AppComponent"]]
})
], AppModule);
return AppModule;
}());
/***/ }),
/***/ "./src/app/client-info/client-info.component.css":
/*!*******************************************************!*\
!*** ./src/app/client-info/client-info.component.css ***!
\*******************************************************/
/*! no static exports found */
/***/ (function(module, exports) {
module.exports = ""
/***/ }),
/***/ "./src/app/client-info/client-info.component.html":
/*!********************************************************!*\
!*** ./src/app/client-info/client-info.component.html ***!
\********************************************************/
/*! no static exports found */
/***/ (function(module, exports) {
module.exports = "<p>\n client-info works!\n</p>\n"
/***/ }),
/***/ "./src/app/client-info/client-info.component.ts":
/*!******************************************************!*\
!*** ./src/app/client-info/client-info.component.ts ***!
\******************************************************/
/*! exports provided: ClientInfoComponent */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ClientInfoComponent", function() { return ClientInfoComponent; });
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ "./node_modules/@angular/core/fesm5/core.js");
var __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (undefined && undefined.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var ClientInfoComponent = /** @class */ (function () {
function ClientInfoComponent() {
}
ClientInfoComponent.prototype.ngOnInit = function () {
};
ClientInfoComponent = __decorate([
Object(_angular_core__WEBPACK_IMPORTED_MODULE_0__["Component"])({
selector: 'app-client-info',
template: __webpack_require__(/*! ./client-info.component.html */ "./src/app/client-info/client-info.component.html"),
styles: [__webpack_require__(/*! ./client-info.component.css */ "./src/app/client-info/client-info.component.css")]
}),
__metadata("design:paramtypes", [])
], ClientInfoComponent);
return ClientInfoComponent;
}());
/***/ }),
/***/ "./src/app/dashboard-options/dashboard-options.component.css":
/*!*******************************************************************!*\
!*** ./src/app/dashboard-options/dashboard-options.component.css ***!
\*******************************************************************/
/*! no static exports found */
/***/ (function(module, exports) {
module.exports = ""
/***/ }),
/***/ "./src/app/dashboard-options/dashboard-options.component.html":
/*!********************************************************************!*\
!*** ./src/app/dashboard-options/dashboard-options.component.html ***!
\********************************************************************/
/*! no static exports found */
/***/ (function(module, exports) {
module.exports = "<p>\n dashboard-options works!\n</p>\n"
/***/ }),
/***/ "./src/app/dashboard-options/dashboard-options.component.ts":
/*!******************************************************************!*\
!*** ./src/app/dashboard-options/dashboard-options.component.ts ***!
\******************************************************************/
/*! exports provided: DashboardOptionsComponent */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DashboardOptionsComponent", function() { return DashboardOptionsComponent; });
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ "./node_modules/@angular/core/fesm5/core.js");
var __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (undefined && undefined.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var DashboardOptionsComponent = /** @class */ (function () {
function DashboardOptionsComponent() {
}
DashboardOptionsComponent.prototype.ngOnInit = function () {
};
DashboardOptionsComponent = __decorate([
Object(_angular_core__WEBPACK_IMPORTED_MODULE_0__["Component"])({
selector: 'app-dashboard-options',
template: __webpack_require__(/*! ./dashboard-options.component.html */ "./src/app/dashboard-options/dashboard-options.component.html"),
styles: [__webpack_require__(/*! ./dashboard-options.component.css */ "./src/app/dashboard-options/dashboard-options.component.css")]
}),
__metadata("design:paramtypes", [])
], DashboardOptionsComponent);
return DashboardOptionsComponent;
}());
/***/ }),
/***/ "./src/app/dashboard/dashboard.component.css":
/*!***************************************************!*\
!*** ./src/app/dashboard/dashboard.component.css ***!
\***************************************************/
/*! no static exports found */
/***/ (function(module, exports) {
module.exports = ""
/***/ }),
/***/ "./src/app/dashboard/dashboard.component.html":
/*!****************************************************!*\
!*** ./src/app/dashboard/dashboard.component.html ***!
\****************************************************/
/*! no static exports found */
/***/ (function(module, exports) {
module.exports = "<p>\n dashboard works!\n</p>\n"
/***/ }),
/***/ "./src/app/dashboard/dashboard.component.ts":
/*!**************************************************!*\
!*** ./src/app/dashboard/dashboard.component.ts ***!
\**************************************************/
/*! exports provided: DashboardComponent */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "DashboardComponent", function() { return DashboardComponent; });
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ "./node_modules/@angular/core/fesm5/core.js");
var __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (undefined && undefined.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var DashboardComponent = /** @class */ (function () {
function DashboardComponent() {
}
DashboardComponent.prototype.ngOnInit = function () {
};
DashboardComponent = __decorate([
Object(_angular_core__WEBPACK_IMPORTED_MODULE_0__["Component"])({
selector: 'app-dashboard',
template: __webpack_require__(/*! ./dashboard.component.html */ "./src/app/dashboard/dashboard.component.html"),
styles: [__webpack_require__(/*! ./dashboard.component.css */ "./src/app/dashboard/dashboard.component.css")]
}),
__metadata("design:paramtypes", [])
], DashboardComponent);
return DashboardComponent;
}());
/***/ }),
/***/ "./src/app/festival/festival.component.css":
/*!*************************************************!*\
!*** ./src/app/festival/festival.component.css ***!
\*************************************************/
/*! no static exports found */
/***/ (function(module, exports) {
module.exports = ""
/***/ }),
/***/ "./src/app/festival/festival.component.html":
/*!**************************************************!*\
!*** ./src/app/festival/festival.component.html ***!
\**************************************************/
/*! no static exports found */
/***/ (function(module, exports) {
module.exports = "<p>\n festival works!\n</p>\n"
/***/ }),
/***/ "./src/app/festival/festival.component.ts":
/*!************************************************!*\
!*** ./src/app/festival/festival.component.ts ***!
\************************************************/
/*! exports provided: FestivalComponent */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "FestivalComponent", function() { return FestivalComponent; });
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ "./node_modules/@angular/core/fesm5/core.js");
var __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (undefined && undefined.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var FestivalComponent = /** @class */ (function () {
function FestivalComponent() {
}
FestivalComponent.prototype.ngOnInit = function () {
};
FestivalComponent = __decorate([
Object(_angular_core__WEBPACK_IMPORTED_MODULE_0__["Component"])({
selector: 'app-festival',
template: __webpack_require__(/*! ./festival.component.html */ "./src/app/festival/festival.component.html"),
styles: [__webpack_require__(/*! ./festival.component.css */ "./src/app/festival/festival.component.css")]
}),
__metadata("design:paramtypes", [])
], FestivalComponent);
return FestivalComponent;
}());
/***/ }),
/***/ "./src/app/paiement-resume/paiement-resume.component.css":
/*!***************************************************************!*\
!*** ./src/app/paiement-resume/paiement-resume.component.css ***!
\***************************************************************/
/*! no static exports found */
/***/ (function(module, exports) {
module.exports = ""
/***/ }),
/***/ "./src/app/paiement-resume/paiement-resume.component.html":
/*!****************************************************************!*\
!*** ./src/app/paiement-resume/paiement-resume.component.html ***!
\****************************************************************/
/*! no static exports found */
/***/ (function(module, exports) {
module.exports = "<p>\n paiement-resume works!\n</p>\n"
/***/ }),
/***/ "./src/app/paiement-resume/paiement-resume.component.ts":
/*!**************************************************************!*\
!*** ./src/app/paiement-resume/paiement-resume.component.ts ***!
\**************************************************************/
/*! exports provided: PaiementResumeComponent */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "PaiementResumeComponent", function() { return PaiementResumeComponent; });
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ "./node_modules/@angular/core/fesm5/core.js");
var __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (undefined && undefined.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var PaiementResumeComponent = /** @class */ (function () {
function PaiementResumeComponent() {
}
PaiementResumeComponent.prototype.ngOnInit = function () {
};
PaiementResumeComponent = __decorate([
Object(_angular_core__WEBPACK_IMPORTED_MODULE_0__["Component"])({
selector: 'app-paiement-resume',
template: __webpack_require__(/*! ./paiement-resume.component.html */ "./src/app/paiement-resume/paiement-resume.component.html"),
styles: [__webpack_require__(/*! ./paiement-resume.component.css */ "./src/app/paiement-resume/paiement-resume.component.css")]
}),
__metadata("design:paramtypes", [])
], PaiementResumeComponent);
return PaiementResumeComponent;
}());
/***/ }),
/***/ "./src/app/product-list/product-list.component.css":
/*!*********************************************************!*\
!*** ./src/app/product-list/product-list.component.css ***!
\*********************************************************/
/*! no static exports found */
/***/ (function(module, exports) {
module.exports = ""
/***/ }),
/***/ "./src/app/product-list/product-list.component.html":
/*!**********************************************************!*\
!*** ./src/app/product-list/product-list.component.html ***!
\**********************************************************/
/*! no static exports found */
/***/ (function(module, exports) {
module.exports = "<p>\n product-list works!\n</p>\n"
/***/ }),
/***/ "./src/app/product-list/product-list.component.ts":
/*!********************************************************!*\
!*** ./src/app/product-list/product-list.component.ts ***!
\********************************************************/
/*! exports provided: ProductListComponent */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ProductListComponent", function() { return ProductListComponent; });
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ "./node_modules/@angular/core/fesm5/core.js");
var __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (undefined && undefined.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var ProductListComponent = /** @class */ (function () {
function ProductListComponent() {
}
ProductListComponent.prototype.ngOnInit = function () {
};
ProductListComponent = __decorate([
Object(_angular_core__WEBPACK_IMPORTED_MODULE_0__["Component"])({
selector: 'app-product-list',
template: __webpack_require__(/*! ./product-list.component.html */ "./src/app/product-list/product-list.component.html"),
styles: [__webpack_require__(/*! ./product-list.component.css */ "./src/app/product-list/product-list.component.css")]
}),
__metadata("design:paramtypes", [])
], ProductListComponent);
return ProductListComponent;
}());
/***/ }),
/***/ "./src/app/sell-pause/sell-pause.component.css":
/*!*****************************************************!*\
!*** ./src/app/sell-pause/sell-pause.component.css ***!
\*****************************************************/
/*! no static exports found */
/***/ (function(module, exports) {
module.exports = ""
/***/ }),
/***/ "./src/app/sell-pause/sell-pause.component.html":
/*!******************************************************!*\
!*** ./src/app/sell-pause/sell-pause.component.html ***!
\******************************************************/
/*! no static exports found */
/***/ (function(module, exports) {
module.exports = "<p>\n sell-pause works!\n</p>\n"
/***/ }),
/***/ "./src/app/sell-pause/sell-pause.component.ts":
/*!****************************************************!*\
!*** ./src/app/sell-pause/sell-pause.component.ts ***!
\****************************************************/
/*! exports provided: SellPauseComponent */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SellPauseComponent", function() { return SellPauseComponent; });
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ "./node_modules/@angular/core/fesm5/core.js");
var __decorate = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (undefined && undefined.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var SellPauseComponent = /** @class */ (function () {
function SellPauseComponent() {
}
SellPauseComponent.prototype.ngOnInit = function () {
};
SellPauseComponent = __decorate([
Object(_angular_core__WEBPACK_IMPORTED_MODULE_0__["Component"])({
selector: 'app-sell-pause',
template: __webpack_require__(/*! ./sell-pause.component.html */ "./src/app/sell-pause/sell-pause.component.html"),
styles: [__webpack_require__(/*! ./sell-pause.component.css */ "./src/app/sell-pause/sell-pause.component.css")]
}),
__metadata("design:paramtypes", [])
], SellPauseComponent);
return SellPauseComponent;
}());
/***/ }),
/***/ "./src/environments/environment.ts":
/*!*****************************************!*\
!*** ./src/environments/environment.ts ***!
\*****************************************/
/*! exports provided: environment */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "environment", function() { return environment; });
// This file can be replaced during build by using the `fileReplacements` array.
// `ng build ---prod` replaces `environment.ts` with `environment.prod.ts`.
// The list of file replacements can be found in `angular.json`.
var environment = {
production: false
};
/*
* In development mode, to ignore zone related error stack frames such as
* `zone.run`, `zoneDelegate.invokeTask` for easier debugging, you can
* import the following file, but please comment it out in production mode
* because it will have performance impact when throw error
*/
// import 'zone.js/dist/zone-error'; // Included with Angular CLI.
/***/ }),
/***/ "./src/main.ts":
/*!*********************!*\
!*** ./src/main.ts ***!
\*********************/
/*! no exports provided */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _angular_core__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @angular/core */ "./node_modules/@angular/core/fesm5/core.js");
/* harmony import */ var _angular_platform_browser_dynamic__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @angular/platform-browser-dynamic */ "./node_modules/@angular/platform-browser-dynamic/fesm5/platform-browser-dynamic.js");
/* harmony import */ var _app_app_module__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! ./app/app.module */ "./src/app/app.module.ts");
/* harmony import */ var _environments_environment__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(/*! ./environments/environment */ "./src/environments/environment.ts");
if (_environments_environment__WEBPACK_IMPORTED_MODULE_3__["environment"].production) {
Object(_angular_core__WEBPACK_IMPORTED_MODULE_0__["enableProdMode"])();
}
Object(_angular_platform_browser_dynamic__WEBPACK_IMPORTED_MODULE_1__["platformBrowserDynamic"])().bootstrapModule(_app_app_module__WEBPACK_IMPORTED_MODULE_2__["AppModule"])
.catch(function (err) { return console.log(err); });
/***/ }),
/***/ 0:
/*!***************************!*\
!*** multi ./src/main.ts ***!
\***************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
module.exports = __webpack_require__(/*! /var/www/html/caisse/caisse-bliss-frontend/src/main.ts */"./src/main.ts");
/***/ })
},[[0,"runtime","vendor"]]]);
//# sourceMappingURL=main.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,137 @@
/******/ (function(modules) { // webpackBootstrap
/******/ // install a JSONP callback for chunk loading
/******/ function webpackJsonpCallback(data) {
/******/ var chunkIds = data[0];
/******/ var moreModules = data[1];
/******/ var executeModules = data[2];
/******/ // add "moreModules" to the modules object,
/******/ // then flag all "chunkIds" as loaded and fire callback
/******/ var moduleId, chunkId, i = 0, resolves = [];
/******/ for(;i < chunkIds.length; i++) {
/******/ chunkId = chunkIds[i];
/******/ if(installedChunks[chunkId]) {
/******/ resolves.push(installedChunks[chunkId][0]);
/******/ }
/******/ installedChunks[chunkId] = 0;
/******/ }
/******/ for(moduleId in moreModules) {
/******/ if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {
/******/ modules[moduleId] = moreModules[moduleId];
/******/ }
/******/ }
/******/ if(parentJsonpFunction) parentJsonpFunction(data);
/******/ while(resolves.length) {
/******/ resolves.shift()();
/******/ }
/******/
/******/ // add entry modules from loaded chunk to deferred list
/******/ deferredModules.push.apply(deferredModules, executeModules || []);
/******/
/******/ // run deferred modules when all chunks ready
/******/ return checkDeferredModules();
/******/ };
/******/ function checkDeferredModules() {
/******/ var result;
/******/ for(var i = 0; i < deferredModules.length; i++) {
/******/ var deferredModule = deferredModules[i];
/******/ var fulfilled = true;
/******/ for(var j = 1; j < deferredModule.length; j++) {
/******/ var depId = deferredModule[j];
/******/ if(installedChunks[depId] !== 0) fulfilled = false;
/******/ }
/******/ if(fulfilled) {
/******/ deferredModules.splice(i--, 1);
/******/ result = __webpack_require__(__webpack_require__.s = deferredModule[0]);
/******/ }
/******/ }
/******/ return result;
/******/ }
/******/
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // object to store loaded and loading chunks
/******/ // undefined = chunk not loaded, null = chunk preloaded/prefetched
/******/ // Promise = chunk loading, 0 = chunk loaded
/******/ var installedChunks = {
/******/ "runtime": 0
/******/ };
/******/
/******/ var deferredModules = [];
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // define __esModule on exports
/******/ __webpack_require__.r = function(exports) {
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ var jsonpArray = window["webpackJsonp"] = window["webpackJsonp"] || [];
/******/ var oldJsonpFunction = jsonpArray.push.bind(jsonpArray);
/******/ jsonpArray.push = webpackJsonpCallback;
/******/ jsonpArray = jsonpArray.slice();
/******/ for(var i = 0; i < jsonpArray.length; i++) webpackJsonpCallback(jsonpArray[i]);
/******/ var parentJsonpFunction = oldJsonpFunction;
/******/
/******/
/******/ // run deferred modules from other chunks
/******/ checkDeferredModules();
/******/ })
/************************************************************************/
/******/ ([]);
//# sourceMappingURL=runtime.js.map

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,548 @@
(window["webpackJsonp"] = window["webpackJsonp"] || []).push([["styles"],{
/***/ "./node_modules/raw-loader/index.js!./node_modules/postcss-loader/lib/index.js??embedded!./src/styles.css":
/*!**********************************************************************************************!*\
!*** ./node_modules/raw-loader!./node_modules/postcss-loader/lib??embedded!./src/styles.css ***!
\**********************************************************************************************/
/*! no static exports found */
/***/ (function(module, exports) {
module.exports = "/* You can add global styles to this file, and also import other style files */\n"
/***/ }),
/***/ "./node_modules/style-loader/lib/addStyles.js":
/*!****************************************************!*\
!*** ./node_modules/style-loader/lib/addStyles.js ***!
\****************************************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
var stylesInDom = {};
var memoize = function (fn) {
var memo;
return function () {
if (typeof memo === "undefined") memo = fn.apply(this, arguments);
return memo;
};
};
var isOldIE = memoize(function () {
// Test for IE <= 9 as proposed by Browserhacks
// @see http://browserhacks.com/#hack-e71d8692f65334173fee715c222cb805
// Tests for existence of standard globals is to allow style-loader
// to operate correctly into non-standard environments
// @see https://github.com/webpack-contrib/style-loader/issues/177
return window && document && document.all && !window.atob;
});
var getTarget = function (target) {
return document.querySelector(target);
};
var getElement = (function (fn) {
var memo = {};
return function(target) {
// If passing function in options, then use it for resolve "head" element.
// Useful for Shadow Root style i.e
// {
// insertInto: function () { return document.querySelector("#foo").shadowRoot }
// }
if (typeof target === 'function') {
return target();
}
if (typeof memo[target] === "undefined") {
var styleTarget = getTarget.call(this, target);
// Special case to return head of iframe instead of iframe itself
if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) {
try {
// This will throw an exception if access to iframe is blocked
// due to cross-origin restrictions
styleTarget = styleTarget.contentDocument.head;
} catch(e) {
styleTarget = null;
}
}
memo[target] = styleTarget;
}
return memo[target]
};
})();
var singleton = null;
var singletonCounter = 0;
var stylesInsertedAtTop = [];
var fixUrls = __webpack_require__(/*! ./urls */ "./node_modules/style-loader/lib/urls.js");
module.exports = function(list, options) {
if (typeof DEBUG !== "undefined" && DEBUG) {
if (typeof document !== "object") throw new Error("The style-loader cannot be used in a non-browser environment");
}
options = options || {};
options.attrs = typeof options.attrs === "object" ? options.attrs : {};
// Force single-tag solution on IE6-9, which has a hard limit on the # of <style>
// tags it will allow on a page
if (!options.singleton && typeof options.singleton !== "boolean") options.singleton = isOldIE();
// By default, add <style> tags to the <head> element
if (!options.insertInto) options.insertInto = "head";
// By default, add <style> tags to the bottom of the target
if (!options.insertAt) options.insertAt = "bottom";
var styles = listToStyles(list, options);
addStylesToDom(styles, options);
return function update (newList) {
var mayRemove = [];
for (var i = 0; i < styles.length; i++) {
var item = styles[i];
var domStyle = stylesInDom[item.id];
domStyle.refs--;
mayRemove.push(domStyle);
}
if(newList) {
var newStyles = listToStyles(newList, options);
addStylesToDom(newStyles, options);
}
for (var i = 0; i < mayRemove.length; i++) {
var domStyle = mayRemove[i];
if(domStyle.refs === 0) {
for (var j = 0; j < domStyle.parts.length; j++) domStyle.parts[j]();
delete stylesInDom[domStyle.id];
}
}
};
};
function addStylesToDom (styles, options) {
for (var i = 0; i < styles.length; i++) {
var item = styles[i];
var domStyle = stylesInDom[item.id];
if(domStyle) {
domStyle.refs++;
for(var j = 0; j < domStyle.parts.length; j++) {
domStyle.parts[j](item.parts[j]);
}
for(; j < item.parts.length; j++) {
domStyle.parts.push(addStyle(item.parts[j], options));
}
} else {
var parts = [];
for(var j = 0; j < item.parts.length; j++) {
parts.push(addStyle(item.parts[j], options));
}
stylesInDom[item.id] = {id: item.id, refs: 1, parts: parts};
}
}
}
function listToStyles (list, options) {
var styles = [];
var newStyles = {};
for (var i = 0; i < list.length; i++) {
var item = list[i];
var id = options.base ? item[0] + options.base : item[0];
var css = item[1];
var media = item[2];
var sourceMap = item[3];
var part = {css: css, media: media, sourceMap: sourceMap};
if(!newStyles[id]) styles.push(newStyles[id] = {id: id, parts: [part]});
else newStyles[id].parts.push(part);
}
return styles;
}
function insertStyleElement (options, style) {
var target = getElement(options.insertInto)
if (!target) {
throw new Error("Couldn't find a style target. This probably means that the value for the 'insertInto' parameter is invalid.");
}
var lastStyleElementInsertedAtTop = stylesInsertedAtTop[stylesInsertedAtTop.length - 1];
if (options.insertAt === "top") {
if (!lastStyleElementInsertedAtTop) {
target.insertBefore(style, target.firstChild);
} else if (lastStyleElementInsertedAtTop.nextSibling) {
target.insertBefore(style, lastStyleElementInsertedAtTop.nextSibling);
} else {
target.appendChild(style);
}
stylesInsertedAtTop.push(style);
} else if (options.insertAt === "bottom") {
target.appendChild(style);
} else if (typeof options.insertAt === "object" && options.insertAt.before) {
var nextSibling = getElement(options.insertInto + " " + options.insertAt.before);
target.insertBefore(style, nextSibling);
} else {
throw new Error("[Style Loader]\n\n Invalid value for parameter 'insertAt' ('options.insertAt') found.\n Must be 'top', 'bottom', or Object.\n (https://github.com/webpack-contrib/style-loader#insertat)\n");
}
}
function removeStyleElement (style) {
if (style.parentNode === null) return false;
style.parentNode.removeChild(style);
var idx = stylesInsertedAtTop.indexOf(style);
if(idx >= 0) {
stylesInsertedAtTop.splice(idx, 1);
}
}
function createStyleElement (options) {
var style = document.createElement("style");
if(options.attrs.type === undefined) {
options.attrs.type = "text/css";
}
addAttrs(style, options.attrs);
insertStyleElement(options, style);
return style;
}
function createLinkElement (options) {
var link = document.createElement("link");
if(options.attrs.type === undefined) {
options.attrs.type = "text/css";
}
options.attrs.rel = "stylesheet";
addAttrs(link, options.attrs);
insertStyleElement(options, link);
return link;
}
function addAttrs (el, attrs) {
Object.keys(attrs).forEach(function (key) {
el.setAttribute(key, attrs[key]);
});
}
function addStyle (obj, options) {
var style, update, remove, result;
// If a transform function was defined, run it on the css
if (options.transform && obj.css) {
result = options.transform(obj.css);
if (result) {
// If transform returns a value, use that instead of the original css.
// This allows running runtime transformations on the css.
obj.css = result;
} else {
// If the transform function returns a falsy value, don't add this css.
// This allows conditional loading of css
return function() {
// noop
};
}
}
if (options.singleton) {
var styleIndex = singletonCounter++;
style = singleton || (singleton = createStyleElement(options));
update = applyToSingletonTag.bind(null, style, styleIndex, false);
remove = applyToSingletonTag.bind(null, style, styleIndex, true);
} else if (
obj.sourceMap &&
typeof URL === "function" &&
typeof URL.createObjectURL === "function" &&
typeof URL.revokeObjectURL === "function" &&
typeof Blob === "function" &&
typeof btoa === "function"
) {
style = createLinkElement(options);
update = updateLink.bind(null, style, options);
remove = function () {
removeStyleElement(style);
if(style.href) URL.revokeObjectURL(style.href);
};
} else {
style = createStyleElement(options);
update = applyToTag.bind(null, style);
remove = function () {
removeStyleElement(style);
};
}
update(obj);
return function updateStyle (newObj) {
if (newObj) {
if (
newObj.css === obj.css &&
newObj.media === obj.media &&
newObj.sourceMap === obj.sourceMap
) {
return;
}
update(obj = newObj);
} else {
remove();
}
};
}
var replaceText = (function () {
var textStore = [];
return function (index, replacement) {
textStore[index] = replacement;
return textStore.filter(Boolean).join('\n');
};
})();
function applyToSingletonTag (style, index, remove, obj) {
var css = remove ? "" : obj.css;
if (style.styleSheet) {
style.styleSheet.cssText = replaceText(index, css);
} else {
var cssNode = document.createTextNode(css);
var childNodes = style.childNodes;
if (childNodes[index]) style.removeChild(childNodes[index]);
if (childNodes.length) {
style.insertBefore(cssNode, childNodes[index]);
} else {
style.appendChild(cssNode);
}
}
}
function applyToTag (style, obj) {
var css = obj.css;
var media = obj.media;
if(media) {
style.setAttribute("media", media)
}
if(style.styleSheet) {
style.styleSheet.cssText = css;
} else {
while(style.firstChild) {
style.removeChild(style.firstChild);
}
style.appendChild(document.createTextNode(css));
}
}
function updateLink (link, options, obj) {
var css = obj.css;
var sourceMap = obj.sourceMap;
/*
If convertToAbsoluteUrls isn't defined, but sourcemaps are enabled
and there is no publicPath defined then lets turn convertToAbsoluteUrls
on by default. Otherwise default to the convertToAbsoluteUrls option
directly
*/
var autoFixUrls = options.convertToAbsoluteUrls === undefined && sourceMap;
if (options.convertToAbsoluteUrls || autoFixUrls) {
css = fixUrls(css);
}
if (sourceMap) {
// http://stackoverflow.com/a/26603875
css += "\n/*# sourceMappingURL=data:application/json;base64," + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))) + " */";
}
var blob = new Blob([css], { type: "text/css" });
var oldSrc = link.href;
link.href = URL.createObjectURL(blob);
if(oldSrc) URL.revokeObjectURL(oldSrc);
}
/***/ }),
/***/ "./node_modules/style-loader/lib/urls.js":
/*!***********************************************!*\
!*** ./node_modules/style-loader/lib/urls.js ***!
\***********************************************/
/*! no static exports found */
/***/ (function(module, exports) {
/**
* When source maps are enabled, `style-loader` uses a link element with a data-uri to
* embed the css on the page. This breaks all relative urls because now they are relative to a
* bundle instead of the current page.
*
* One solution is to only use full urls, but that may be impossible.
*
* Instead, this function "fixes" the relative urls to be absolute according to the current page location.
*
* A rudimentary test suite is located at `test/fixUrls.js` and can be run via the `npm test` command.
*
*/
module.exports = function (css) {
// get current location
var location = typeof window !== "undefined" && window.location;
if (!location) {
throw new Error("fixUrls requires window.location");
}
// blank or null?
if (!css || typeof css !== "string") {
return css;
}
var baseUrl = location.protocol + "//" + location.host;
var currentDir = baseUrl + location.pathname.replace(/\/[^\/]*$/, "/");
// convert each url(...)
/*
This regular expression is just a way to recursively match brackets within
a string.
/url\s*\( = Match on the word "url" with any whitespace after it and then a parens
( = Start a capturing group
(?: = Start a non-capturing group
[^)(] = Match anything that isn't a parentheses
| = OR
\( = Match a start parentheses
(?: = Start another non-capturing groups
[^)(]+ = Match anything that isn't a parentheses
| = OR
\( = Match a start parentheses
[^)(]* = Match anything that isn't a parentheses
\) = Match a end parentheses
) = End Group
*\) = Match anything and then a close parens
) = Close non-capturing group
* = Match anything
) = Close capturing group
\) = Match a close parens
/gi = Get all matches, not the first. Be case insensitive.
*/
var fixedCss = css.replace(/url\s*\(((?:[^)(]|\((?:[^)(]+|\([^)(]*\))*\))*)\)/gi, function(fullMatch, origUrl) {
// strip quotes (if they exist)
var unquotedOrigUrl = origUrl
.trim()
.replace(/^"(.*)"$/, function(o, $1){ return $1; })
.replace(/^'(.*)'$/, function(o, $1){ return $1; });
// already a full url? no change
if (/^(#|data:|http:\/\/|https:\/\/|file:\/\/\/|\s*$)/i.test(unquotedOrigUrl)) {
return fullMatch;
}
// convert the url to a full url
var newUrl;
if (unquotedOrigUrl.indexOf("//") === 0) {
//TODO: should we add protocol?
newUrl = unquotedOrigUrl;
} else if (unquotedOrigUrl.indexOf("/") === 0) {
// path should be relative to the base url
newUrl = baseUrl + unquotedOrigUrl; // already starts with '/'
} else {
// path should be relative to current directory
newUrl = currentDir + unquotedOrigUrl.replace(/^\.\//, ""); // Strip leading './'
}
// send back the fixed url(...)
return "url(" + JSON.stringify(newUrl) + ")";
});
// send back the fixed css
return fixedCss;
};
/***/ }),
/***/ "./src/styles.css":
/*!************************!*\
!*** ./src/styles.css ***!
\************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
var content = __webpack_require__(/*! !../node_modules/raw-loader!../node_modules/postcss-loader/lib??embedded!./styles.css */ "./node_modules/raw-loader/index.js!./node_modules/postcss-loader/lib/index.js??embedded!./src/styles.css");
if(typeof content === 'string') content = [[module.i, content, '']];
var transform;
var insertInto;
var options = {"hmr":true}
options.transform = transform
options.insertInto = undefined;
var update = __webpack_require__(/*! ../node_modules/style-loader/lib/addStyles.js */ "./node_modules/style-loader/lib/addStyles.js")(content, options);
if(content.locals) module.exports = content.locals;
if(false) {}
/***/ }),
/***/ 2:
/*!******************************!*\
!*** multi ./src/styles.css ***!
\******************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {
module.exports = __webpack_require__(/*! /var/www/html/caisse/caisse-bliss-frontend/src/styles.css */"./src/styles.css");
/***/ })
},[[2,"runtime"]]]);
//# sourceMappingURL=styles.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

11
assets/js/parts/dashboard.js Executable file
View File

@ -0,0 +1,11 @@
/**
* test to import things
*/
export class DashboardStuff{
sayHi(){
console.log('hiiiiiiii! from dashboard stuff');
}
sayHo(){
console.log('hoooo');
}
};

View File

@ -10,11 +10,19 @@ require('bootstrap-sass');
$(document).ready(function () { $(document).ready(function () {
$('[data-toggle="popover"]').popover(); $('[data-toggle="popover"]').popover();
$('#menu_button').on('click', function () {
$('#menu-dashboard').toggleClass('shown');
})
}); });
require('./caisseCtrl');
require('./dashboard');
var PrevisionnelCtrl = require('./previsionnel');
console.log('hello console for main.js'); console.log('hello console for main.js');
var stuff = ['initialstuff']; var stuff = ['initialstuff'];
// TODO split controllers in other files
angular angular
.module('caisse', []) .module('caisse', [])
.controller('CaisseCtrl', ['$scope', '$http', '$timeout', function ($scope, $http, $timeout) { .controller('CaisseCtrl', ['$scope', '$http', '$timeout', function ($scope, $http, $timeout) {
@ -34,6 +42,7 @@ angular
}; };
$scope.activeItemsSold = []; // list of products ID to sell $scope.activeItemsSold = []; // list of products ID to sell
$scope.activeSelling = []; // list of products to sell $scope.activeSelling = []; // list of products to sell
$scope.activeSellingFiltered = []; // list of products to sell
$scope.activeFestival = { // an event where selling take place $scope.activeFestival = { // an event where selling take place
id : null, id : null,
name : "le festival", name : "le festival",
@ -42,6 +51,44 @@ angular
clientsCount : 0, clientsCount : 0,
commentaire : "" commentaire : ""
}; };
/**
* set the right paid amount
*/
$scope.setRightAmountPaid = function () {
// debugger;
$scope.paidAmount += $scope.sumOfList($scope.activeSelling);
}
/**
* deduplicate the active selling items in the view,
* show a count for each of them when there are more than one
*/
$scope.refreshDeduplicateSellings = () => {
let soldObjectsIdsCount = {}
$scope.activeSellingFiltered = {};
$scope.activeSelling.forEach(elem => {
let groupId = elem.id;
let group = soldObjectsIdsCount[groupId];
if (group) { // sort elements by the product id corresponding
group.count++;
group.totalPrice += (elem.price * 1);
group.sellings.push(elem);
} else {
soldObjectsIdsCount[groupId] = {
groupId : groupId,
count : 1,
name : elem.name,
unitPrice : elem.price * 1,
totalPrice: elem.price * 1,
sellings : [elem],
}
}
});
$scope.activeSellingFiltered = soldObjectsIdsCount;
}
/** /**
* get the sum of products prices * get the sum of products prices
* @param list * @param list
@ -50,7 +97,7 @@ angular
$scope.sumOfList = function (list) { $scope.sumOfList = function (list) {
let counter = 0; let counter = 0;
for (let i = 0; i < list.length; i++) { for (let i = 0; i < list.length; i++) {
counter += list[i].price; counter += list[i].price * 1;
} }
return counter; return counter;
}; };
@ -63,13 +110,20 @@ angular
return $scope.sumOfList($scope.activeSelling); return $scope.sumOfList($scope.activeSelling);
}; };
$scope.categoriesVisibleCount = function () {
let count = 0;
$scope.categories.forEach(function (elem) {
elem.hidden ? count++ : "";
});
return count;
}
$scope.regenActiveSellingIds = function () { $scope.regenActiveSellingIds = function () {
$scope.activeItemsSold = []; $scope.activeItemsSold = [];
$scope.paidAmount = 0; $scope.paidAmount = 0;
for (let obj in $scope.activeSelling) { for (let obj in $scope.activeSelling) {
$scope.activeItemsSold.push(obj.id); $scope.activeItemsSold.push(obj.id);
} }
$scope.paidAmount += $scope.sumOfList($scope.activeSelling);
}; };
$scope.stuff = stuff; $scope.stuff = stuff;
$scope.setActiveSelling = function (selling) { $scope.setActiveSelling = function (selling) {
@ -87,6 +141,8 @@ angular
$scope.activeSelling.push(product); $scope.activeSelling.push(product);
$scope.activeItemsSold.push(product.id); $scope.activeItemsSold.push(product.id);
$scope.regenActiveSellingIds(); $scope.regenActiveSellingIds();
$scope.refreshDeduplicateSellings();
$scope.setRightAmountPaid();
}; };
/** /**
* remove from current sell list * remove from current sell list
@ -95,7 +151,27 @@ angular
$scope.removeProduct = function (product, index) { $scope.removeProduct = function (product, index) {
product.stockCount++; product.stockCount++;
$scope.activeSelling.splice($index, 1); $scope.activeSelling.splice($index, 1);
$scope.regenActiveSellingIds() $scope.regenActiveSellingIds();
$scope.refreshDeduplicateSellings();
};
/**
* remove all products of a certain group id in the active Selling
* @param productId
* @returns {*}
*/
$scope.removeGroupeProducts = function (productId) {
console.log("##### removeGroupeProducts", productId);
console.log("$scope.activeSelling", $scope.activeSelling);
$scope.activeSelling = $scope.activeSelling.filter(elem => elem.id != productId)
console.log("$scope.activeSelling", $scope.activeSelling);
$scope.regenActiveSellingIds();
$scope.refreshDeduplicateSellings();
}
$scope.removeAll = function () {
$scope.activeSelling = [];
$scope.regenActiveSellingIds();
$scope.refreshDeduplicateSellings();
}; };
$scope.pauseSelling = function () { $scope.pauseSelling = function () {
$scope.pausedSelling.push(angular.copy($scope.activeSelling)); $scope.pausedSelling.push(angular.copy($scope.activeSelling));
@ -108,12 +184,13 @@ angular
$scope.clearSellingComment = function () { $scope.clearSellingComment = function () {
$scope.sellingComment = ''; $scope.sellingComment = '';
document.querySelector('#sellingCommentInput').focus(); document.querySelector('.client-now input').focus();
}; };
$scope.clearCurrentSelling = function () { $scope.clearCurrentSelling = function () {
$scope.paidAmount = 0; $scope.paidAmount = 0;
// $scope.sellingComment = ""; $scope.clearSellingComment();
$scope.activeSelling = []; $scope.activeSelling = [];
$scope.removeAll();
}; };
// http related calls // http related calls
@ -164,31 +241,33 @@ angular
console.log('logger', stuff); console.log('logger', stuff);
}; };
$scope.sendForm = function () { $scope.sendForm = function () {
console.log('$scope.sellingComment', this.sellingComment); console.log('$scope.sellingComment', $scope.sellingComment);
console.log("$scope.activeSelling", $scope.activeSelling);
let lesParams = { let lesParams = {
paidByClient : this.paidAmount, paidByClient : $scope.paidAmount,
sellingComment: this.sellingComment, sellingComment: $scope.sellingComment,
activeSelling : this.activeSelling, activeSelling : $scope.activeSelling,
activeFestival: this.activeFestival activeFestival: $scope.activeFestival
}; };
$scope.recentSellings.push({ $scope.recentSellings.push({
id : this.recentId++, id : $scope.recentId++,
amount : this.CurrentSellingTotal(), amount : $scope.CurrentSellingTotal(),
paidAmount: this.paidAmount, paidAmount: $scope.paidAmount,
products : products :
angular angular
.copy(this.activeSelling) .copy($scope.activeSelling)
}); });
console.log('$scope.recentSellings', this.recentSellings); console.log('$scope.recentSellings', $scope.recentSellings);
$scope.lesParams = lesParams; $scope.lesParams = lesParams;
$http({ $http({
method : 'POST', method : 'POST',
url : 'add-selling', url : 'logged/add-selling',
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json'
}, },
data : lesParams // pass in data as strings data : lesParams // pass in data as strings
}).then(function (rep) { }).then(function (rep) {
$scope.clearCurrentSelling(); $scope.clearCurrentSelling();
// if successful, bind success message to message // if successful, bind success message to message
$scope.successMessage = rep.data.message; $scope.successMessage = rep.data.message;
@ -203,22 +282,40 @@ angular
} }
}, function (rep) { }, function (rep) {
console.log('nope! ', rep.data); console.log('nope! ', rep.data);
$scope.showTemporaryErrorMessage();
}) })
; ;
}; };
$scope.sellingOk = false; $scope.sellingOk = false;
$scope.sellingError = false;
$scope.tempMessage = {}; $scope.tempMessage = {};
$scope.showTemporaryMessage = function () { $scope.showTemporaryMessage = function () {
console.log('show message');
if ($scope.sellingOk) { if ($scope.sellingOk) {
$scope.sellingOk = false;
return; return;
} }
$scope.sellingOk = true; $scope.sellingOk = true;
$timeout.cancel($scope.tempMessage); $timeout.cancel($scope.tempMessage);
$scope.tempMessage = $timeout(function () { $scope.tempMessage = $timeout(function () {
console.log('hide message');
$scope.sellingOk = false; $scope.sellingOk = false;
}, 2000) }, 2000)
}; };
$scope.showTemporaryErrorMessage = function () {
console.log('show message');
if ($scope.sellingError) {
$scope.sellingError = false;
return;
}
$scope.sellingError = true;
$timeout.cancel($scope.tempMessage);
$scope.tempMessage = $timeout(function () {
console.log('hide message');
$scope.sellingError = false;
}, 2000)
};
$scope.init = (function () { $scope.init = (function () {
$scope.fetchProductsFromDB(); $scope.fetchProductsFromDB();
})(); })();
@ -328,32 +425,30 @@ angular
console.log('fetch expenses...'); console.log('fetch expenses...');
$scope.config.loading = true; $scope.config.loading = true;
$http.get('get-my-expenses').then((rep) => { $http.get('logged/get-my-expenses').then((rep) => {
console.log('get-my-expenses', rep.data.expenses); console.log('logged/get-my-expenses', rep.data.expenses);
$scope.updateconf(rep) $scope.updateconf(rep)
}, },
$scope.manageError) $scope.manageError)
}; };
// save TODO $scope.save = function () {
$scope.save = () => {
if ($scope.config.loading) { if ($scope.config.loading) {
console.log('already saving'); console.log('already saving');
return; return;
} }
console.log('update expenses...'); console.log('update expenses...');
$scope.config.loading = true; $scope.config.loading = true;
$http.post('save-my-expenses', { $http.post('logged/save-my-expenses', {
expenses: $scope.expenses, expenses: $scope.expenses,
config : $scope.config config : $scope.config
}) })
.then((rep) => { .then((rep) => {
console.log('save-my-expenses', rep); console.log('logged/save-my-expenses', rep);
$scope.updateconf(rep) $scope.updateconf(rep)
}, },
$scope.manageError) $scope.manageError)
}; };
$scope.addExpense = () => { $scope.addExpense = function () {
$scope.expenses.push({ $scope.expenses.push({
name : "", name : "",
repeat: 0, repeat: 0,
@ -361,15 +456,15 @@ angular
amount: 0, amount: 0,
}) })
}; };
$scope.init = () => { $scope.init = function () {
$scope.fetchExpenses(); $scope.fetchExpenses();
}; };
$scope.manageError = (error) => { $scope.manageError = (error) => {
console.error(error); console.error(error);
$scope.config.loading = false; $scope.config.loading = false;
} };
$scope.updateCanevas = () => { $scope.updateCanevas = function () {
var dataPoints = $scope.graphPointsPrevision; var dataPoints = $scope.graphPointsPrevision;
var chartContainer = new CanvasJS.Chart("simulationPrevision", { var chartContainer = new CanvasJS.Chart("simulationPrevision", {
title: { title: {
@ -385,6 +480,6 @@ angular
] ]
}); });
chartContainer.render(); chartContainer.render();
} };
$scope.init(); $scope.init();
}]); }]);

163
assets/js/parts/previsionnel.js Executable file
View File

@ -0,0 +1,163 @@
export var PrevisionnelCtrl = function ($scope, $http, $timeout) {
$scope.config = {
initialLoadingDone : false,
loading : false,
lines : 24,
debounceTime : 300, // miliseconds to wait before updating model and saving changes
/**
* expenses kind of the user
*/
disponibility : 5000,
averageMonthlyEarnings: 600,
warningThershold : 2000,
showDelays : false,
showRepeats : false,
monthsBeforeNoMoney : null,
};
let exampleExpenses = [
{name: "appart", amount: 800, delay: 0, repeat: $scope.config.lines, enabled: true},
{name: "assurance voiture", amount: 50, delay: 0, repeat: $scope.config.lines, enabled: true},
{name: "internet", amount: 20, delay: 0, repeat: $scope.config.lines, enabled: true},
{name: "elec", amount: 100, delay: 0, repeat: $scope.config.lines, enabled: true},
{name: "chat", amount: 20, delay: 0, repeat: $scope.config.lines, enabled: true},
{name: "transports", amount: 70, delay: 0, repeat: $scope.config.lines, enabled: false},
];
// $scope.expenses=[];
$scope.expenses = exampleExpenses;
/**
* sum of all monthly expenses, ignoring delay
* @returns {number}
*/
$scope.sumMonthlyExpenses = () => {
let sum = 0;
$scope.expenses.forEach((elem) => {
if (elem.enabled) {
sum += elem.amount;
}
})
return sum;
};
$scope.previsionTable = [];
$scope.calculatePrevisionTable = () => {
let turns = $scope.config.lines;
let monthly = $scope.sumMonthlyExpenses();
let available = $scope.config.disponibility;
let previsionTable = [];
let changedNoMoneyConfig = false;
$scope.config.monthsBeforeNoMoney = null;
for (let i = 0; i <= turns; i++) {
// TODO take in account delays in expenses
available = available - monthly + $scope.config.averageMonthlyEarnings;
let newLine = {
expense : monthly,
available: available,
};
if (available <= 0 && !changedNoMoneyConfig) {
$scope.config.monthsBeforeNoMoney = i;
changedNoMoneyConfig = true;
}
previsionTable.push(newLine);
}
$scope.previsionTable = previsionTable;
$scope.makeGraphPointsOfPrevisionTable(previsionTable);
return previsionTable;
};
$scope.graphPointsPrevision = [];
$scope.makeGraphPointsOfPrevisionTable = (previsionTable) => {
console.log("previsionTable", previsionTable);
$scope.graphPointsPrevision = [];
for (let i = 0; i < previsionTable.length; i++) {
$scope.graphPointsPrevision.push({
label: previsionTable[i].available + " euros restants dans " + i + " mois",
y : previsionTable[i].available,
x : i,
})
}
}
$scope.updateconf = (rep) => {
// update view calculs
$scope.calculatePrevisionTable();
$scope.updateCanevas()
// flags
$scope.config.loading = false;
$scope.config.initialLoadingDone = true;
$scope.config.disponibility = rep.data.disponibility;
$scope.config.averageMonthlyEarnings = rep.data.averageMonthlyEarnings;
// default data when user has nothing saved
console.log('rep.data.expenses.length', rep.data.expenses.length)
if (!rep.data.expenses.length) {
$scope.expenses = exampleExpenses;
} else {
$scope.expenses = rep.data.expenses;
}
};
// http related calls
$scope.fetchExpenses = () => {
console.log('fetch expenses...');
$scope.config.loading = true;
$http.get('get-my-expenses').then((rep) => {
console.log('get-my-expenses', rep.data.expenses);
$scope.updateconf(rep)
},
$scope.manageError)
};
$scope.save = function () {
if ($scope.config.loading) {
console.log('already saving');
return;
}
console.log('update expenses...');
$scope.config.loading = true;
$http.post('save-my-expenses', {
expenses: $scope.expenses,
config : $scope.config
})
.then((rep) => {
console.log('save-my-expenses', rep);
$scope.updateconf(rep)
},
$scope.manageError)
};
$scope.addExpense = function () {
$scope.expenses.push({
name : "",
repeat: 0,
delay : 0,
amount: 0,
})
};
$scope.init = function () {
$scope.fetchExpenses();
};
$scope.manageError = (error) => {
console.error(error);
$scope.config.loading = false;
}
$scope.updateCanevas = function () {
var dataPoints = $scope.graphPointsPrevision;
var chartContainer = new CanvasJS.Chart("simulationPrevision", {
title: {
text: "Euros disponibles dans le temps"
},
// animationEnabled: true,
data : [
{
// Change type to "doughnut", "line", "splineArea", etc.
type : "splineArea",
dataPoints: dataPoints
}
]
});
chartContainer.render();
}
$scope.init();
};

11
compile-frontend.sh Executable file
View File

@ -0,0 +1,11 @@
#/bin/bash
echo "###############################";
echo "start update of frontend submodule assets";
echo "###############################";
git submodule update;
cd caisse-bliss-frontend
ng build
cp caisse-bliss-frontend/dist/appli/* /assets/js/build-frontend-submodule
echo "###########";
echo "update done";
echo "###########";

BIN
composer-temp.phar Normal file

Binary file not shown.

View File

@ -20,7 +20,7 @@
] ]
}, },
"require": { "require": {
"php": ">=5.5.9", "php": ">=7.0",
"doctrine/doctrine-bundle": "^1.6", "doctrine/doctrine-bundle": "^1.6",
"doctrine/orm": "^2.5", "doctrine/orm": "^2.5",
"friendsofsymfony/user-bundle": "~2.0", "friendsofsymfony/user-bundle": "~2.0",

1841
composer.lock generated

File diff suppressed because it is too large Load Diff

52
docs/installation.md Executable file
View File

@ -0,0 +1,52 @@
# Requirements:
a web server speaking PHP, composer and NPM to install dependencies.
I develop on [Ubuntu](https://ubuntu.org), so here are the steps i recommend:
## Install [Composer](https://getcomposer.org/download/) via PHP command
Composer manages dependencies of a lot of php projects. Try these commands or refer to [the download docs of getcomposer.org](https://getcomposer.org/download/)
```
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('sha384', 'composer-setup.php') === '48e3236262b34d30969dca3c37281b3b4bbe3221bda826ac6a9a62d6444cdb0dcd0615698a5cbe587c3f0fe57a54d8f5') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"
php composer-setup.php
php -r "unlink('composer-setup.php');"
composer install
```
# Installation:
When you have satisfied all the previous requirements you can install dependencies with [the bash script](/install.sh):
```bash
bash install.sh
```
## Configure your app parameters
In the [paramters.yml](/app/config/parameters.yml) file, setup your database access (create your DB if necessary). Works with mysql and others via the magic of Doctrine ORM.
```yaml
database_host: 127.0.0.1
database_port: null
database_name: symfony
database_user: YOURDATABASEUSER
database_password: YOURDATABASEPASSWORD
```
update schema with doctrine in the command line.
```bash
php bin/console doctrine:schema:update --dump-sql
php bin/console doctrine:schema:update --force
```
compile front end assets
```bash
yarn run encore dev --watch
```
access the front with your browser
```bash
php bin/console server:run
firefox http://http://127.0.0.1:8000/
```
enjoy!
#install via Docker ?
I didn't do that for the moment, but you can contribute to this if you like to.

5
docs/upgrade.md Executable file
View File

@ -0,0 +1,5 @@
# Upgrade the app
Pull the last news, and update the vendors. Update database, Rebuild the front, and that's it.
All of this is done with the `bash update.sh` script.
No need to reboot anything.

View File

@ -1,4 +1,4 @@
#!/bin/bash #!/bin/bash
echo "################################"; echo "################################";
echo "start UPDATE of symfony project"; echo "start UPDATE of symfony project";
@ -7,7 +7,7 @@ echo " ";
echo "####### fix file permissions ######"; echo "####### fix file permissions ######";
`which setfacl` > TEST `which setfacl` > TEST
if [ echo $TEST == 'acl not found' ]; then if [ echo $TEST == 'acl not found' ]||[ echo $TEST == 'acl non trouvé' ]; then
echo "acl is not installed" echo "acl is not installed"
sudo apt install acl -y sudo apt install acl -y
exit exit
@ -22,7 +22,7 @@ sudo setfacl -R -m u:"$HTTPDUSER":rwX -m u:$(whoami):rwX var
echo "####### phpunit test suite ######"; echo "####### phpunit test suite ######";
`which phpunit` > TEST `which phpunit` > TEST
if [ echo $TEST == 'phpunit not found' ]; then if [ echo $TEST == 'phpunit not found' ]||[ echo $TEST == 'phpunit non trouvé' ]; then
echo "phpunit is not installed" echo "phpunit is not installed"
sudo apt install phpunit -y sudo apt install phpunit -y
exit exit
@ -33,7 +33,7 @@ fi
echo "####### node packages ######"; echo "####### node packages ######";
`which npm` > TEST `which npm` > TEST
if [ echo $TEST == 'npm not found' ]; then if [ echo $TEST == 'npm not found' ]||[ echo $TEST == 'npm non trouvé' ]; then
echo "npm is not installed" echo "npm is not installed"
sudo apt install npm -y sudo apt install npm -y
exit exit
@ -44,14 +44,14 @@ fi
`which yarn` > TEST `which yarn` > TEST
if [ echo $TEST == 'yarn not found' ]; then if [ echo $TEST == 'yarn not found' ]||[ echo $TEST == 'yarn non trouvé' ]; then
echo "yarn is not installed" echo "yarn is not installed"
sudo npm i -g yarn sudo npm i -g yarn
exit exit
else else
echo "yarn est bien là" echo "yarn est bien là"
yarn -v yarn -v
echo "####### build front end with yarn ######"; echo "####### build front end with yarn ######";
yarn yarn
yarn run encore production yarn run encore production

View File

@ -344,7 +344,7 @@ class DefaultController extends Controller
// ['name' => 'bidule', 'count' => 0, 'value' => 0], // ['name' => 'bidule', 'count' => 0, 'value' => 0],
]; ];
$statsForFestival = [ $statsForFestivalMock = [
['name' => 'festoche bidule', 'clients_count' => 125, 'chiffreAffaire' => 236, 'date' => new \DateTime()], ['name' => 'festoche bidule', 'clients_count' => 125, 'chiffreAffaire' => 236, 'date' => new \DateTime()],
]; ];
foreach ($allSellingList as $client) { foreach ($allSellingList as $client) {
@ -373,11 +373,12 @@ class DefaultController extends Controller
return $this->render('logged/history.html.twig', return $this->render('logged/history.html.twig',
[ [
'statisticsFestivals' => $statsForFestival, // 'statisticsFestivals' => $statsForFestivalMock, // mock of festival stats
'statisticsFestivals' => $statisticsFestivals,
'statisticsSoldProducts' => $statisticsSoldProducts, 'statisticsSoldProducts' => $statisticsSoldProducts,
'chiffreAffaires' => $chiffreAffaires, 'chiffreAffaires' => $chiffreAffaires,
'recentSells' => $mySellings, 'recentSells' => $mySellings,
'allSellings' => $allSellingList, 'allSellings' => count($mySellings),
'base_dir' => realpath($this->getParameter('kernel.project_dir')) . DIRECTORY_SEPARATOR, 'base_dir' => realpath($this->getParameter('kernel.project_dir')) . DIRECTORY_SEPARATOR,
]); ]);
} }

View File

@ -0,0 +1,140 @@
<?php
namespace AppBundle\Controller;
use AppBundle\Entity\SerieFestival;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;use Symfony\Component\HttpFoundation\Request;
/**
* Seriefestival controller.
*
* @Route("seriefestival")
*/
class SerieFestivalController extends Controller
{
/**
* Lists all serieFestival entities.
*
* @Route("/", name="seriefestival_index")
* @Method("GET")
*/
public function indexAction()
{
$em = $this->getDoctrine()->getManager();
$serieFestivals = $em->getRepository('AppBundle:SerieFestival')->findAll();
return $this->render('seriefestival/index.html.twig', array(
'serieFestivals' => $serieFestivals,
));
}
/**
* Creates a new serieFestival entity.
*
* @Route("/new", name="seriefestival_new")
* @Method({"GET", "POST"})
*/
public function newAction(Request $request)
{
$usr= $this->getUser();
$serieFestival = new Seriefestival();
$serieFestival->setUser($usr);
$form = $this->createForm('AppBundle\Form\SerieFestivalType', $serieFestival);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($serieFestival);
$em->flush();
return $this->redirectToRoute('seriefestival_show', array('id' => $serieFestival->getId()));
}
return $this->render('seriefestival/new.html.twig', array(
'serieFestival' => $serieFestival,
'form' => $form->createView(),
));
}
/**
* Finds and displays a serieFestival entity.
*
* @Route("/{id}", name="seriefestival_show")
* @Method("GET")
*/
public function showAction(SerieFestival $serieFestival)
{
$deleteForm = $this->createDeleteForm($serieFestival);
return $this->render('seriefestival/show.html.twig', array(
'serieFestival' => $serieFestival,
'delete_form' => $deleteForm->createView(),
));
}
/**
* Displays a form to edit an existing serieFestival entity.
*
* @Route("/{id}/edit", name="seriefestival_edit")
* @Method({"GET", "POST"})
*/
public function editAction(Request $request, SerieFestival $serieFestival)
{
$deleteForm = $this->createDeleteForm($serieFestival);
$editForm = $this->createForm('AppBundle\Form\SerieFestivalType', $serieFestival);
$editForm->handleRequest($request);
if ($editForm->isSubmitted() && $editForm->isValid()) {
$this->getDoctrine()->getManager()->flush();
return $this->redirectToRoute('seriefestival_edit', array('id' => $serieFestival->getId()));
}
return $this->render('seriefestival/edit.html.twig', array(
'serieFestival' => $serieFestival,
'edit_form' => $editForm->createView(),
'delete_form' => $deleteForm->createView(),
));
}
/**
* Deletes a serieFestival entity.
*
* @Route("/{id}", name="seriefestival_delete")
* @Method("DELETE")
*/
public function deleteAction(Request $request, SerieFestival $serieFestival)
{
$form = $this->createDeleteForm($serieFestival);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->remove($serieFestival);
$em->flush();
}
return $this->redirectToRoute('seriefestival_index');
}
/**
* Creates a form to delete a serieFestival entity.
*
* @param SerieFestival $serieFestival The serieFestival entity
*
* @return \Symfony\Component\Form\Form The form
*/
private function createDeleteForm(SerieFestival $serieFestival)
{
return $this->createFormBuilder()
->setAction($this->generateUrl('seriefestival_delete', array('id' => $serieFestival->getId())))
->setMethod('DELETE')
->getForm()
;
}
}

View File

@ -87,7 +87,11 @@ class Festival {
private $fraisRepas; private $fraisRepas;
/** public function __toString() {
return $this->getName();
}
/**
* @return mixed * @return mixed
*/ */
public function getSerieFestival() public function getSerieFestival()
@ -130,7 +134,7 @@ class Festival {
'fondDeCaisseApres' => $this->getFondDeCaisseApres(), 'fondDeCaisseApres' => $this->getFondDeCaisseApres(),
'sold' => $soldItems, 'sold' => $soldItems,
]; ];
} }
public function recalculateChiffreAffaire() { public function recalculateChiffreAffaire() {
$sellings = $this->getSellRecords(); $sellings = $this->getSellRecords();

View File

@ -12,7 +12,13 @@ class FestivalType extends AbstractType {
*/ */
public function buildForm( FormBuilderInterface $builder, array $options ) { public function buildForm( FormBuilderInterface $builder, array $options ) {
$builder $builder
->add( 'name' ) ->add( 'name',
null,
[
'attr' => [
'autofocus' => true,
],
] )
->add( 'fraisInscription' ) ->add( 'fraisInscription' )
->add( 'fraisTransport' ) ->add( 'fraisTransport' )
->add( 'fraisHebergement' ) ->add( 'fraisHebergement' )

View File

@ -6,33 +6,36 @@ use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\OptionsResolver\OptionsResolver;
class ProductCategoryType extends AbstractType class ProductCategoryType extends AbstractType {
{ /**
/** * {@inheritdoc}
* {@inheritdoc} */
*/ public function buildForm( FormBuilderInterface $builder, array $options ) {
public function buildForm(FormBuilderInterface $builder, array $options) $builder->add( 'name',
{ null,
$builder->add('name') [
// ->add('users') 'attr' => [
; 'autofocus' => true,
}/** ],
* {@inheritdoc} ] )// ->add('users')
*/ ;
public function configureOptions(OptionsResolver $resolver) }
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\ProductCategory'
));
}
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function getBlockPrefix() public function configureOptions( OptionsResolver $resolver ) {
{ $resolver->setDefaults( [
return 'appbundle_productcategory'; 'data_class' => 'AppBundle\Entity\ProductCategory',
} ] );
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix() {
return 'appbundle_productcategory';
}
} }

View File

@ -23,13 +23,20 @@ class ProductType extends AbstractType {
* {@inheritdoc} * {@inheritdoc}
*/ */
public function buildForm( FormBuilderInterface $builder, array $options ) { public function buildForm( FormBuilderInterface $builder, array $options ) {
$builder->add( 'name' , null, ['label'=>'Nom']) $builder->add( 'name',
null,
[
'label' => 'Nom',
'attr' => [
'autofocus' => true,
],
] )
->add( 'image', ->add( 'image',
null, null,
[ 'label' => 'URL pour image' ] ) [ 'label' => 'URL pour image' ] )
->add( 'stockCount', null, ['label'=>'En stock'] ) ->add( 'stockCount', null, [ 'label' => 'En stock' ] )
->add( 'price', null, ['label'=>'Prix en euros']) ->add( 'price', null, [ 'label' => 'Prix en euros' ] )
->add( 'comment', null, ['label'=>'Commentaire']); ->add( 'comment', null, [ 'label' => 'Commentaire' ] );
$user = $this->security->getUser(); $user = $this->security->getUser();
if ( ! $user ) { if ( ! $user ) {
throw new \LogicException( throw new \LogicException(
@ -46,10 +53,10 @@ class ProductType extends AbstractType {
$form->add( 'category', $form->add( 'category',
EntityType::class, EntityType::class,
[ [
'class' => 'AppBundle:ProductCategory', 'class' => 'AppBundle:ProductCategory',
'placeholder' => '--- catégories ---', 'placeholder' => '--- catégories ---',
'choices' => $categories, 'choices' => $categories,
'label' => 'Catégorie', 'label' => 'Catégorie',
] ); ] );
} ); } );

View File

@ -22,7 +22,14 @@ class SellRecordType extends AbstractType {
* {@inheritdoc} * {@inheritdoc}
*/ */
public function buildForm( FormBuilderInterface $builder, array $options ) { public function buildForm( FormBuilderInterface $builder, array $options ) {
$builder->add( 'products' ); $builder->add( 'products' )
->add('comment',
null,
[
'attr' => [
'autofocus' => true,
],
]);
} }

View File

@ -0,0 +1,51 @@
<?php
namespace AppBundle\Form;
use AppBundle\Entity\Festival;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\Extension\Core\Type\DateType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class SerieFestivalType extends AbstractType {
/**
* {@inheritdoc}
*/
public function buildForm( FormBuilderInterface $builder, array $options ) {
$builder->add( 'name',
null,
[
'attr' => [
'autofocus' => true,
],
] )
->add( 'dateCreation',
DateType::class,
[
// renders it as a single text box
'widget' => 'single_text',
] )
->add( 'festivals', EntityType::class, [ 'class' => Festival::class, 'multiple' => true ] )
;
}
/**
* {@inheritdoc}
*/
public function configureOptions( OptionsResolver $resolver ) {
$resolver->setDefaults( [
'data_class' => 'AppBundle\Entity\SerieFestival',
] );
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix() {
return 'appbundle_seriefestival';
}
}

View File

View File

@ -0,0 +1,55 @@
<?php
namespace AppBundle\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class SerieFestivalControllerTest extends WebTestCase
{
/*
public function testCompleteScenario()
{
// Create a new client to browse the application
$client = static::createClient();
// Create a new entry in the database
$crawler = $client->request('GET', '/seriefestival/');
$this->assertEquals(200, $client->getResponse()->getStatusCode(), "Unexpected HTTP status code for GET /seriefestival/");
$crawler = $client->click($crawler->selectLink('Create a new entry')->link());
// Fill in the form and submit it
$form = $crawler->selectButton('Create')->form(array(
'appbundle_seriefestival[field_name]' => 'Test',
// ... other fields to fill
));
$client->submit($form);
$crawler = $client->followRedirect();
// Check data in the show view
$this->assertGreaterThan(0, $crawler->filter('td:contains("Test")')->count(), 'Missing element td:contains("Test")');
// Edit the entity
$crawler = $client->click($crawler->selectLink('Edit')->link());
$form = $crawler->selectButton('Update')->form(array(
'appbundle_seriefestival[field_name]' => 'Foo',
// ... other fields to fill
));
$client->submit($form);
$crawler = $client->followRedirect();
// Check the element contains an attribute with value equals "Foo"
$this->assertGreaterThan(0, $crawler->filter('[value="Foo"]')->count(), 'Missing element [value="Foo"]');
// Delete the entity
$client->submit($crawler->selectButton('Delete')->form());
$crawler = $client->followRedirect();
// Check the entity has been delete on the list
$this->assertNotRegExp('/Foo/', $client->getResponse()->getContent());
}
*/
}

View File

@ -1,2 +0,0 @@
layout.logout: __layout.logout
layout.register: __layout.register

View File

@ -1,3 +0,0 @@
---
layout.logout: __layout.logout
layout.register: __layout.register

View File

@ -1,3 +0,0 @@
---
layout.logout: __layout.logout
layout.register: __layout.register

121
translations/messages.en.yml Executable file
View File

@ -0,0 +1,121 @@
layout.login: login
layout.logout: logout
layout.register: subscribe
menu.title: 'Bliss cash register'
menu.dashboard: Dashboard
menu.history: History
menu.import: Import
menu.festivals: Festivals
menu.series: Séries
menu.products: Products
menu.categories: Categories
menu.future: Forecast
user.greet: Hi
security.login.username: user
security.login.password: password
security.login.remember_me: remember
security.login.submit: send
home.main_description: 'Your dynamic mobile online cash register thought for exhibitors and creators during festivals. This cash register will be able to adapt to your stock evolution and will release you from the throes of making and completing account master record yourself.'
home.try: 'Try now'
home.demo_hint: 'Démonstration en vous connectant avec le login: demo et le mot de passe demo.'
home.specs.free: 'No cost'
home.specs.free_text: 'Manage your stand accounts online without spending a dime. No need to carry an inventory and use quick and dirty spreadsheets.'
home.specs.flex: Flexible
home.specs.flex_text: 'Change your products on the fly, more than one can mange the cash register if you wish, change who is manager at anytime. Create several products just by writing their name with simplified import interface.'
home.specs.portable: Portable
home.specs.portable_text: 'Made to be used on markets and fairs. Your inventory management will therefore be simplified.'
home.specs.open: 'Open Source'
home.specs.open_text: 'Auto hébergeable et modifiable à volonté. Sources disponible sur gitlab. Développé par CipherBliss.'
home.specs.stats: Statistiques
home.specs.stats_text: 'Statistics and stock management updated in real time.'
home.specs.data: 'Data Love'
home.specs.data_text: 'Données exportables et importables en masse librement.'
home.contact.hint: 'contact me for more information'
home.contact.email: 'by email'
home.contact.telegram: 'Telegram @Tykayn'
home.contact.social: 'or on Mastodon'
dashboard.options.express: 'mode vente express'
dashboard.options.express_text: 'express sale lets you record a sale for a single article without completing the details'
dashboard.options.stocks: stocks
dashboard.options.sold: sold
dashboard.customer: 'Current customer'
dashboard.customer_default_name: 'an individual'
dashboard.products: produits
dashboard.visibility: 'Categories visibility'
dashboard.total: Total
dashboard.festival: Festival
global.made_by: 'developed by'
global.categ: 'Product category'
global.categ_new: 'New category'
global.products: Products
global.products_hint: 'hint: use mass import to create several products and categories at once'
global.products_new: 'New product'
global.festivals: Festivals
global.current: Current
global.wip: 'Work in progress'
category.name: Name
category.products: Products
category.sold: Sold
category.actions: Actions
products.category: Category
products.name: Name
products.image: Picture
products.price: Price
products.stocks: Stocks
products.comment: Comment
products.actions: Actions
festivals.name: Name
festivals.creation: 'Creation date'
festivals.costs: 'Tous Frais'
festivals.customers: Customers
festivals.before: 'petty cash before'
festivals.after: 'petty cash after'
festivals.ca: 'chiffre affaire'
festivals.stock: 'petty cash + revenue'
festivals.diff: diff
festivals.benef: 'bénefices CA - frais'
festivals.actions: Actions
history.title: History
history.export: 'Export all data as csv'
history.sold.customers: Clients
history.sold.ca: Revenue
history.sold.cart: 'panier moyen'
history.stats: 'Sales statistics'
history.last: 'Latest Sales'
sellings.date: date
sellings.comm: comment
sellings.products: products
sellings.amount: amount
import.title: 'Mass import, create'
import.create: 'Mass products creation'
import.create_text: 'Create massively products and their category, one per line'
import.validate: 'Mass creation'
import.import: 'Import sales history'
import.import_step_1: 'Download template file'
import.import_step_2: 'Fill your template with your sales'
import.import_step_3: 'to do'
forecast.title: 'Sales forecast'
forecast.saving: Saving...
forecast.saved: 'Changes saved'
forecast.conf: Configuration
forecast.start: 'Initially available money'
forecast.month_earnings: 'Average earnings per month'
forecast.delay: 'Manage payment deadlines'
forecast.repeat: 'Manage rehearsals'
forecast.monthly: 'Monthly expenses'
forecast.benef: 'Monthly profit'
forecast.credit: 'Achievable monthly credit (33%% of average earnings per month)'
forecast.posts_title: 'Monthly expenses'
forecast.posts_text: 'Specify the categories of monthly expenses you make to change the remaining months budget simulation.'
forecast.simulation: 'Simulation on % month'
forecast.table.warning_text: 'It will be broke in months %'
forecast.table.months: 'Month in the future'
forecast.table.date: date
forecast.table.expenses: Expenses
forecast.table.availability: Availability
forecast.columns.name: Name
forecast.columns.monthly: 'price per month'
forecast.columns.yearly: 'annual price'
forecast.columns.enabled: enabled
forecast.example.title: 'Examples of expenses to add'
forecast.example.content: 'home rent, heath insurance, public transport, car insurance, motorbike insurance, leisure stuff, miscellaneous, gas, electricity, savings, social security contributions, business meals, shopping, web hosting, protonmail subscription, VPN subscription, audio/video service subscription, fuel, vehicle, donations, doctor, cat, dog, unicorn '

121
translations/messages.fr.yml Executable file
View File

@ -0,0 +1,121 @@
layout.login: Connexion
layout.logout: Déconnexion
layout.register: Inscription
menu.title: 'Caisse Bliss'
menu.dashboard: Dashboard
menu.history: Historique
menu.import: Importer
menu.festivals: Festivals
menu.series: Séries
menu.products: Produits
menu.categories: Catégories
menu.future: Prévisionnel
user.greet: Bonjour
security.login.username: utilisateur
security.login.password: 'mot de passe'
security.login.remember_me: 'se souvenir'
security.login.submit: envoyer
home.main_description: 'Votre caisse mobile dynamique en ligne. Pensé pour les exposants et les créateurs divers en festival, cette caisse saura s''adapter à l''évolution de vos stocks et vous libèrera des affres de la fiche de compte à faire et compléter soi même.'
home.try: 'Essayer dès maintenant'
home.demo_hint: 'Démonstration en vous connectant avec le login: demo et le mot de passe demo.'
home.specs.free: Gratuit
home.specs.free_text: 'Gérez votre comptabilité de stand en ligne sans dépenser un rond. Plus besoin de transporter un inventaire et des feuilles de calcul faites à l''arrache.'
home.specs.flex: Flexible
home.specs.flex_text: 'Modifiez vos produits à la volée, soyez plusieurs à gérer la caisse si vous le souhaitez, changez de responsable en cours de journée. Créez plusieurs produits juste en écrivant leur nom avec l''interface d''importation simplifiée.'
home.specs.portable: Portable
home.specs.portable_text: 'Fait pour être utilisé sur les marchés et les salons. Votre gestion des stocks n''en sera que simplifiée.'
home.specs.open: 'Open Source'
home.specs.open_text: 'Auto hébergeable et modifiable à volonté. Sources disponible sur gitlab. Développé par CipherBliss.'
home.specs.stats: Statistiques
home.specs.stats_text: 'Données statistiques et gestion des stocks actualisée au fur et à mesure des ventes.'
home.specs.data: 'Data Love'
home.specs.data_text: 'Données exportables et importables en masse librement.'
home.contact.hint: 'contactez-moi pour tout renseignement'
home.contact.email: 'par email'
home.contact.telegram: 'Telegram @Tykayn'
home.contact.social: 'ou sur Mastodon'
dashboard.options.express: 'mode vente express'
dashboard.options.express_text: 'la vente express vous permet d''enregistrer une vente pour un seul article sans remplir le formulaire de détail'
dashboard.options.stocks: stocks
dashboard.options.sold: vendus
dashboard.customer: 'Client actuel'
dashboard.customer_default_name: 'un gens'
dashboard.products: produits
dashboard.visibility: 'Visibilité des catégories'
dashboard.total: Total
dashboard.festival: Festival
global.made_by: 'développé par'
global.categ: 'Catégorie de produit'
global.categ_new: 'Nouvelle catégorie'
global.products: Produits
global.products_hint: 'astuce: Utilisez l''import de masse pour créer plusieurs produits et catégories à la fois'
global.products_new: 'Nouveau produit'
global.festivals: Festivals
global.current: Actuel
global.wip: 'Fonctionnalité en cours de création'
category.name: Nom
category.products: Produits
category.sold: Vendus
category.actions: Actions
products.category: Category
products.name: Name
products.image: Image
products.price: Price
products.stocks: Stocks
products.comment: Comment
products.actions: Actions
festivals.name: Name
festivals.creation: Datecreation
festivals.costs: 'Tous Frais'
festivals.customers: Clients
festivals.before: 'fond caisse avant'
festivals.after: 'fond caisse apres'
festivals.ca: 'chiffre affaire'
festivals.stock: 'fond caisse + CA'
festivals.diff: diff
festivals.benef: 'bénefices CA - frais'
festivals.actions: Actions
history.title: Historique
history.export: 'Exporter toutes vos données en format csv'
history.sold.customers: Clients
history.sold.ca: 'Chiffre d''affaires'
history.sold.cart: 'panier moyen'
history.stats: 'Statistiques de ventes'
history.last: 'Dernières ventes'
sellings.date: date
sellings.comm: commentaire
sellings.products: produits
sellings.amount: montant
import.title: 'Importation, création en masse'
import.create: 'Création de produits en masse'
import.create_text: 'Créez vos produits et leur catégorie en masse, un par ligne'
import.validate: 'Créer en masse'
import.import: 'Importer votre historique de ventes'
import.import_step_1: 'Télécharger le fichier de modèle'
import.import_step_2: 'Remplir votre modèle avec vos ventes'
import.import_step_3: 'à faire'
forecast.title: Prévisionnel
forecast.saving: 'Sauvegarde en cours'
forecast.saved: 'Modifications sauvegardées'
forecast.conf: Configuration
forecast.start: 'Euros disponibles au départ'
forecast.month_earnings: 'Gains moyen par mois'
forecast.delay: 'Gérer délais de paiement'
forecast.repeat: 'Gérer répétitions'
forecast.monthly: 'Dépenses mensuelles'
forecast.benef: 'Bénef mensuel'
forecast.credit: 'Crédit mensuel réalisable (33% des gains moyens par mois)'
forecast.posts_title: 'Postes de dépenses mensuelles'
forecast.posts_text: 'Indiquez les catégories de dépenses mensuelles que vous faites pour faire évoluer la simulation de budget restant dans plusieurs mois.'
forecast.simulation: 'Simulation sur % mois'
forecast.table.warning_text: 'Ce sera la dèche dans % mois'
forecast.table.months: 'Month in the future'
forecast.table.date: date
forecast.table.expenses: Dépenses
forecast.table.availability: Disponibilité
forecast.columns.name: Nom
forecast.columns.monthly: 'prix mensuel'
forecast.columns.yearly: 'prix annuel'
forecast.columns.enabled: activé
forecast.example.title: 'Exemples de postes de dépenses à ajouter'
forecast.example.content: 'appartement mutuelle transport en commun assurance voiture assurance moto trucs de loisirs divers gaz elec internet épargne impots cottisation URSSAF resto au boulot courses serveur wouaibe abonnement protonmail VPN abonnement service audio, vidéo carburant véhicule donations médecin chat chien licorne '

View File

@ -8,6 +8,8 @@ composer self-update
composer update composer update
yarn --version yarn --version
bash compile-frontend.sh
yarn run encore production yarn run encore production
php bin/console doctrine:schema:update --dump-sql php bin/console doctrine:schema:update --dump-sql
php bin/console doctrine:schema:update --force php bin/console doctrine:schema:update --force

View File

@ -389,7 +389,7 @@ class SymfonyRequirements extends RequirementCollection
{ {
/* mandatory requirements follow */ /* mandatory requirements follow */
$installedPhpVersion = phpversion(); $installedPhpVersion = PHP_VERSION;
$requiredPhpVersion = $this->getPhpRequiredVersion(); $requiredPhpVersion = $this->getPhpRequiredVersion();
$this->addRecommendation( $this->addRecommendation(
@ -448,15 +448,8 @@ class SymfonyRequirements extends RequirementCollection
} }
if (false !== $requiredPhpVersion && version_compare($installedPhpVersion, $requiredPhpVersion, '>=')) { if (false !== $requiredPhpVersion && version_compare($installedPhpVersion, $requiredPhpVersion, '>=')) {
$timezones = array();
foreach (DateTimeZone::listAbbreviations() as $abbreviations) {
foreach ($abbreviations as $abbreviation) {
$timezones[$abbreviation['timezone_id']] = true;
}
}
$this->addRequirement( $this->addRequirement(
isset($timezones[@date_default_timezone_get()]), in_array(@date_default_timezone_get(), DateTimeZone::listIdentifiers(), true),
sprintf('Configured default timezone "%s" must be supported by your installation of PHP', @date_default_timezone_get()), sprintf('Configured default timezone "%s" must be supported by your installation of PHP', @date_default_timezone_get()),
'Your default timezone is not supported by PHP. Check for typos in your <strong>php.ini</strong> file and have a look at the list of deprecated timezones at <a href="http://php.net/manual/en/timezones.others.php">http://php.net/manual/en/timezones.others.php</a>.' 'Your default timezone is not supported by PHP. Check for typos in your <strong>php.ini</strong> file and have a look at the list of deprecated timezones at <a href="http://php.net/manual/en/timezones.others.php">http://php.net/manual/en/timezones.others.php</a>.'
); );
@ -731,7 +724,7 @@ class SymfonyRequirements extends RequirementCollection
'Install and/or enable a <strong>PHP accelerator</strong> (highly recommended).' 'Install and/or enable a <strong>PHP accelerator</strong> (highly recommended).'
); );
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { if ('WIN' === strtoupper(substr(PHP_OS, 0, 3))) {
$this->addRecommendation( $this->addRecommendation(
$this->getRealpathCacheSize() >= 5 * 1024 * 1024, $this->getRealpathCacheSize() >= 5 * 1024 * 1024,
'realpath_cache_size should be at least 5M in php.ini', 'realpath_cache_size should be at least 5M in php.ini',

3099
yarn.lock

File diff suppressed because it is too large Load Diff