diff --git a/.amber.yml b/.amber.yml
new file mode 100644
index 0000000..6eff810
--- /dev/null
+++ b/.amber.yml
@@ -0,0 +1,4 @@
+type: app
+database: pg
+language: slang
+model: granite
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..0113c5b
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,15 @@
+/doc/
+/lib/
+/.crystal/
+/.shards/
+/.vscode/
+/tmp/
+.env
+.encryption_key
+production.yml
+.DS_Store
+/bin/
+/node_modules
+/public/dist
+shard.lock
+package-lock.json
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..b0ea544
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,12 @@
+FROM amberframework/amber:v0.9.0
+
+WORKDIR /app
+
+COPY shard.* /app/
+RUN shards install
+
+COPY . /app
+
+RUN rm -rf /app/node_modules
+
+CMD amber watch
diff --git a/README.md b/README.md
index 34d538d..2ba5858 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,41 @@
# carnetdejeu
-Gérer sa collection de jeux vidéos, consoles et figurines.
-Et plus si affinités.
\ No newline at end of file
+Carnet de jeu (CDJ) est une application web permettant de gérer sa collection de jeux vidéos, consoles et figurines.
+
+Site officiel : [https://carnetdejeu.fr/](https://carnetdejeu.fr/)
+
+# Motivation
+
+L'idée principale de ce projet est d'avoir - enfin - un site web francophone concernant sa collection de jeux vidéos.
+
+Mais également d'avoir une alternative OpenSource au très connu Backloggery.com.
+
+# Pré-requis
+
+ * Crystal 0.26.0
+ * Amber 0.9.0
+ * shards 0.8.1
+
+# Installation des dépendances Crystal
+
+```bash
+shards install
+```
+
+# Aperçu de l'application
+
+```
+amber w
+```
+
+# Fabriqué avec
+
+ * [Amber](https://amberframework.org/) - framework pour créer des applications simples, rapides et agréables
+
+# Contributeurs
+
+ * Olivier DOSSMANN - création initiale - [blankoworld](https://github.com/blankoworld/)
+
+# Licence
+
+Ce projet est délivré sous les termes de la licence EUPL 1.2. Pour plus d’informations, veuillez lire [la licence EUPL 1.2](https://joinup.ec.europa.eu/collection/eupl/eupl-text-11-12).
diff --git a/config/application.cr b/config/application.cr
new file mode 100644
index 0000000..429e84c
--- /dev/null
+++ b/config/application.cr
@@ -0,0 +1,131 @@
+require "./initializers/**"
+
+require "amber"
+
+require "../src/controllers/application_controller"
+require "../src/controllers/**"
+
+# About Application.cr File
+#
+# This is Amber application main entry point. This file is responsible for loading
+# initializers, classes, and all application related code in order to have
+# Amber::Server boot up.
+#
+# > We recommend to not modify the order of the require since the order will
+# affect the behavior of the application.
+#
+# With `Amber::Server.configure` block you can redefine the Server configuration
+# settings and use ENVIRONMENT variables and/or values evaluated at runtime.
+#
+# > Important! Yaml configurations are first class citizen and are loaded first before
+# this file, we recommend to use yaml configurations before changing any settings here.
+# Any uncommented setting here will override the YAML with the value set here.
+
+Amber::Server.configure do |settings|
+ # Use your environment variables settings here.
+ #
+ # Name: A name that identifies this application. This is not internally
+ # used by the framework.
+ #
+ # settings.name = "Cdj Carnetdejeu web application."
+ #
+ #
+ # Colorize Logging: specifies whether or not to use ANSI color codes
+ # when logging information, display the time and/or to display the severity level.
+ # Defaults to true.
+ #
+ # Log Level defines the verbosity of the Amber logger. This option defaults to
+ # debug for all environments. The available log levels are: debug, info, warn,
+ # error, fatal, and unknown.
+ #
+ # settings.logging.colorize = true
+ # settings.logging.severity = "debug"
+ # settings.logging.filter = %w(password confirm_password)
+ # settings.logging.skip = %w()
+ # settings.logging.context = %w(request headers cookies session params)
+ #
+ #
+ # Secret Key Base: is used for specifying a key which allows sessions
+ # for the application to be verified against a known secure key to
+ # prevent tampering. Applications get Amber.secret_key
+ # initialized to a random key present in `ENV["AMBER_SECRET_KEY"]` or
+ # `.amber_secret_key` in this order.
+ #
+ # settings.secret_key_base= FEHWm3Fpm7vrPejFPM9x-3PLkj7C_fho6N-nIaBa19g
+ #
+ #
+ # Host: is the application server host address or ip address. Useful for when
+ # deploying Amber to a PAAS and likely the assigned server IP is either
+ # known or unknown. Defaults to an environment variable HOST
+ #
+ # settings.host = ENV["HOST"] if ENV["HOST"]?
+ #
+ #
+ # Port Reuse: Amber supports clustering mode which allows to spin
+ # multiple app instances per core. This setting allows to bind the different
+ # instances to the same port. Default this setting to true if the number or process
+ # is greater than 1.
+ #
+ # > Read more about Linux PORT REUSE https://lwn.net/Articles/542629/
+ #
+ # settings.port_reuse = true
+ #
+ #
+ # Process Count: This will enable Amber to be used in cluster mode,
+ # spinning an instance for each number of process specified here.
+ # Rule of thumb, always leave at least 1 core available for system processes/resources.
+ #
+ # settings.process_count = ENV["PROCESS_COUNT"].to_i if ENV["PROCESS_COUNT"]?
+ #
+ #
+ # PORT: This is the port that you're application will run on. Examples would be (80, 443, 3000, 8080)
+ #
+ settings.port = ENV["PORT"].to_i if ENV["PORT"]?
+ #
+ #
+ # Redis URL: Redis is an in memory key value storage. Amber utilizes redis as
+ # a storing option for session information.
+ #
+ # settings.redis_url = ENV["REDIS_URL"] if ENV["REDIS_URL"]?
+ #
+ #
+ # Database URL: This is the database connection string or data file url.
+ # The connection string contains the information to establish a connection to the
+ # database or the data file. Defaults to the database provider you chose at
+ # at app generation.
+ #
+ # settings.database_url = ENV["DATABASE_URL"] if ENV["DATABASE_URL"]?
+ #
+ #
+ # SSL Key File: The private key is a text file used initially to generate a
+ # Certificate Signing Request (CSR), and later to secure and verify connections
+ # using the certificate created per that request. The private key is used to create
+ # a digital signature as you might imagine from the name, the private key should be
+ # ``closely guarded.
+ #
+ # settings.ssl_key_file = ENV["SSL_KEY_FILE"] if ENV["SSL_KEY_FILE"]?
+ #
+ #
+ # SSL Cert File: This represents the signed certificate file. SSL Certificates are
+ # small data files that digitally bind a cryptographic key to an organization's
+ # details. When installed on a web server, it activates the padlock and the https
+ # protocol and allows secure connections from a web server to a browser.
+ #
+ # settings.ssl_cert_file = ENV["SSL_CERT_FILE"] if ENV["SSL_CERT_FILE"]?
+ #
+ #
+ # Session: A Hash that specifies the session storage mechanism, expiration and key to be used
+ # for the application. The `key` specifies the name of the cookie to be used defaults to
+ # "amber.session". The store can be `encrypted_cookie`, `signed_cookie` or `redis`. Expires
+ # when set to 0 means this is indefinitely and is expressed in seconds.
+ #
+ # settings.session = { "key" => "amber.session", "store" => "signed_cookie", "expires" => 0 }
+ #
+ #
+ # Logger: is the logger that Amber and other capable shards in the project will use
+ # instead of writing directly to STDOUT. Supply a custom logger to write to syslog, etc.
+ #
+ # settings.logger = Amber::Environment::Logger.new(File.open("cdj_carnetdejeu.log", "w"))
+ #
+ #
+end
diff --git a/config/environments/.production.enc b/config/environments/.production.enc
new file mode 100644
index 0000000..14d3405
Binary files /dev/null and b/config/environments/.production.enc differ
diff --git a/config/environments/development.yml b/config/environments/development.yml
new file mode 100644
index 0000000..5a5edc1
--- /dev/null
+++ b/config/environments/development.yml
@@ -0,0 +1,36 @@
+secret_key_base: cie0hbJtXS-F51akAYdEeNof67tLG4q-L5bpaLqgPTE
+port: 3000
+name: cdj_carnetdejeu
+
+logging:
+ severity: debug
+ colorize: true
+ filter:
+ - password
+ - confirm_password
+ context:
+ - request
+ - session
+ - headers
+ - cookies
+ - params
+
+host: 0.0.0.0
+port_reuse: true
+process_count: 1
+# ssl_key_file:
+# ssl_cert_file:
+redis_url: "redis://localhost:6379"
+database_url: postgres://postgres:@localhost:5432/cdj_carnetdejeu_development
+
+session:
+ key: amber.session
+ store: signed_cookie
+ expires: 0
+
+smtp:
+ enabled: false
+
+secrets:
+ description: Store your development secrets credentials and settings here.
+
diff --git a/config/environments/test.yml b/config/environments/test.yml
new file mode 100644
index 0000000..f90f93f
--- /dev/null
+++ b/config/environments/test.yml
@@ -0,0 +1,36 @@
+secret_key_base: 2jEkAoKdioIl6U1W0T-Zu2U7V5HRQ3-GpeIxOeEVjms
+port: 3000
+name: cdj_carnetdejeu
+
+logging:
+ severity: debug
+ colorize: true
+ filter:
+ - password
+ - confirm_password
+ context:
+ - request
+ - session
+ - headers
+ - cookies
+ - params
+
+host: 0.0.0.0
+port_reuse: false
+process_count: 1
+# ssl_key_file:
+# ssl_cert_file:
+redis_url: "redis://localhost:6379"
+database_url: postgres://postgres:@localhost:5432/cdj_carnetdejeu_test
+
+session:
+ key: amber.session
+ store: signed_cookie
+ expires: 0
+
+smtp:
+ enabled: false
+
+secrets:
+ description: Store your development secrets credentials and settings here.
+
diff --git a/config/initializers/database.cr b/config/initializers/database.cr
new file mode 100644
index 0000000..69378b7
--- /dev/null
+++ b/config/initializers/database.cr
@@ -0,0 +1,6 @@
+require "granite/adapter/pg"
+
+Granite::Adapters << Granite::Adapter::Pg.new({name: "pg", url: Amber.settings.database_url})
+Granite.settings.logger = Amber.settings.logger.dup
+Granite.settings.logger.progname = "Granite"
+
diff --git a/config/initializers/i18n.cr b/config/initializers/i18n.cr
new file mode 100644
index 0000000..1b005b2
--- /dev/null
+++ b/config/initializers/i18n.cr
@@ -0,0 +1,24 @@
+require "citrine-i18n"
+
+Citrine::I18n.configure do |settings|
+ # Backend storage (as supported by i18n.cr)
+ # settings.backend = I18n::Backend::Yaml.new
+
+ # Default locale (defaults to "en" and "./src/locales/**/en.yml").
+ # For a new default locale to be accepted, it must be found by the
+ # backend storage and reported in "settings.available_locales".
+ # settings.default_locale = "en"
+
+ # Separator between sublevels of data (defaults to '.')
+ # e.g. I18n.translate("some/thing") instead of "some.thing"
+ # settings.default_separator = '.'
+
+ # Returns the current exception handler. Defaults to an instance of
+ # I18n::ExceptionHandler.
+ # settings.exception_handler = ExceptionHandler.new
+
+ # The path from where the translations should be loaded
+ settings.load_path += ["./src/locales"]
+end
+
+I18n.init
diff --git a/config/routes.cr b/config/routes.cr
new file mode 100644
index 0000000..0c9e0e3
--- /dev/null
+++ b/config/routes.cr
@@ -0,0 +1,42 @@
+Amber::Server.configure do
+ pipeline :web do
+ # Plug is the method to use connect a pipe (middleware)
+ # A plug accepts an instance of HTTP::Handler
+ plug Amber::Pipe::PoweredByAmber.new
+ # plug Amber::Pipe::ClientIp.new(["X-Forwarded-For"])
+ plug Citrine::I18n::Handler.new
+ plug Amber::Pipe::Error.new
+ plug Amber::Pipe::Logger.new
+ plug Amber::Pipe::Session.new
+ plug Amber::Pipe::Flash.new
+ plug Amber::Pipe::CSRF.new
+ end
+
+ pipeline :api do
+ plug Amber::Pipe::PoweredByAmber.new
+ plug Amber::Pipe::Error.new
+ plug Amber::Pipe::Logger.new
+ plug Amber::Pipe::Session.new
+ plug Amber::Pipe::CORS.new
+ end
+
+ # All static content will run these transformations
+ pipeline :static do
+ plug Amber::Pipe::PoweredByAmber.new
+ plug Amber::Pipe::Error.new
+ plug Amber::Pipe::Static.new("./public")
+ end
+
+ routes :web do
+ get "/", HomeController, :index
+ end
+
+ routes :api do
+ end
+
+ routes :static do
+ # Each route is defined as follow
+ # verb resource : String, controller : Symbol, action : Symbol
+ get "/*", Amber::Controller::Static, :index
+ end
+end
diff --git a/config/webpack/common.js b/config/webpack/common.js
new file mode 100644
index 0000000..336418e
--- /dev/null
+++ b/config/webpack/common.js
@@ -0,0 +1,69 @@
+const webpack = require('webpack');
+const path = require('path');
+const ExtractTextPlugin = require('extract-text-webpack-plugin');
+
+let config = {
+ entry: {
+ 'main.bundle.js': './src/assets/javascripts/main.js',
+ 'main.bundle.css': './src/assets/stylesheets/main.scss'
+ },
+ output: {
+ filename: '[name]',
+ path: path.resolve(__dirname, '../../public/dist'),
+ publicPath: '/dist'
+ },
+ resolve: {
+ alias: {
+ amber: path.resolve(__dirname, '../../lib/amber/assets/js/amber.js')
+ }
+ },
+ module: {
+ rules: [
+ {
+ test: /\.css$/,
+ exclude: /node_modules/,
+ use: ExtractTextPlugin.extract({
+ fallback: 'style-loader',
+ use: 'css-loader'
+ })
+ },
+ {
+ test: /\.scss$/,
+ exclude: /node_modules/,
+ use: ExtractTextPlugin.extract({
+ fallback: 'style-loader',
+ use: ['css-loader', 'sass-loader']
+ })
+ },
+ {
+ test: /\.(png|svg|jpg|gif)$/,
+ exclude: /node_modules/,
+ use: [
+ 'file-loader?name=/images/[name].[ext]'
+ ]
+ },
+ {
+ test: /\.(woff|woff2|eot|ttf|otf)$/,
+ exclude: /node_modules/,
+ use: [
+ 'file-loader?name=/[name].[ext]'
+ ]
+ },
+ {
+ test: /\.js?$/,
+ exclude: /node_modules/,
+ loader: 'babel-loader',
+ query: {
+ presets: ['env']
+ }
+ }
+ ]
+ },
+ plugins: [
+ new ExtractTextPlugin('main.bundle.css'),
+ ],
+ // For more info about webpack logs see: https://webpack.js.org/configuration/stats/
+ stats: 'errors-only'
+};
+
+module.exports = config;
diff --git a/config/webpack/development.js b/config/webpack/development.js
new file mode 100644
index 0000000..3ec0d95
--- /dev/null
+++ b/config/webpack/development.js
@@ -0,0 +1,7 @@
+const webpack = require('webpack');
+const merge = require('webpack-merge');
+const common = require('./common.js');
+
+module.exports = merge(common, {
+ devtool: 'inline-source-map'
+});
diff --git a/config/webpack/production.js b/config/webpack/production.js
new file mode 100644
index 0000000..4a44b47
--- /dev/null
+++ b/config/webpack/production.js
@@ -0,0 +1,11 @@
+const webpack = require('webpack');
+const merge = require('webpack-merge');
+const common = require('./common.js');
+
+module.exports = merge(common, {
+ plugins: [
+ new webpack.optimize.UglifyJsPlugin({
+ compress: { warnings: false }
+ })
+ ]
+});
diff --git a/db/migrations/.gitkeep b/db/migrations/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..13ff841
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,42 @@
+version: '2'
+
+services:
+ app:
+ build: .
+ image: cdj_carnetdejeu
+ command: amber watch
+ environment:
+ DATABASE_URL: postgres://admin:password@db:5432/cdj_carnetdejeu_development
+ ports:
+ - 3000:3000
+ links:
+ - db
+ volumes:
+ - .:/app
+ - nodes:/app/node_modules
+ - shards:/app/lib
+
+ migrate:
+ build: .
+ image: cdj_carnetdejeu
+ command: bash -c 'while ! nc -q 1 db 5432
+
+
+
+
+
+
+
+
+
+
diff --git a/public/favicon.ico b/public/favicon.ico
new file mode 100644
index 0000000..edb2d9c
Binary files /dev/null and b/public/favicon.ico differ
diff --git a/public/favicon.png b/public/favicon.png
new file mode 100644
index 0000000..850d724
Binary files /dev/null and b/public/favicon.png differ
diff --git a/public/robots.txt b/public/robots.txt
new file mode 100644
index 0000000..f591645
--- /dev/null
+++ b/public/robots.txt
@@ -0,0 +1,3 @@
+# http://www.robotstxt.org
+User-agent: *
+Disallow:
diff --git a/shard.yml b/shard.yml
new file mode 100644
index 0000000..6c3eab6
--- /dev/null
+++ b/shard.yml
@@ -0,0 +1,47 @@
+name: cdj_carnetdejeu
+version: 0.1.0
+
+authors:
+ - Olivier DOSSMANN
+
+crystal: 0.26.0
+
+license: UNLICENSED
+
+targets:
+ cdj_carnetdejeu:
+ main: src/cdj_carnetdejeu.cr
+
+ amber:
+ main: lib/amber/src/amber/cli.cr
+
+dependencies:
+ amber:
+ github: amberframework/amber
+ version: 0.9.0
+ #branch: master
+
+ granite:
+ github: amberframework/granite
+ version: ~> 0.13.0
+
+ quartz_mailer:
+ github: amberframework/quartz-mailer
+ version: ~> 0.5.1
+
+ jasper_helpers:
+ github: amberframework/jasper-helpers
+ version: ~> 0.2.0
+
+ pg:
+ github: will/crystal-pg
+ version: ~> 0.15.0
+
+ citrine-i18n:
+ github: amberframework/citrine-i18n
+ version: 0.3.2
+
+development_dependencies:
+ garnet_spec:
+ github: amberframework/garnet-spec
+ version: ~> 0.2.1
diff --git a/spec/spec_helper.cr b/spec/spec_helper.cr
new file mode 100644
index 0000000..ecec995
--- /dev/null
+++ b/spec/spec_helper.cr
@@ -0,0 +1,16 @@
+ENV["AMBER_ENV"] ||= "test"
+
+require "spec"
+require "micrate"
+require "garnet_spec"
+
+require "../config/*"
+
+Micrate::DB.connection_url = Amber.settings.database_url
+
+# Automatically run migrations on the test database
+Micrate::Cli.run_up
+
+# Disable Granite logs in tests
+Granite.settings.logger = Logger.new nil
+
diff --git a/src/assets/fonts/.gitkeep b/src/assets/fonts/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/src/assets/images/.gitkeep b/src/assets/images/.gitkeep
new file mode 100644
index 0000000..e69de29
diff --git a/src/assets/images/logo.png b/src/assets/images/logo.png
new file mode 100644
index 0000000..457789a
Binary files /dev/null and b/src/assets/images/logo.png differ
diff --git a/src/assets/javascripts/main.js b/src/assets/javascripts/main.js
new file mode 100644
index 0000000..4b3eb94
--- /dev/null
+++ b/src/assets/javascripts/main.js
@@ -0,0 +1,23 @@
+import Amber from 'amber'
+
+if (!Date.prototype.toGranite) {
+ (function() {
+
+ function pad(number) {
+ if (number < 10) {
+ return '0' + number;
+ }
+ return number;
+ }
+
+ Date.prototype.toGranite = function() {
+ return this.getUTCFullYear() +
+ '-' + pad(this.getUTCMonth() + 1) +
+ '-' + pad(this.getUTCDate()) +
+ ' ' + pad(this.getUTCHours()) +
+ ':' + pad(this.getUTCMinutes()) +
+ ':' + pad(this.getUTCSeconds()) ;
+ };
+
+ }());
+}
diff --git a/src/assets/stylesheets/main.scss b/src/assets/stylesheets/main.scss
new file mode 100644
index 0000000..638d392
--- /dev/null
+++ b/src/assets/stylesheets/main.scss
@@ -0,0 +1,117 @@
+$font-stack: "Helvetica Neue", Helvetica, Arial, sans-serif;
+$background-color: #f4994b;
+$nav-item-color: #ffe4cd;
+
+/*
+ * Globals
+ */
+body {
+ font-family: $font-stack;
+ color: #555;
+}
+
+h1, .h1,
+h2, .h2,
+h3, .h3,
+h4, .h4,
+h5, .h5,
+h6, .h6 {
+ margin-top: 0;
+ font-family: $font-stack;
+ font-weight: normal;
+ color: #333;
+}
+
+/*
+ * Override Bootstrap's default container.
+ */
+@media (min-width: 1200px) {
+ .container {
+ width: 970px;
+ }
+}
+
+/*
+ * Masthead for nav
+ */
+.masthead {
+ background-color: $background-color;
+ -webkit-box-shadow: inset 0 -2px 5px rgba(0,0,0,.1);
+ box-shadow: inset 0 -2px 5px rgba(0,0,0,.1);
+}
+
+/* Nav links */
+.nav-item {
+ position: relative;
+ display: inline-block;
+ padding: 10px;
+ font-weight: 500;
+ color: $nav-item-color;
+}
+.nav-item:hover,
+.nav-item:focus {
+ color: #fff;
+ text-decoration: none;
+}
+
+/* Active state gets a caret at the bottom */
+.nav .active {
+ color: #fff;
+}
+.nav .active:after {
+ position: absolute;
+ bottom: 0;
+ left: 50%;
+ width: 0;
+ height: 0;
+ margin-left: -5px;
+ vertical-align: middle;
+ content: " ";
+ border-right: 5px solid transparent;
+ border-bottom: 5px solid;
+ border-left: 5px solid transparent;
+}
+
+.main {
+ padding-top: 20px;
+}
+
+#logo {
+ background-color: $background-color;
+ background-image: url("../images/logo.png");
+ background-size:contain;
+ width: 200px;
+ height:278px;
+}
+
+/* Hide logo in small screens */
+@media (max-width: 767px) {
+ #logo {
+ display: none;
+ }
+}
+
+.table td, .table th {
+ vertical-align: middle;
+}
+
+.alert {
+ margin-top: 1em;
+
+ p {
+ margin-top: 0;
+ margin-bottom: 0;
+ }
+}
+
+// For Navigation pulling right
+.nav-item-auth {
+ &.nav-item-auth-signout, &.nav-item-auth-signup {
+ order: 9999;
+ }
+
+ &.nav-item-auth-profile, &.nav-item-auth-signin {
+ order: 9990;
+ margin-left: auto;
+ }
+}
\ No newline at end of file
diff --git a/src/cdj_carnetdejeu.cr b/src/cdj_carnetdejeu.cr
new file mode 100644
index 0000000..66d2b28
--- /dev/null
+++ b/src/cdj_carnetdejeu.cr
@@ -0,0 +1,3 @@
+require "../config/*"
+
+Amber::Server.start
diff --git a/src/controllers/application_controller.cr b/src/controllers/application_controller.cr
new file mode 100644
index 0000000..0967557
--- /dev/null
+++ b/src/controllers/application_controller.cr
@@ -0,0 +1,6 @@
+require "jasper_helpers"
+
+class ApplicationController < Amber::Controller::Base
+ include JasperHelpers
+ LAYOUT = "application.slang"
+end
diff --git a/src/controllers/home_controller.cr b/src/controllers/home_controller.cr
new file mode 100644
index 0000000..2543e78
--- /dev/null
+++ b/src/controllers/home_controller.cr
@@ -0,0 +1,5 @@
+class HomeController < ApplicationController
+ def index
+ render("index.slang")
+ end
+end
diff --git a/src/locales/en.yml b/src/locales/en.yml
new file mode 100644
index 0000000..28c4419
--- /dev/null
+++ b/src/locales/en.yml
@@ -0,0 +1,2 @@
+---
+welcome_to_amber: "Welcome to Amber Framework!"
diff --git a/src/views/home/index.slang b/src/views/home/index.slang
new file mode 100644
index 0000000..1dbac34
--- /dev/null
+++ b/src/views/home/index.slang
@@ -0,0 +1,9 @@
+.row
+ #logo
+ .col-sm-12.col-md-6
+ h2 = t "welcome_to_amber"
+ p Thank you for trying out the Amber Framework. We are working hard to provide a super fast and reliable framework that provides all the productivity tools you are used to without sacrificing the speed.
+ .list-group
+ a.list-group-item.list-group-item-action target="_blank" href="https://docs.amberframework.org" Getting Started with Amber Framework
+ a.list-group-item.list-group-item-action target="_blank" href="https://github.com/veelenga/awesome-crystal" List of Awesome Crystal projects and shards
+ a.list-group-item.list-group-item-action target="_blank" href="https://crystalshards.xyz" What's hot in Crystal right now
diff --git a/src/views/layouts/_nav.slang b/src/views/layouts/_nav.slang
new file mode 100644
index 0000000..0888270
--- /dev/null
+++ b/src/views/layouts/_nav.slang
@@ -0,0 +1,2 @@
+- active = context.request.path == "/" ? "active" : ""
+a class="nav-item #{active}" href="/" Home
diff --git a/src/views/layouts/application.slang b/src/views/layouts/application.slang
new file mode 100644
index 0000000..aa83d80
--- /dev/null
+++ b/src/views/layouts/application.slang
@@ -0,0 +1,32 @@
+doctype html
+html
+ head
+ title Cdj Carnetdejeu using Amber
+ meta charset="utf-8"
+ meta http-equiv="X-UA-Compatible" content="IE=edge"
+ meta name="viewport" content="width=device-width, initial-scale=1"
+ link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css"
+ link rel="stylesheet" href="/dist/main.bundle.css"
+ link rel="apple-touch-icon" href="/favicon.png"
+ link rel="icon" href="/favicon.png"
+ link rel="icon" type="image/x-icon" href="/favicon.ico"
+
+ body
+ .masthead
+ .container
+ nav.nav
+ == render(partial: "layouts/_nav.slang")
+ .container
+ .row
+ .col-sm
+ - flash.each do |key, value|
+ div class="alert alert-#{key}"
+ p = flash[key]
+ .row
+ .col-sm-12.main
+ == content
+
+ script src="https://code.jquery.com/jquery-3.3.1.min.js"
+ script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"
+ script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"
+ script src="/dist/main.bundle.js"