Browse Source

Création initiale du projet Amber

master
Olivier DOSSMANN 10 months ago
parent
commit
6d4cadc2ae

+ 4
- 0
.amber.yml View File

@@ -0,0 +1,4 @@
1
+type: app
2
+database: pg
3
+language: slang
4
+model: granite

+ 15
- 0
.gitignore View File

@@ -0,0 +1,15 @@
1
+/doc/
2
+/lib/
3
+/.crystal/
4
+/.shards/
5
+/.vscode/
6
+/tmp/
7
+.env
8
+.encryption_key
9
+production.yml
10
+.DS_Store
11
+/bin/
12
+/node_modules
13
+/public/dist
14
+shard.lock
15
+package-lock.json

+ 12
- 0
Dockerfile View File

@@ -0,0 +1,12 @@
1
+FROM amberframework/amber:v0.9.0
2
+
3
+WORKDIR /app
4
+
5
+COPY shard.* /app/
6
+RUN shards install 
7
+
8
+COPY . /app
9
+
10
+RUN rm -rf /app/node_modules
11
+
12
+CMD amber watch

+ 39
- 2
README.md View File

@@ -1,4 +1,41 @@
1 1
 # carnetdejeu
2 2
 
3
-Gérer sa collection de jeux vidéos, consoles et figurines.
4
-Et plus si affinités.
3
+Carnet de jeu (CDJ) est une application web permettant de gérer sa collection de jeux vidéos, consoles et figurines.
4
+
5
+Site officiel : [https://carnetdejeu.fr/](https://carnetdejeu.fr/)
6
+
7
+# Motivation
8
+
9
+L'idée principale de ce projet est d'avoir - enfin - un site web francophone concernant sa collection de jeux vidéos.
10
+
11
+Mais également d'avoir une alternative OpenSource au très connu Backloggery.com.
12
+
13
+# Pré-requis
14
+
15
+  * Crystal 0.26.0
16
+  * Amber 0.9.0
17
+  * shards 0.8.1
18
+
19
+# Installation des dépendances Crystal
20
+
21
+```bash
22
+shards install
23
+```
24
+
25
+# Aperçu de l'application
26
+
27
+```
28
+amber w
29
+```
30
+
31
+# Fabriqué avec
32
+
33
+  * [Amber](https://amberframework.org/) - framework pour créer des applications simples, rapides et agréables
34
+
35
+# Contributeurs
36
+
37
+  * Olivier DOSSMANN - création initiale - [blankoworld](https://github.com/blankoworld/)
38
+
39
+# Licence
40
+
41
+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).

+ 131
- 0
config/application.cr View File

@@ -0,0 +1,131 @@
1
+require "./initializers/**"
2
+
3
+require "amber"
4
+
5
+require "../src/controllers/application_controller"
6
+require "../src/controllers/**"
7
+
8
+# About Application.cr File
9
+#
10
+# This is Amber application main entry point. This file is responsible for loading
11
+# initializers, classes, and all application related code in order to have
12
+# Amber::Server boot up.
13
+#
14
+# > We recommend to not modify the order of the require since the order will
15
+# affect the behavior of the application.
16
+#
17
+# With `Amber::Server.configure` block you can redefine the Server configuration
18
+# settings and use ENVIRONMENT variables and/or values evaluated at runtime.
19
+#
20
+# > Important! Yaml configurations are first class citizen and are loaded first before
21
+# this file, we recommend to use yaml configurations before changing any settings here.
22
+# Any uncommented setting here will override the YAML with the value set here.
23
+
24
+Amber::Server.configure do |settings|
25
+  # Use your environment variables settings here.
26
+  #
27
+  # Name: A name that identifies this application. This is not internally
28
+  # used by the framework.
29
+  #
30
+  # settings.name = "Cdj Carnetdejeu web application."
31
+  #
32
+  #
33
+  # Colorize Logging: specifies whether or not to use ANSI color codes
34
+  # when logging information, display the time and/or to display the severity level.
35
+  # Defaults to true.
36
+  #
37
+  # Log Level defines the verbosity of the Amber logger. This option defaults to
38
+  # debug for all environments. The available log levels are: debug, info, warn,
39
+  # error, fatal, and unknown.
40
+  #
41
+  # settings.logging.colorize = true
42
+  # settings.logging.severity = "debug"
43
+  # settings.logging.filter = %w(password confirm_password)
44
+  # settings.logging.skip = %w()
45
+  # settings.logging.context = %w(request headers cookies session params)
46
+  #
47
+  #
48
+  # Secret Key Base: is used for specifying a key which allows sessions
49
+  # for the application to be verified against a known secure key to
50
+  # prevent tampering. Applications get Amber.secret_key
51
+  # initialized to a random key present in `ENV["AMBER_SECRET_KEY"]` or
52
+  # `.amber_secret_key` in this order.
53
+  #
54
+  # settings.secret_key_base= FEHWm3Fpm7vrPejFPM9x-3PLkj7C_fho6N-nIaBa19g
55
+  #
56
+  #
57
+  # Host: is the application server host address or ip address. Useful for when
58
+  # deploying Amber to a PAAS and likely the assigned server IP is either
59
+  # known or unknown. Defaults to an environment variable HOST
60
+  #
61
+  # settings.host = ENV["HOST"] if ENV["HOST"]?
62
+  #
63
+  #
64
+  # Port Reuse: Amber supports clustering mode which allows to spin
65
+  # multiple app instances per core. This setting allows to bind the different
66
+  # instances to the same port. Default this setting to true if the number or process
67
+  # is greater than 1.
68
+  #
69
+  # > Read more about Linux PORT REUSE https://lwn.net/Articles/542629/
70
+  #
71
+  # settings.port_reuse = true
72
+  #
73
+  #
74
+  # Process Count: This will enable Amber to be used in cluster mode,
75
+  # spinning an instance for each number of process specified here.
76
+  # Rule of thumb, always leave at least 1 core available for system processes/resources.
77
+  #
78
+  # settings.process_count = ENV["PROCESS_COUNT"].to_i if ENV["PROCESS_COUNT"]?
79
+  #
80
+  #
81
+  # PORT: This is the port that you're application will run on. Examples would be (80, 443, 3000, 8080)
82
+  #
83
+  settings.port = ENV["PORT"].to_i if ENV["PORT"]?
84
+  #
85
+  #
86
+  # Redis URL: Redis is an in memory key value storage. Amber utilizes redis as
87
+  # a storing option for session information.
88
+  #
89
+  # settings.redis_url = ENV["REDIS_URL"] if ENV["REDIS_URL"]?
90
+  #
91
+  #
92
+  # Database URL: This is the database connection string or data file url.
93
+  # The connection string contains the information to establish a connection to the
94
+  # database or the data file. Defaults to the database provider you chose at
95
+  # at app generation.
96
+  #
97
+  # settings.database_url = ENV["DATABASE_URL"] if ENV["DATABASE_URL"]?
98
+  #
99
+  #
100
+  # SSL Key File: The private key is a text file used initially to generate a
101
+  # Certificate Signing Request (CSR), and later to secure and verify connections
102
+  # using the certificate created per that request. The private key is used to create
103
+  # a digital signature as you might imagine from the name, the private key should be
104
+  # ``closely guarded.
105
+  #
106
+  # settings.ssl_key_file = ENV["SSL_KEY_FILE"] if ENV["SSL_KEY_FILE"]?
107
+  #
108
+  #
109
+  # SSL Cert File: This represents the signed certificate file. SSL Certificates are
110
+  # small data files that digitally bind a cryptographic key to an organization's
111
+  # details. When installed on a web server, it activates the padlock and the https
112
+  # protocol and allows secure connections from a web server to a browser.
113
+  #
114
+  # settings.ssl_cert_file = ENV["SSL_CERT_FILE"] if ENV["SSL_CERT_FILE"]?
115
+  #
116
+  #
117
+  # Session: A Hash that specifies the session storage mechanism, expiration and key to be used
118
+  # for the application. The `key` specifies the name of the cookie to be used defaults to
119
+  # "amber.session". The store can be `encrypted_cookie`, `signed_cookie` or `redis`. Expires
120
+  # when set to 0 means this is indefinitely and is expressed in seconds.
121
+  #
122
+  # settings.session = { "key" => "amber.session", "store" => "signed_cookie", "expires" => 0 }
123
+  #
124
+  #
125
+  # Logger: is the logger that Amber and other capable shards in the project will use
126
+  # instead of writing directly to STDOUT. Supply a custom logger to write to syslog, etc.
127
+  #
128
+  # settings.logger = Amber::Environment::Logger.new(File.open("cdj_carnetdejeu.log", "w"))
129
+  #
130
+  #
131
+end

BIN
config/environments/.production.enc View File


+ 36
- 0
config/environments/development.yml View File

@@ -0,0 +1,36 @@
1
+secret_key_base: cie0hbJtXS-F51akAYdEeNof67tLG4q-L5bpaLqgPTE
2
+port: 3000
3
+name: cdj_carnetdejeu
4
+
5
+logging:
6
+  severity: debug
7
+  colorize: true
8
+  filter:
9
+    - password
10
+    - confirm_password
11
+  context:
12
+    - request
13
+    - session
14
+    - headers
15
+    - cookies
16
+    - params
17
+
18
+host: 0.0.0.0
19
+port_reuse: true
20
+process_count: 1
21
+# ssl_key_file:
22
+# ssl_cert_file:
23
+redis_url: "redis://localhost:6379"
24
+database_url: postgres://postgres:@localhost:5432/cdj_carnetdejeu_development
25
+
26
+session:
27
+  key: amber.session
28
+  store: signed_cookie
29
+  expires: 0
30
+
31
+smtp:
32
+  enabled: false
33
+
34
+secrets:
35
+  description: Store your development secrets credentials and settings here.
36
+

+ 36
- 0
config/environments/test.yml View File

@@ -0,0 +1,36 @@
1
+secret_key_base: 2jEkAoKdioIl6U1W0T-Zu2U7V5HRQ3-GpeIxOeEVjms
2
+port: 3000
3
+name: cdj_carnetdejeu
4
+
5
+logging:
6
+  severity: debug
7
+  colorize: true
8
+  filter:
9
+    - password
10
+    - confirm_password
11
+  context:
12
+    - request
13
+    - session
14
+    - headers
15
+    - cookies
16
+    - params
17
+
18
+host: 0.0.0.0
19
+port_reuse: false
20
+process_count: 1
21
+# ssl_key_file:
22
+# ssl_cert_file:
23
+redis_url: "redis://localhost:6379"
24
+database_url: postgres://postgres:@localhost:5432/cdj_carnetdejeu_test
25
+
26
+session:
27
+  key: amber.session
28
+  store: signed_cookie
29
+  expires: 0
30
+
31
+smtp:
32
+  enabled: false
33
+
34
+secrets:
35
+  description: Store your development secrets credentials and settings here.
36
+

+ 6
- 0
config/initializers/database.cr View File

@@ -0,0 +1,6 @@
1
+require "granite/adapter/pg"
2
+
3
+Granite::Adapters << Granite::Adapter::Pg.new({name: "pg", url: Amber.settings.database_url})
4
+Granite.settings.logger = Amber.settings.logger.dup
5
+Granite.settings.logger.progname = "Granite"
6
+

+ 24
- 0
config/initializers/i18n.cr View File

@@ -0,0 +1,24 @@
1
+require "citrine-i18n"
2
+
3
+Citrine::I18n.configure do |settings|
4
+  # Backend storage (as supported by i18n.cr)
5
+  # settings.backend = I18n::Backend::Yaml.new
6
+
7
+  # Default locale (defaults to "en" and "./src/locales/**/en.yml").
8
+  # For a new default locale to be accepted, it must be found by the
9
+  # backend storage and reported in "settings.available_locales".
10
+  # settings.default_locale = "en"
11
+
12
+  # Separator between sublevels of data (defaults to '.')
13
+  # e.g. I18n.translate("some/thing") instead of "some.thing"
14
+  # settings.default_separator = '.'
15
+
16
+  # Returns the current exception handler. Defaults to an instance of
17
+  # I18n::ExceptionHandler.
18
+  # settings.exception_handler = ExceptionHandler.new
19
+
20
+  # The path from where the translations should be loaded
21
+  settings.load_path += ["./src/locales"]
22
+end
23
+
24
+I18n.init

+ 42
- 0
config/routes.cr View File

@@ -0,0 +1,42 @@
1
+Amber::Server.configure do
2
+  pipeline :web do
3
+    # Plug is the method to use connect a pipe (middleware)
4
+    # A plug accepts an instance of HTTP::Handler
5
+    plug Amber::Pipe::PoweredByAmber.new
6
+    # plug Amber::Pipe::ClientIp.new(["X-Forwarded-For"])
7
+    plug Citrine::I18n::Handler.new
8
+    plug Amber::Pipe::Error.new
9
+    plug Amber::Pipe::Logger.new
10
+    plug Amber::Pipe::Session.new
11
+    plug Amber::Pipe::Flash.new
12
+    plug Amber::Pipe::CSRF.new
13
+  end
14
+
15
+  pipeline :api do
16
+    plug Amber::Pipe::PoweredByAmber.new
17
+    plug Amber::Pipe::Error.new
18
+    plug Amber::Pipe::Logger.new
19
+    plug Amber::Pipe::Session.new
20
+    plug Amber::Pipe::CORS.new
21
+  end
22
+
23
+  # All static content will run these transformations
24
+  pipeline :static do
25
+    plug Amber::Pipe::PoweredByAmber.new
26
+    plug Amber::Pipe::Error.new
27
+    plug Amber::Pipe::Static.new("./public")
28
+  end
29
+
30
+  routes :web do
31
+    get "/", HomeController, :index
32
+  end
33
+
34
+  routes :api do
35
+  end
36
+
37
+  routes :static do
38
+    # Each route is defined as follow
39
+    # verb resource : String, controller : Symbol, action : Symbol
40
+    get "/*", Amber::Controller::Static, :index
41
+  end
42
+end

+ 69
- 0
config/webpack/common.js View File

@@ -0,0 +1,69 @@
1
+const webpack = require('webpack');
2
+const path = require('path');
3
+const ExtractTextPlugin = require('extract-text-webpack-plugin');
4
+
5
+let config = {
6
+  entry: {
7
+    'main.bundle.js': './src/assets/javascripts/main.js',
8
+    'main.bundle.css': './src/assets/stylesheets/main.scss'
9
+  },
10
+  output: {
11
+    filename: '[name]',
12
+    path: path.resolve(__dirname, '../../public/dist'),
13
+    publicPath: '/dist'
14
+  },
15
+  resolve: {
16
+    alias: {
17
+      amber: path.resolve(__dirname, '../../lib/amber/assets/js/amber.js')
18
+    }
19
+  },
20
+  module: {
21
+    rules: [
22
+      {
23
+        test: /\.css$/,
24
+        exclude: /node_modules/,
25
+        use: ExtractTextPlugin.extract({
26
+          fallback: 'style-loader',
27
+          use: 'css-loader'
28
+        })
29
+      },
30
+      {
31
+        test: /\.scss$/,
32
+        exclude: /node_modules/,
33
+        use: ExtractTextPlugin.extract({
34
+          fallback: 'style-loader',
35
+          use: ['css-loader', 'sass-loader']
36
+        })
37
+      },
38
+      {
39
+        test: /\.(png|svg|jpg|gif)$/,
40
+        exclude: /node_modules/,
41
+        use: [
42
+          'file-loader?name=/images/[name].[ext]'
43
+        ]
44
+      },
45
+      {
46
+        test: /\.(woff|woff2|eot|ttf|otf)$/,
47
+        exclude: /node_modules/,
48
+        use: [
49
+          'file-loader?name=/[name].[ext]'
50
+        ]
51
+      },
52
+      {
53
+        test: /\.js?$/,
54
+        exclude: /node_modules/,
55
+        loader: 'babel-loader',
56
+        query: {
57
+          presets: ['env']
58
+        }
59
+      }
60
+    ]
61
+  },
62
+  plugins: [
63
+    new ExtractTextPlugin('main.bundle.css'),
64
+  ],
65
+  // For more info about webpack logs see: https://webpack.js.org/configuration/stats/
66
+  stats: 'errors-only'
67
+};
68
+
69
+module.exports = config;

+ 7
- 0
config/webpack/development.js View File

@@ -0,0 +1,7 @@
1
+const webpack = require('webpack');
2
+const merge = require('webpack-merge');
3
+const common = require('./common.js');
4
+
5
+module.exports = merge(common, {
6
+  devtool: 'inline-source-map'
7
+});

+ 11
- 0
config/webpack/production.js View File

@@ -0,0 +1,11 @@
1
+const webpack = require('webpack');
2
+const merge = require('webpack-merge');
3
+const common = require('./common.js');
4
+
5
+module.exports = merge(common, {
6
+  plugins: [
7
+    new webpack.optimize.UglifyJsPlugin({
8
+      compress: { warnings: false }
9
+    })
10
+  ]
11
+});

+ 0
- 0
db/migrations/.gitkeep View File


+ 42
- 0
docker-compose.yml View File

@@ -0,0 +1,42 @@
1
+version: '2'
2
+
3
+services:
4
+  app:
5
+    build: .
6
+    image: cdj_carnetdejeu
7
+    command: amber watch
8
+    environment:
9
+      DATABASE_URL: postgres://admin:password@db:5432/cdj_carnetdejeu_development
10
+    ports:
11
+      - 3000:3000
12
+    links:
13
+      - db
14
+    volumes:
15
+    - .:/app
16
+    - nodes:/app/node_modules
17
+    - shards:/app/lib
18
+
19
+  migrate:
20
+    build: .
21
+    image: cdj_carnetdejeu
22
+    command: bash -c 'while ! nc -q 1 db 5432 </dev/null; do sleep 1; done && amber db migrate seed'
23
+    environment:
24
+      DATABASE_URL: postgres://admin:password@db:5432/cdj_carnetdejeu_development
25
+    volumes:
26
+      - .:/app
27
+    links:
28
+      - db
29
+
30
+  db:
31
+    image: postgres
32
+    environment:
33
+      POSTGRES_USER: admin
34
+      POSTGRES_PASSWORD: password
35
+      POSTGRES_DB: cdj_carnetdejeu_development
36
+    volumes:
37
+      - db:/var/lib/postgres/data
38
+
39
+volumes:
40
+  db:
41
+  nodes:
42
+  shards:

+ 27
- 0
package.json View File

@@ -0,0 +1,27 @@
1
+{
2
+  "name": "cdj_carnetdejeu",
3
+  "version": "0.1.0",
4
+  "description": "Cdj Carnetdejeu with Amber",
5
+  "private": true,
6
+  "author": "Olivier DOSSMANN",
7
+  "license": "UNLICENSED",
8
+  "scripts": {
9
+    "build": "webpack --config config/webpack/development.js",
10
+    "watch": "webpack -w --config config/webpack/development.js",
11
+    "release": "webpack -p --config config/webpack/production.js",
12
+    "test": "echo \"No test specified\" && exit 1"
13
+  },
14
+  "devDependencies": {
15
+    "babel-core": "^6.26.3",
16
+    "babel-loader": "^7.1.4",
17
+    "babel-preset-env": "^1.6.1",
18
+    "css-loader": "^0.28.11",
19
+    "file-loader": "^1.1.11",
20
+    "node-sass": "^4.9.0",
21
+    "sass-loader": "^7.0.1",
22
+    "style-loader": "^0.21.0",
23
+    "webpack": "^3.12.0",
24
+    "webpack-merge": "^4.1.2",
25
+    "extract-text-webpack-plugin": "^3.0.2"
26
+  }
27
+}

+ 15
- 0
public/crossdomain.xml View File

@@ -0,0 +1,15 @@
1
+<?xml version="1.0"?>
2
+<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
3
+<cross-domain-policy>
4
+  <!-- Read this: www.adobe.com/devnet/articles/crossdomain_policy_file_spec.html -->
5
+
6
+  <!-- Most restrictive policy: -->
7
+  <site-control permitted-cross-domain-policies="none"/>
8
+
9
+  <!-- Least restrictive policy: -->
10
+  <!--
11
+  <site-control permitted-cross-domain-policies="all"/>
12
+  <allow-access-from domain="*" to-ports="*" secure="false"/>
13
+  <allow-http-request-headers-from domain="*" headers="*" secure="false"/>
14
+  -->
15
+</cross-domain-policy>

BIN
public/favicon.ico View File


BIN
public/favicon.png View File


+ 3
- 0
public/robots.txt View File

@@ -0,0 +1,3 @@
1
+# http://www.robotstxt.org
2
+User-agent: *
3
+Disallow:

+ 47
- 0
shard.yml View File

@@ -0,0 +1,47 @@
1
+name: cdj_carnetdejeu
2
+version: 0.1.0
3
+
4
+authors:
5
+  - Olivier DOSSMANN <git@dossmann.net>
6
+
7
+crystal: 0.26.0
8
+
9
+license: UNLICENSED
10
+
11
+targets:
12
+  cdj_carnetdejeu:
13
+    main: src/cdj_carnetdejeu.cr
14
+
15
+  amber:
16
+    main: lib/amber/src/amber/cli.cr
17
+
18
+dependencies:
19
+  amber:
20
+    github: amberframework/amber
21
+    version: 0.9.0
22
+    #branch: master
23
+
24
+  granite:
25
+    github: amberframework/granite
26
+    version: ~> 0.13.0
27
+
28
+  quartz_mailer:
29
+    github: amberframework/quartz-mailer
30
+    version: ~> 0.5.1
31
+
32
+  jasper_helpers:
33
+    github: amberframework/jasper-helpers
34
+    version: ~> 0.2.0
35
+
36
+  pg:
37
+    github: will/crystal-pg
38
+    version: ~> 0.15.0
39
+
40
+  citrine-i18n:
41
+    github: amberframework/citrine-i18n
42
+    version: 0.3.2
43
+
44
+development_dependencies:
45
+ garnet_spec:
46
+   github: amberframework/garnet-spec
47
+   version: ~> 0.2.1

+ 16
- 0
spec/spec_helper.cr View File

@@ -0,0 +1,16 @@
1
+ENV["AMBER_ENV"] ||= "test"
2
+
3
+require "spec"
4
+require "micrate"
5
+require "garnet_spec"
6
+
7
+require "../config/*"
8
+
9
+Micrate::DB.connection_url = Amber.settings.database_url
10
+
11
+# Automatically run migrations on the test database
12
+Micrate::Cli.run_up
13
+
14
+# Disable Granite logs in tests
15
+Granite.settings.logger = Logger.new nil
16
+

+ 0
- 0
src/assets/fonts/.gitkeep View File


+ 0
- 0
src/assets/images/.gitkeep View File


BIN
src/assets/images/logo.png View File


+ 23
- 0
src/assets/javascripts/main.js View File

@@ -0,0 +1,23 @@
1
+import Amber from 'amber'
2
+
3
+if (!Date.prototype.toGranite) {
4
+  (function() {
5
+
6
+    function pad(number) {
7
+      if (number < 10) {
8
+        return '0' + number;
9
+      }
10
+      return number;
11
+    }
12
+
13
+    Date.prototype.toGranite = function() {
14
+      return this.getUTCFullYear() +
15
+        '-' + pad(this.getUTCMonth() + 1) +
16
+        '-' + pad(this.getUTCDate()) +
17
+        ' ' + pad(this.getUTCHours()) +
18
+        ':' + pad(this.getUTCMinutes()) +
19
+        ':' + pad(this.getUTCSeconds())  ;
20
+    };
21
+
22
+  }());
23
+}

+ 117
- 0
src/assets/stylesheets/main.scss View File

@@ -0,0 +1,117 @@
1
+$font-stack: "Helvetica Neue", Helvetica, Arial, sans-serif;
2
+$background-color: #f4994b;
3
+$nav-item-color: #ffe4cd;
4
+
5
+/*
6
+ * Globals
7
+ */
8
+body {
9
+  font-family: $font-stack;
10
+  color: #555;
11
+}
12
+
13
+h1, .h1,
14
+h2, .h2,
15
+h3, .h3,
16
+h4, .h4,
17
+h5, .h5,
18
+h6, .h6 {
19
+  margin-top: 0;
20
+  font-family: $font-stack;
21
+  font-weight: normal;
22
+  color: #333;
23
+}
24
+
25
+/*
26
+ * Override Bootstrap's default container.
27
+ */
28
+@media (min-width: 1200px) {
29
+  .container {
30
+    width: 970px;
31
+  }
32
+}
33
+
34
+/*
35
+ * Masthead for nav
36
+ */
37
+.masthead {
38
+  background-color: $background-color;
39
+  -webkit-box-shadow: inset 0 -2px 5px rgba(0,0,0,.1);
40
+          box-shadow: inset 0 -2px 5px rgba(0,0,0,.1);
41
+}
42
+
43
+/* Nav links */
44
+.nav-item {
45
+  position: relative;
46
+  display: inline-block;
47
+  padding: 10px;
48
+  font-weight: 500;
49
+  color: $nav-item-color;
50
+}
51
+.nav-item:hover,
52
+.nav-item:focus {
53
+  color: #fff;
54
+  text-decoration: none;
55
+}
56
+
57
+/* Active state gets a caret at the bottom */
58
+.nav .active {
59
+  color: #fff;
60
+}
61
+.nav .active:after {
62
+  position: absolute;
63
+  bottom: 0;
64
+  left: 50%;
65
+  width: 0;
66
+  height: 0;
67
+  margin-left: -5px;
68
+  vertical-align: middle;
69
+  content: " ";
70
+  border-right: 5px solid transparent;
71
+  border-bottom: 5px solid;
72
+  border-left: 5px solid transparent;
73
+}
74
+
75
+.main {
76
+  padding-top: 20px;
77
+}
78
+
79
+#logo {
80
+  background-color: $background-color;
81
+  background-image: url("../images/logo.png");
82
+  background-size:contain;
83
+  width: 200px;
84
+  height:278px;
85
+}
86
+
87
+/* Hide logo in small screens */
88
+@media (max-width: 767px) {
89
+  #logo {
90
+    display: none;
91
+  }
92
+}
93
+
94
+.table td, .table th {
95
+  vertical-align: middle;
96
+}
97
+
98
+.alert {
99
+  margin-top: 1em;
100
+
101
+  p {
102
+    margin-top: 0;
103
+    margin-bottom: 0;
104
+  }
105
+}
106
+
107
+// For Navigation pulling right
108
+.nav-item-auth {
109
+  &.nav-item-auth-signout, &.nav-item-auth-signup {
110
+    order: 9999;
111
+  }
112
+
113
+  &.nav-item-auth-profile, &.nav-item-auth-signin {
114
+    order: 9990;
115
+    margin-left: auto;
116
+  }
117
+}

