35 changed files with 781 additions and 2 deletions
@ -0,0 +1,4 @@ |
|||
type: app |
|||
database: pg |
|||
language: slang |
|||
model: granite |
@ -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 |
@ -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 |
@ -1,4 +1,41 @@ |
|||
# carnetdejeu |
|||
|
|||
Gérer sa collection de jeux vidéos, consoles et figurines. |
|||
Et plus si affinités. |
|||
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). |
|||
|
@ -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 |
Binary file not shown.
@ -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. |
|||
|
@ -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. |
|||
|
@ -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" |
|||
|
@ -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 |
@ -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 |
@ -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; |
@ -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' |
|||
}); |
@ -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 } |
|||
}) |
|||
] |
|||
}); |
@ -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 </dev/null; do sleep 1; done && amber db migrate seed' |
|||
environment: |
|||
DATABASE_URL: postgres://admin:password@db:5432/cdj_carnetdejeu_development |
|||
volumes: |
|||
- .:/app |
|||
links: |
|||
- db |
|||
|
|||
db: |
|||
image: postgres |
|||
environment: |
|||
POSTGRES_USER: admin |
|||
POSTGRES_PASSWORD: password |
|||
POSTGRES_DB: cdj_carnetdejeu_development |
|||
volumes: |
|||
- db:/var/lib/postgres/data |
|||
|
|||
volumes: |
|||
db: |
|||
nodes: |
|||
shards: |
@ -0,0 +1,27 @@ |
|||
{ |
|||
"name": "cdj_carnetdejeu", |
|||
"version": "0.1.0", |
|||
"description": "Cdj Carnetdejeu with Amber", |
|||
"private": true, |
|||
"author": "Olivier DOSSMANN", |
|||
"license": "UNLICENSED", |
|||
"scripts": { |
|||
"build": "webpack --config config/webpack/development.js", |
|||
"watch": "webpack -w --config config/webpack/development.js", |
|||
"release": "webpack -p --config config/webpack/production.js", |
|||
"test": "echo \"No test specified\" && exit 1" |
|||
}, |
|||
"devDependencies": { |
|||
"babel-core": "^6.26.3", |
|||
"babel-loader": "^7.1.4", |
|||
"babel-preset-env": "^1.6.1", |
|||
"css-loader": "^0.28.11", |
|||
"file-loader": "^1.1.11", |
|||
"node-sass": "^4.9.0", |
|||
"sass-loader": "^7.0.1", |
|||
"style-loader": "^0.21.0", |
|||
"webpack": "^3.12.0", |
|||
"webpack-merge": "^4.1.2", |
|||
"extract-text-webpack-plugin": "^3.0.2" |
|||
} |
|||
} |
@ -0,0 +1,15 @@ |
|||
<?xml version="1.0"?> |
|||
<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd"> |
|||
<cross-domain-policy> |
|||
<!-- Read this: www.adobe.com/devnet/articles/crossdomain_policy_file_spec.html --> |
|||
|
|||
<!-- Most restrictive policy: --> |
|||
<site-control permitted-cross-domain-policies="none"/> |
|||
|
|||
<!-- Least restrictive policy: --> |
|||
<!-- |
|||
<site-control permitted-cross-domain-policies="all"/> |
|||
<allow-access-from domain="*" to-ports="*" secure="false"/> |
|||
<allow-http-request-headers-from domain="*" headers="*" secure="false"/> |
|||
--> |
|||
</cross-domain-policy> |
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 452 B |
@ -0,0 +1,3 @@ |
|||
# http://www.robotstxt.org |
|||
User-agent: * |
|||
Disallow: |
@ -0,0 +1,47 @@ |
|||
name: cdj_carnetdejeu |
|||
version: 0.1.0 |
|||
|
|||
authors: |
|||
- Olivier DOSSMANN <git@dossmann.net> |
|||
|
|||
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 |
@ -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 |
|||
|
After Width: | Height: | Size: 18 KiB |
@ -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()) ; |
|||
}; |
|||
|
|||
}()); |
|||
} |
@ -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; |
|||
} |
|||
} |
@ -0,0 +1,3 @@ |
|||
require "../config/*" |
|||
|
|||
Amber::Server.start |
@ -0,0 +1,6 @@ |
|||
require "jasper_helpers" |
|||
|
|||
class ApplicationController < Amber::Controller::Base |
|||
include JasperHelpers |
|||
LAYOUT = "application.slang" |
|||
end |
@ -0,0 +1,5 @@ |
|||
class HomeController < ApplicationController |
|||
def index |
|||
render("index.slang") |
|||
end |
|||
end |
@ -0,0 +1,2 @@ |
|||
--- |
|||
welcome_to_amber: "Welcome to Amber Framework!" |
@ -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 |
@ -0,0 +1,2 @@ |
|||
- active = context.request.path == "/" ? "active" : "" |
|||
a class="nav-item #{active}" href="/" Home |
@ -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" |
Loading…
Reference in new issue