+ 3
- 0
src/cdj_carnetdejeu.cr View File

@@ -0,0 +1,3 @@
1
+require "../config/*"
2
+
3
+Amber::Server.start

+ 6
- 0
src/controllers/application_controller.cr View File

@@ -0,0 +1,6 @@
1
+require "jasper_helpers"
2
+
3
+class ApplicationController < Amber::Controller::Base
4
+  include JasperHelpers
5
+  LAYOUT = "application.slang"
6
+end

+ 5
- 0
src/controllers/home_controller.cr View File

@@ -0,0 +1,5 @@
1
+class HomeController < ApplicationController
2
+  def index
3
+    render("index.slang")
4
+  end
5
+end

+ 2
- 0
src/locales/en.yml View File

@@ -0,0 +1,2 @@
1
+---
2
+welcome_to_amber: "Welcome to Amber Framework!"

+ 9
- 0
src/views/home/index.slang View File

@@ -0,0 +1,9 @@
1
+.row
2
+  #logo
3
+  .col-sm-12.col-md-6
4
+    h2 = t "welcome_to_amber"
5
+    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.
6
+    .list-group
7
+      a.list-group-item.list-group-item-action target="_blank" href="https://docs.amberframework.org" Getting Started with Amber Framework
8
+      a.list-group-item.list-group-item-action target="_blank" href="https://github.com/veelenga/awesome-crystal" List of Awesome Crystal projects and shards
9
+      a.list-group-item.list-group-item-action target="_blank" href="https://crystalshards.xyz" What's hot in Crystal right now

+ 2
- 0
src/views/layouts/_nav.slang View File

@@ -0,0 +1,2 @@
1
+- active = context.request.path == "/" ? "active" : ""
2
+a class="nav-item #{active}" href="/" Home

+ 32
- 0
src/views/layouts/application.slang View File

@@ -0,0 +1,32 @@
1
+doctype html
2
+html
3
+  head
4
+    title Cdj Carnetdejeu using Amber
5
+    meta charset="utf-8"
6
+    meta http-equiv="X-UA-Compatible" content="IE=edge"
7
+    meta name="viewport" content="width=device-width, initial-scale=1"
8
+    link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/css/bootstrap.min.css"
9
+    link rel="stylesheet" href="/dist/main.bundle.css"
10
+    link rel="apple-touch-icon" href="/favicon.png"
11
+    link rel="icon" href="/favicon.png"
12
+    link rel="icon" type="image/x-icon" href="/favicon.ico"
13
+
14
+  body
15
+    .masthead
16
+      .container
17
+        nav.nav
18
+          == render(partial: "layouts/_nav.slang")
19
+    .container
20
+      .row
21
+        .col-sm
22
+          - flash.each do |key, value|
23
+            div class="alert alert-#{key}"
24
+              p = flash[key]
25
+      .row
26
+        .col-sm-12.main
27
+          == content
28
+
29
+    script src="https://code.jquery.com/jquery-3.3.1.min.js"
30
+    script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.0/umd/popper.min.js"
31
+    script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.0/js/bootstrap.min.js"
32
+    script src="/dist/main.bundle.js"

Loading…
Cancel
Save