update
This commit is contained in:
parent
666943d4f1
commit
51208cad8d
27 changed files with 1003 additions and 678 deletions
4
nodemon.json
Normal file
4
nodemon.json
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"verbose": false,
|
||||
"ignore": ["views", "static"]
|
||||
}
|
1
presentation.md
Normal file
1
presentation.md
Normal file
|
@ -0,0 +1 @@
|
|||
Potremmo impermutabile e lui carissime ignoranza, della nome noi sempre a prieghi in beato per. Noia quale lodato nella raccontare novella che. Nel dare modo in liberalita piaceri, alla impetrata il di e la novella manifestamente siamo, che che quali.
|
13
src/app.ts
13
src/app.ts
|
@ -12,6 +12,7 @@ import AdminAuthMiddleware from './middlewares/AdminAuthMiddleware'
|
|||
import DelegateAuthMiddleware from './middlewares/DelegateAuthMiddleware'
|
||||
import PublicController from './controllers/PublicController'
|
||||
import cors from 'cors'
|
||||
import twig from 'twig'
|
||||
|
||||
dotenv.config({
|
||||
path: __dirname + '/../.env'
|
||||
|
@ -21,6 +22,8 @@ const app: express.Application = express()
|
|||
const host: string = "0.0.0.0"
|
||||
const port: number = 8001
|
||||
|
||||
twig.cache(false)
|
||||
|
||||
let main = async () => {
|
||||
mongoose.connection.on('error', err => {
|
||||
console.error(err)
|
||||
|
@ -36,6 +39,10 @@ let main = async () => {
|
|||
console.log('> Connected to mongodb')
|
||||
})
|
||||
|
||||
app.set("twig options", {
|
||||
allow_async: true,
|
||||
strict_variables: false
|
||||
})
|
||||
app.use(cors())
|
||||
app.use(bodyParser.json())
|
||||
|
||||
|
@ -46,6 +53,8 @@ let main = async () => {
|
|||
|
||||
app.get('/', PublicController.home)
|
||||
app.get('/association/:slug', PublicController.organization)
|
||||
app.get('/a-propos', PublicController.about)
|
||||
app.get('/mentions-legales', PublicController.legals)
|
||||
|
||||
app.get('/icon/:id', DefaultController.viewIcon)
|
||||
app.get('/email', DefaultController.sendEmail)
|
||||
|
@ -79,6 +88,8 @@ let main = async () => {
|
|||
.put('/', DelegateController.update)
|
||||
.post('/submit', DelegateController.submit)
|
||||
.post('/thumbnail', DelegateController.uploadThumbnail())
|
||||
.post('/cover', DelegateController.uploadCover())
|
||||
.post('/medias', DelegateController.uploadMedias())
|
||||
.delete('/', DelegateController.destroy)
|
||||
)
|
||||
|
||||
|
@ -92,7 +103,7 @@ let main = async () => {
|
|||
*/
|
||||
|
||||
app.post('/api/media', MediaController.uploadRoute())
|
||||
app.delete('/api/media/:key', MediaController.delete)
|
||||
//app.delete('/api/media/:key', MediaController.delete)
|
||||
|
||||
app.use(express.static('/apps/forum_server/static'))
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import cryptoRandomString from 'crypto-random-string'
|
|||
import EmailService from '../EmailService'
|
||||
import slugify from 'slugify'
|
||||
import { Document } from 'mongoose'
|
||||
import MediaService from '../MediaService'
|
||||
|
||||
export default class AdminOrganizationController {
|
||||
static getMany(req: express.Request, res: express.Response) {
|
||||
|
@ -22,22 +23,22 @@ export default class AdminOrganizationController {
|
|||
let body: any = {
|
||||
token: AdminOrganizationController.generateToken(),
|
||||
createdAt: new Date(),
|
||||
slug: req.body.adminName === undefined ? undefined : slugify(req.body.adminName).toLowerCase(),
|
||||
...req.body
|
||||
// ...{
|
||||
// proposedVersion: {
|
||||
// name: '',
|
||||
// descriptionShort: '',
|
||||
// descriptionLong: '',
|
||||
// contacts: [],
|
||||
// schedule: [],
|
||||
// pricing: [],
|
||||
// tag: null,
|
||||
// cover: null,
|
||||
// gallery: [],
|
||||
// thumbnail: null
|
||||
// }
|
||||
// }
|
||||
slug: slugify(req.body.adminName).toLowerCase(),
|
||||
...req.body,
|
||||
...{
|
||||
proposedVersion: {
|
||||
name: req.body.adminName
|
||||
// descriptionShort: '',
|
||||
// descriptionLong: '',
|
||||
// contacts: [],
|
||||
// schedule: [],
|
||||
// pricing: [],
|
||||
// tag: null,
|
||||
// cover: null,
|
||||
// gallery: [],
|
||||
// thumbnail: null
|
||||
}
|
||||
}
|
||||
}
|
||||
Organization.create(body).then(data => {
|
||||
AdminOrganizationController.sendEmailTokenUniversal(data)
|
||||
|
@ -75,16 +76,46 @@ export default class AdminOrganizationController {
|
|||
}
|
||||
|
||||
static destroy(req: express.Request, res: express.Response) {
|
||||
Organization.deleteOne({ _id: req.params.id }).then(data => {
|
||||
let isSuccess = data.deletedCount !== undefined && data.deletedCount > 0
|
||||
res.status(isSuccess ? 200 : 400).json({
|
||||
success: isSuccess,
|
||||
data
|
||||
})
|
||||
}).catch(err => res.status(400).json({
|
||||
success: false,
|
||||
errors: err.errors
|
||||
}))
|
||||
Organization.findById(req.params.id).then(organization => {
|
||||
Organization.deleteOne({ _id: req.params.id }).then(data => {
|
||||
if (organization === null) {
|
||||
return
|
||||
}
|
||||
// delete all media from this organization
|
||||
let keys: string[] = []
|
||||
const proposedVersion: any = organization.get('proposedVersion')
|
||||
if (proposedVersion.thumbnail !== undefined && proposedVersion.thumbnail !== null) {
|
||||
keys.push(proposedVersion.thumbnail.key)
|
||||
}
|
||||
if (proposedVersion.cover !== undefined && proposedVersion.cover !== null) {
|
||||
keys.push(proposedVersion.cover.key)
|
||||
}
|
||||
console.log(proposedVersion.gallery)
|
||||
if (Array.isArray(proposedVersion.gallery)) {
|
||||
keys = keys.concat(proposedVersion.gallery.map((m: any) => m.key))
|
||||
}
|
||||
|
||||
keys.forEach((key: string) => {
|
||||
if (key === undefined || key === null || key.length <= 2) { return }
|
||||
console.log('> OrganizationDestroyMediaCleanup: Deleted ' + key)
|
||||
MediaService.getS3().deleteObject({
|
||||
Bucket: MediaService.getBucket(),
|
||||
Key: key
|
||||
}, (err, _) => {
|
||||
if (err !== null) {
|
||||
console.error('> OrganizationDestroyMediaCleanup: Cannot delete a media from a organization which will be deleted')
|
||||
console.log(err, err.stack)
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
let isSuccess = data.deletedCount !== undefined && data.deletedCount > 0
|
||||
res.status(isSuccess ? 200 : 400).json({
|
||||
success: isSuccess,
|
||||
data
|
||||
})
|
||||
}).catch(err => res.status(400).json({ success: false, errors: err.errors }))
|
||||
}).catch(err => res.status(400).json({ success: false, errors: err }))
|
||||
}
|
||||
|
||||
static sendEmailToken(req: express.Request, res: express.Response) {
|
||||
|
@ -150,11 +181,16 @@ export default class AdminOrganizationController {
|
|||
}
|
||||
|
||||
static sendEmailTokenUniversal(data: Document) {
|
||||
const baseUrl = process.env.WEB_UI_URL === undefined ? "URL_NOT_FOUND" : process.env.WEB_UI_URL
|
||||
EmailService.send(
|
||||
data.get('email'),
|
||||
"Votre lien secret pour modifier votre association",
|
||||
"token",
|
||||
{ adminName: data.get('adminName'), token: data.get('token') }
|
||||
{
|
||||
adminName: data.get('adminName'),
|
||||
token: data.get('token'),
|
||||
link: baseUrl + '/delegate?delegateToken=' + data.get('token')
|
||||
}
|
||||
).then(() => {
|
||||
console.log('> A token email was sent')
|
||||
}).catch(() => {
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
import Tag from '../models/Tag'
|
||||
import Organization from '../models/Organization'
|
||||
import * as express from 'express'
|
||||
import EmailService from '../EmailService'
|
||||
|
@ -9,7 +10,15 @@ import slugify from 'slugify'
|
|||
export default class DelegateController {
|
||||
|
||||
static get(req: express.Request, res: express.Response) {
|
||||
res.json({ success: true, data: res.locals.organization })
|
||||
Tag.find().then(tags => {
|
||||
res.json({
|
||||
success: true,
|
||||
data: {
|
||||
organization: res.locals.organization,
|
||||
tags
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
static test(req: express.Request, res: express.Response) {
|
||||
|
@ -17,28 +26,92 @@ export default class DelegateController {
|
|||
}
|
||||
|
||||
static update(req: express.Request, res: express.Response) {
|
||||
if (res.locals.organization.validationState === 'pending') {
|
||||
const organization: any = res.locals.organization
|
||||
if (organization.validationState === 'pending') {
|
||||
return res.json({
|
||||
success: false,
|
||||
errors: [{ code: 'update-forbidden', message: 'Organization cannot be updated while the validationState is set to "pending"' }]
|
||||
})
|
||||
}
|
||||
// only update proposedVersion
|
||||
Organization.updateOne({ _id: res.locals.organization._id }, {
|
||||
proposedVersion: req.body,
|
||||
updatedAt: new Date()
|
||||
}).then(data => {
|
||||
res.json({
|
||||
success: true,
|
||||
data,
|
||||
body: req.body
|
||||
|
||||
const next = (tag: any) => {
|
||||
// only update proposedVersion
|
||||
let proposedVersion: any = req.body
|
||||
proposedVersion.tag = tag
|
||||
proposedVersion.descriptionLong = proposedVersion.descriptionLong.replace(/\n/g, '')
|
||||
|
||||
// validate contact.address
|
||||
// validate all fields to not overflow
|
||||
// validate the size of all the json, all the data recorded
|
||||
|
||||
// manage medias
|
||||
// delete media that are not used
|
||||
if (!Array.isArray(proposedVersion.gallery)) {
|
||||
proposedVersion.gallery = []
|
||||
}
|
||||
if (Array.isArray(organization.proposedVersion.gallery)) {
|
||||
organization.proposedVersion.gallery.forEach((media: any) => {
|
||||
// if a existing media is not in the new version we delete it
|
||||
if (proposedVersion.gallery.filter((m: any) => m.key === media.key).length === 0) {
|
||||
console.log('> Old media cleanup: we must delete ', media)
|
||||
MediaService.getS3().deleteObject({
|
||||
Bucket: MediaService.getBucket(),
|
||||
Key: media.key
|
||||
}, (err, _) => {
|
||||
if (err !== null) {
|
||||
console.error('> Cannot delete a old media element')
|
||||
console.log(err, err.stack)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// format schedule, pricing
|
||||
if (!Array.isArray(proposedVersion.schedule)) {
|
||||
proposedVersion.schedule = []
|
||||
}
|
||||
if (!Array.isArray(proposedVersion.pricing)) {
|
||||
proposedVersion.pricing = []
|
||||
}
|
||||
|
||||
Organization.updateOne({ _id: organization._id }, {
|
||||
proposedVersion,
|
||||
updatedAt: new Date()
|
||||
}).then(data => {
|
||||
res.json({
|
||||
success: true,
|
||||
data,
|
||||
body: req.body
|
||||
})
|
||||
}).catch(err => {
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
errors: err.errors !== undefined ? err.errors : err
|
||||
})
|
||||
})
|
||||
}).catch(err => {
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
errors: err.errors !== undefined ? err.errors : err
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
if (req.body.tag !== undefined && req.body.tag !== null && req.body.tag.length > 2) {
|
||||
// skip the tag part if the tag didn't changed
|
||||
if (
|
||||
organization.proposedVersion.tag === undefined ||
|
||||
organization.proposedVersion.tag === null ||
|
||||
req.body.tag !== organization.proposedVersion.tag._id
|
||||
) {
|
||||
// if the tag is defined, search the tag id
|
||||
Tag.findById(req.body.tag).then(tag => {
|
||||
next(tag)
|
||||
}).catch(err => {
|
||||
console.log(err)
|
||||
res.status(400).json({ success: false, errors: err, _note: 'The tag id provided is invalid' })
|
||||
})
|
||||
} else {
|
||||
next(organization.tag)
|
||||
}
|
||||
} else {
|
||||
next(null)
|
||||
}
|
||||
}
|
||||
|
||||
static submit(req: express.Request, res: express.Response) {
|
||||
|
@ -78,7 +151,6 @@ export default class DelegateController {
|
|||
}
|
||||
|
||||
static uploadThumbnail(): express.RequestHandler[] {
|
||||
// we upload the thumbnail
|
||||
return [
|
||||
multer({
|
||||
storage: multerS3({
|
||||
|
@ -88,14 +160,14 @@ export default class DelegateController {
|
|||
contentType: multerS3.AUTO_CONTENT_TYPE,
|
||||
key: (_: any, file: any, cb: any) => {
|
||||
console.log(file)
|
||||
cb(null, Date.now().toString() + '_' + slugify(file.originalname))
|
||||
cb(null, Date.now().toString() + '_thumbnail')
|
||||
}
|
||||
})
|
||||
}).single('file'),
|
||||
(req: express.Request, res: express.Response) => {
|
||||
// if the current thumbnail is defined AND the published thumnbnail is defined AND the current thumbnail is different from the published one
|
||||
// THEN we delete the current thumbnail
|
||||
const proposedVersion: any = res.locals.organization.proposedVersion
|
||||
let proposedVersion: any = res.locals.organization.proposedVersion
|
||||
const publishedVersion: any = res.locals.organization.publishedVersion
|
||||
if (
|
||||
proposedVersion !== undefined && proposedVersion !== null &&
|
||||
|
@ -109,7 +181,7 @@ export default class DelegateController {
|
|||
Bucket: MediaService.getBucket(),
|
||||
Key: proposedVersion.thumbnail.key
|
||||
}, (err, _) => {
|
||||
if (err !== null) {
|
||||
if (err !== null) {
|
||||
console.error('> Cannot delete a old thumbnail')
|
||||
console.log(err, err.stack)
|
||||
}
|
||||
|
@ -122,13 +194,134 @@ export default class DelegateController {
|
|||
contentType: req.file.contentType,
|
||||
// @ts-ignore
|
||||
location: req.file.location,
|
||||
// @ts-ignore
|
||||
size: req.file.size,
|
||||
// @ts-ignore
|
||||
originalFileName: req.file.originalname,
|
||||
type: 'thumbnail'
|
||||
}
|
||||
proposedVersion = { ...res.locals.organization.proposedVersion, thumbnail }
|
||||
Organization.updateOne({ _id: res.locals.organization._id }, {
|
||||
proposedVersion: { thumbnail },
|
||||
proposedVersion,
|
||||
updatedAt: new Date()
|
||||
}).then(data => {
|
||||
res.json({ success: true, data, thumbnail })
|
||||
res.json({ success: true, data, thumbnail, proposedVersion })
|
||||
}).catch(err => {
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
errors: err.errors !== undefined ? err.errors : err
|
||||
})
|
||||
})
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
static uploadCover(): express.RequestHandler[] {
|
||||
return [
|
||||
multer({
|
||||
storage: multerS3({
|
||||
s3: MediaService.getS3(),
|
||||
bucket: 'development-bucket',
|
||||
acl: 'public-read',
|
||||
contentType: multerS3.AUTO_CONTENT_TYPE,
|
||||
key: (_: any, file: any, cb: any) => {
|
||||
console.log(file)
|
||||
cb(null, Date.now().toString() + '_cover')
|
||||
}
|
||||
})
|
||||
}).single('file'),
|
||||
(req: express.Request, res: express.Response) => {
|
||||
// if the current thumbnail is defined AND the published thumnbnail is defined AND the current thumbnail is different from the published one
|
||||
// THEN we delete the current thumbnail
|
||||
let proposedVersion: any = res.locals.organization.proposedVersion
|
||||
const publishedVersion: any = res.locals.organization.publishedVersion
|
||||
if (
|
||||
proposedVersion !== undefined && proposedVersion !== null &&
|
||||
proposedVersion.cover !== undefined && proposedVersion.cover !== null &&
|
||||
publishedVersion !== undefined && publishedVersion !== null &&
|
||||
publishedVersion.cover !== undefined && publishedVersion.cover !== null &&
|
||||
publishedVersion.cover.location !== proposedVersion.cover.location
|
||||
) {
|
||||
console.log(' we must delete ', proposedVersion.cover)
|
||||
MediaService.getS3().deleteObject({
|
||||
Bucket: MediaService.getBucket(),
|
||||
Key: proposedVersion.cover.key
|
||||
}, (err, _) => {
|
||||
if (err !== null) {
|
||||
console.error('> Cannot delete a old cover')
|
||||
console.log(err, err.stack)
|
||||
}
|
||||
})
|
||||
}
|
||||
const cover: any = {
|
||||
// @ts-ignore
|
||||
key: req.file.key,
|
||||
// @ts-ignore
|
||||
contentType: req.file.contentType,
|
||||
// @ts-ignore
|
||||
location: req.file.location,
|
||||
// @ts-ignore
|
||||
size: req.file.size,
|
||||
// @ts-ignore
|
||||
originalFileName: req.file.originalname,
|
||||
type: 'cover'
|
||||
}
|
||||
proposedVersion = { ...res.locals.organization.proposedVersion, cover }
|
||||
Organization.updateOne({ _id: res.locals.organization._id }, {
|
||||
proposedVersion,
|
||||
updatedAt: new Date()
|
||||
}).then(data => {
|
||||
res.json({ success: true, data, cover, proposedVersion })
|
||||
}).catch(err => {
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
errors: err.errors !== undefined ? err.errors : err
|
||||
})
|
||||
})
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
static uploadMedias(): express.RequestHandler[] {
|
||||
return [
|
||||
multer({
|
||||
storage: multerS3({
|
||||
s3: MediaService.getS3(),
|
||||
bucket: 'development-bucket',
|
||||
acl: 'public-read',
|
||||
contentType: multerS3.AUTO_CONTENT_TYPE,
|
||||
key: (_: any, file: any, cb: any) => {
|
||||
console.log(file)
|
||||
cb(null, Date.now().toString() + '_media')
|
||||
}
|
||||
})
|
||||
}).array('file'),
|
||||
(req: express.Request, res: express.Response) => {
|
||||
let proposedVersion: any = res.locals.organization.proposedVersion
|
||||
|
||||
// @ts-ignore
|
||||
req.files.forEach((file: any) => {
|
||||
proposedVersion.gallery.push({
|
||||
key: file.key,
|
||||
contentType: file.contentType,
|
||||
location: file.location,
|
||||
size: file.size,
|
||||
type: 'image',
|
||||
originalFileName: file.originalname
|
||||
})
|
||||
})
|
||||
|
||||
Organization.updateOne({ _id: res.locals.organization._id }, {
|
||||
proposedVersion,
|
||||
updatedAt: new Date()
|
||||
}).then(result => {
|
||||
res.json({
|
||||
success: true,
|
||||
data: {
|
||||
result,
|
||||
gallery: proposedVersion.gallery
|
||||
}
|
||||
})
|
||||
}).catch(err => {
|
||||
res.status(400).json({
|
||||
success: false,
|
||||
|
|
|
@ -16,7 +16,7 @@ export default class MediaController {
|
|||
contentType: multerS3.AUTO_CONTENT_TYPE,
|
||||
key: (_: any, file: any, cb: any) => {
|
||||
console.log(file)
|
||||
cb(null, Date.now().toString() + '_' + slugify(file.originalname)) //use Date.now() for unique file keys
|
||||
cb(null, Date.now().toString()) //use Date.now() for unique file keys
|
||||
}
|
||||
})
|
||||
}).single('file'),
|
||||
|
@ -25,9 +25,6 @@ export default class MediaController {
|
|||
}
|
||||
|
||||
static upload(req: express.Request, res: express.Response) {
|
||||
|
||||
|
||||
|
||||
res.json({
|
||||
success: true,
|
||||
data: { file: req.file }
|
||||
|
|
|
@ -7,24 +7,78 @@ import Mustache from 'mustache'
|
|||
import fs from 'fs'
|
||||
import { IconService, IconInterface } from '../IconService'
|
||||
import IORedis from 'ioredis'
|
||||
import Tag from '../models/Tag'
|
||||
|
||||
export default class PublicController {
|
||||
|
||||
|
||||
static async home(req: express.Request, res: express.Response) {
|
||||
// let client: IORedis.Redis = RedisService.getClient()
|
||||
// await client.set('hello', 'world')
|
||||
// res.json({
|
||||
// data: await client.get('hello')
|
||||
// })
|
||||
res.render('home.twig', {
|
||||
message : "Hello World"
|
||||
Tag.find().then(tags => {
|
||||
Organization.find().then(organizations => {
|
||||
res.render('home.twig', {
|
||||
tags,
|
||||
tagsJSON: JSON.stringify(tags),
|
||||
organizationsJSON: JSON.stringify(organizations.map(o => {
|
||||
const version = o.get('proposedVersion')
|
||||
return {
|
||||
name: version.name,
|
||||
description: version.descriptionShort,
|
||||
thumbnail: version.thumbnail.location,
|
||||
tag: version.tag._id,
|
||||
slug: o.get('slug')
|
||||
}
|
||||
}))
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
static async organization(req: express.Request, res: express.Response) {
|
||||
res.render('index.twig', {
|
||||
message : "Hello World"
|
||||
})
|
||||
Organization.find({ slug: req.params.slug }).then(data => {
|
||||
if (data.length === 0) {
|
||||
res.status(404).render('not-found.twig')
|
||||
} else {
|
||||
const version = data[0].get('proposedVersion')
|
||||
if (version.contacts !== null && version.contacts !== undefined) {
|
||||
if (typeof version.contacts.address === 'string') {
|
||||
version.contacts.address = version.contacts.address.split('\n')
|
||||
}
|
||||
if (typeof version.contacts.phone === 'string') {
|
||||
let phone = version.contacts.phone
|
||||
if (phone.indexOf('+33') === 0) {
|
||||
phone = '0' + phone.substr(3)
|
||||
}
|
||||
let phoneSplit = ''
|
||||
let partEnd = false
|
||||
for (var i = 0; i < phone.length; i++) {
|
||||
phoneSplit += phone.charAt(i)
|
||||
if (partEnd === true) {
|
||||
phoneSplit += ' '
|
||||
}
|
||||
partEnd = !partEnd
|
||||
}
|
||||
version.contacts.phoneInt = "+33" + phone.substr(1)
|
||||
version.contacts.phoneSplit = phoneSplit
|
||||
}
|
||||
}
|
||||
console.log(version)
|
||||
res.render('organization.twig', {
|
||||
layout: 'standalone',
|
||||
data: version
|
||||
})
|
||||
}
|
||||
}).catch(_ => res.status(404).render('not-found.twig'))
|
||||
}
|
||||
|
||||
static async about(req: express.Request, res: express.Response) {
|
||||
res.render('about.twig')
|
||||
}
|
||||
|
||||
static async legals(req: express.Request, res: express.Response) {
|
||||
res.render('legals.twig')
|
||||
}
|
||||
}
|
|
@ -29,11 +29,6 @@ class AllowedString extends mongoose.SchemaType {
|
|||
// @ts-ignore
|
||||
mongoose.Schema.Types['AllowedString'] = AllowedString
|
||||
|
||||
const ScheduleIntervalBoundary = {
|
||||
hour: { type: Number },
|
||||
minute: { type: Number }
|
||||
}
|
||||
|
||||
const Media = {
|
||||
location: { type: String },
|
||||
type: {
|
||||
|
@ -41,8 +36,10 @@ const Media = {
|
|||
name: 'MediaType',
|
||||
allowedValues: ['cover', 'thumbnail', 'video', 'image']
|
||||
},
|
||||
originalFileName: { type: String },
|
||||
key: { type: String },
|
||||
contentType: { type: String }
|
||||
contentType: { type: String },
|
||||
size: { type: Number } // size of the file in bytes
|
||||
}
|
||||
|
||||
const OrganizationVersion = {
|
||||
|
@ -68,8 +65,8 @@ const OrganizationVersion = {
|
|||
description: { type: String },
|
||||
when: [{
|
||||
day: { type: String }, // (Lundi,Mardi,Mercredi,Jeudi,Vendredi,Samedi,Dimanche)
|
||||
from: ScheduleIntervalBoundary,
|
||||
to: ScheduleIntervalBoundary
|
||||
from: { type: String },
|
||||
to: { type: String }
|
||||
}]
|
||||
}],
|
||||
pricing: [{
|
||||
|
|
|
@ -1,39 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Home</title>
|
||||
<meta charset="UTF-8" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Roboto&family=Roboto+Slab&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.1/css/all.min.css" />
|
||||
<link rel="stylesheet" href="./assets/main.css" />
|
||||
<link rel="stylesheet" href="./assets/home.css" />
|
||||
<meta name="viewport" content="width=device-width">
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class="header">
|
||||
<div class="container header-container">
|
||||
<div class="header-image">
|
||||
<img src="assets/img/espace_condorcet_logo.jpg" />
|
||||
</div>
|
||||
<div class="header-content">
|
||||
<a
|
||||
href="https://www.espacecondorcet.org/"
|
||||
class="header-sub-title">
|
||||
Espace Condorcet Centre Social
|
||||
</a>
|
||||
<h1 class="header-title">Forum des associations</h1>
|
||||
<div class="header-description">
|
||||
Cette année nous vous invitons à découvrir le forum virtuel des associations.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="content">
|
||||
<p>Lorem, ipsum dolor sit amet consectetur adipisicing elit. Autem alias sapiente neque? Dignissimos harum blanditiis fugiat eius alias nam repudiandae, et explicabo nihil eos, quos reprehenderit nobis aperiam quibusdam ad?</p>
|
||||
</div>
|
||||
</div>
|
||||
<script></script>
|
||||
</body>
|
||||
</html>
|
|
@ -17,7 +17,6 @@
|
|||
.header-menu {
|
||||
display: flex;
|
||||
align-items: flex-end;
|
||||
|
||||
}
|
||||
|
||||
.header-menu a {
|
||||
|
@ -94,6 +93,11 @@
|
|||
height: 1.2em;
|
||||
}
|
||||
|
||||
.nav-item svg {
|
||||
width: .75em;
|
||||
height: .75em;
|
||||
}
|
||||
|
||||
.nav-icon {
|
||||
width: 3em;
|
||||
padding-left: .5em;
|
||||
|
@ -114,7 +118,7 @@
|
|||
.nav-title {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
opacity: 0.85;
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.nav-access {
|
||||
|
@ -194,6 +198,7 @@
|
|||
}
|
||||
|
||||
.card-content {
|
||||
/* width: 100%; */
|
||||
padding: 1.5em;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
@ -213,6 +218,11 @@
|
|||
font-size: 1.4em;
|
||||
}
|
||||
|
||||
.card-icon svg {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
}
|
||||
|
||||
.card-title {
|
||||
font-size: 1.6em;
|
||||
color: #B12008;
|
||||
|
@ -316,4 +326,3 @@
|
|||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
BIN
static/assets/img/favicon.png
Normal file
BIN
static/assets/img/favicon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.6 KiB |
|
@ -10,6 +10,11 @@ let navContent = document.getElementById('nav-content')
|
|||
let mosaic = document.getElementById('mosaic')
|
||||
let mosaicHeader = document.getElementById('mosaic-header')
|
||||
|
||||
organizations = organizations.map(org => {
|
||||
org.tag = tags.filter(t => t._id === org.tag)[0]
|
||||
return org
|
||||
})
|
||||
|
||||
navEnabler.onclick = async () => {
|
||||
if (!navOpened) {
|
||||
// open the menu
|
||||
|
@ -73,6 +78,14 @@ function renderNavItem(tag) {
|
|||
return navItem
|
||||
}
|
||||
|
||||
function setAttributes(node, attrs) {
|
||||
for (var key in attrs) {
|
||||
attr = document.createAttribute(key)
|
||||
attr.value = attrs[key]
|
||||
node.attributes.setNamedItem(attr)
|
||||
}
|
||||
}
|
||||
|
||||
function renderCard(organization) {
|
||||
let card = createEl('card')
|
||||
|
||||
|
@ -92,13 +105,19 @@ function renderCard(organization) {
|
|||
titleContainer.appendChild(title)
|
||||
|
||||
let icon = createEl('card-icon')
|
||||
let iconTag = createEl(organization.tag.icon, 'i')
|
||||
icon.appendChild(iconTag)
|
||||
icon.innerHTML = `<svg
|
||||
aria-hidden="true"
|
||||
focusable="false"
|
||||
role="img"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 ${organization.tag.icon.width} ${organization.tag.icon.height}">
|
||||
<path fill="currentColor" d="${organization.tag.icon.path}"></path>
|
||||
</svg>`
|
||||
titleContainer.appendChild(icon)
|
||||
upperContent.appendChild(titleContainer)
|
||||
|
||||
let description = createEl('card-description')
|
||||
description.textContent = organization.descriptionShort
|
||||
description.textContent = organization.description
|
||||
upperContent.appendChild(description)
|
||||
|
||||
let link = createEl('card-link')
|
||||
|
@ -109,6 +128,10 @@ function renderCard(organization) {
|
|||
content.appendChild(upperContent)
|
||||
content.appendChild(link)
|
||||
card.appendChild(content)
|
||||
|
||||
card.onclick = () => {
|
||||
window.location = aTag.href
|
||||
}
|
||||
return card
|
||||
}
|
||||
|
||||
|
@ -129,7 +152,7 @@ function enableTag(node) {
|
|||
if (!all) {
|
||||
tagId = node.attributes['data-tag-id'].value
|
||||
}
|
||||
let data = organizations.filter(orga => orga.tag.id === tagId || all)
|
||||
let data = organizations.filter(orga => orga.tag._id === tagId || all)
|
||||
let cards = renderMosaic(data)
|
||||
if (currentCardContainer !== null) {
|
||||
mosaic.removeChild(currentCardContainer)
|
||||
|
|
|
@ -8,7 +8,7 @@ body {
|
|||
}
|
||||
|
||||
.container {
|
||||
width: 80%;
|
||||
width: 60%;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
|
@ -23,8 +23,21 @@ a:hover {
|
|||
color: #2980b9;
|
||||
}
|
||||
|
||||
|
||||
@media (max-width: 1600px) {
|
||||
.container {
|
||||
width: 70%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 1500px) {
|
||||
.container {
|
||||
width: 80%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.container {
|
||||
width: 92%;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,13 +23,19 @@
|
|||
color: #34495e;
|
||||
cursor: pointer;
|
||||
transition: all .2s;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.return-icon {
|
||||
font-size: 1.5em;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-right: .5em;
|
||||
}
|
||||
|
||||
.return-icon svg {
|
||||
width: 1.3em;
|
||||
}
|
||||
|
||||
.return:hover {
|
||||
opacity: 0.88;
|
||||
text-decoration: underline;
|
||||
|
@ -140,7 +146,7 @@
|
|||
transform: scale(1.2);
|
||||
}
|
||||
|
||||
.media-main {
|
||||
.media-container:first-of-type {
|
||||
grid-row: 1 / span 2;
|
||||
}
|
||||
|
||||
|
@ -207,10 +213,29 @@ section {
|
|||
margin-bottom: .5em;
|
||||
}
|
||||
|
||||
.description p {
|
||||
margin-top: .75em;
|
||||
}
|
||||
.description p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.description h3 {
|
||||
font-size: 1.4em;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.description h4 {
|
||||
font-size: 1.2em;
|
||||
margin-top: 1em;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.description h3, .description h4 {
|
||||
opacity: 0.8;
|
||||
}
|
||||
|
||||
/* *****************************************************************************
|
||||
|
||||
* SCHEDULE
|
||||
|
@ -237,7 +262,7 @@ section {
|
|||
|
||||
.schedule-category-collapse-icon {
|
||||
color: #B12008;
|
||||
font-size: 1.5em;
|
||||
width: 1.5em;
|
||||
transition: all 0.1s ease-out;
|
||||
}
|
||||
|
||||
|
@ -251,7 +276,6 @@ section {
|
|||
.schedule-category-days-container {
|
||||
border-radius: 4px;
|
||||
background-color: #ECF0F1;
|
||||
width: 40;
|
||||
|
||||
margin-left: 2em;
|
||||
margin-top: 1em;
|
||||
|
@ -283,14 +307,14 @@ section {
|
|||
|
||||
.pricing {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.pricing-card {
|
||||
max-width: 14em;
|
||||
height: 10em;
|
||||
width: 100%;
|
||||
padding-top: 1.5em;
|
||||
padding-bottom: 1.5em;
|
||||
padding: 1.5em 1em;
|
||||
text-align: center;
|
||||
border-radius: 4px;
|
||||
display: flex;
|
||||
|
@ -360,6 +384,10 @@ section {
|
|||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
.contact-icon svg {
|
||||
width: .7em;
|
||||
}
|
||||
|
||||
.contact-content {
|
||||
text-align: right;
|
||||
}
|
||||
|
@ -369,21 +397,45 @@ section {
|
|||
font-weight: bold;
|
||||
}
|
||||
|
||||
.external-link {
|
||||
width: .8em;
|
||||
}
|
||||
|
||||
.email .contact-icon svg {
|
||||
width: .9em;
|
||||
}
|
||||
|
||||
.website .contact-icon svg {
|
||||
width: .9em;
|
||||
}
|
||||
|
||||
.facebook .contact-icon {
|
||||
background-color: #3B5999;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.facebook .contact-icon svg {
|
||||
width: .5em;
|
||||
}
|
||||
|
||||
.instagram .contact-icon {
|
||||
background:linear-gradient(45deg, #405de6, #5851db, #833ab4, #c13584, #e1306c, #fd1d1d);
|
||||
color: white;
|
||||
}
|
||||
|
||||
.instagram .contact-icon svg {
|
||||
width: .75em;
|
||||
}
|
||||
|
||||
.twitter .contact-icon {
|
||||
background-color: #1DA1F2;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.twitter .contact-icon svg {
|
||||
width: .75em;
|
||||
}
|
||||
|
||||
/* *****************************************************************************
|
||||
|
||||
* FOOTER
|
||||
|
@ -412,6 +464,13 @@ section {
|
|||
}
|
||||
|
||||
|
||||
@media (max-width: 1200px) {
|
||||
.schedule-category-days-container {
|
||||
margin-right: 25em;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@media (max-width: 900px) {
|
||||
|
||||
.cover-background {
|
||||
|
@ -446,23 +505,40 @@ section {
|
|||
grid-template-columns: .5fr .5fr;
|
||||
grid-template-rows: 1fr .5fr .5fr;
|
||||
}
|
||||
.media-main {
|
||||
|
||||
.media-container:first-of-type {
|
||||
grid-row: 1 / span 1;
|
||||
grid-column: 1 / span 2;
|
||||
}
|
||||
|
||||
.schedule-category-header {
|
||||
padding-left: 1em;
|
||||
padding-right: 1em;
|
||||
}
|
||||
|
||||
.schedule-category-days-container {
|
||||
margin-right: 5em;
|
||||
}
|
||||
|
||||
.pricing-card {
|
||||
margin-right: .5em;
|
||||
.pricing {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.pricing-card {
|
||||
margin-right: 0;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.contact {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.contact-icon {
|
||||
width: 1.5em;
|
||||
height: 1.5em;
|
||||
}
|
||||
|
||||
.contact-item {
|
||||
padding-left: 1em;
|
||||
padding-right: 1em;
|
||||
|
@ -470,5 +546,21 @@ section {
|
|||
|
||||
.contact-content {
|
||||
word-break: break-all;
|
||||
font-size: .9em;
|
||||
}
|
||||
|
||||
.facebook .contact-content, .twitter .contact-content, .website .contact-content, .instagram .contact-content {
|
||||
font-size: .8em;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.schedule-category-days-container {
|
||||
margin-right: 1em;
|
||||
padding-left: 1em;
|
||||
padding-right: 1em;
|
||||
}
|
||||
.return-title {
|
||||
display: none;
|
||||
}
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
/home/mbess/font_awesome_icons/
|
248
static/home.html
248
static/home.html
|
@ -1,248 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Home</title>
|
||||
<meta charset="UTF-8" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Roboto&family=Roboto+Slab&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.1/css/all.min.css" />
|
||||
<link rel="stylesheet" href="./assets/main.css" />
|
||||
<link rel="stylesheet" href="./assets/home.css" />
|
||||
<meta name="viewport" content="width=device-width">
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class="header">
|
||||
<div class="container header-container">
|
||||
<div class="header-left">
|
||||
<div class="header-image">
|
||||
<img src="assets/img/espace_condorcet_logo.jpg" />
|
||||
</div>
|
||||
<div class="header-content">
|
||||
<a
|
||||
href="https://www.espacecondorcet.org/"
|
||||
class="header-sub-title">
|
||||
Espace Condorcet Centre Social
|
||||
</a>
|
||||
<h1 class="header-title">Forum des associations</h1>
|
||||
<div class="header-description">
|
||||
Cette année nous vous invitons à découvrir le forum virtuel des associations.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="header-menu">
|
||||
<a href="#">Mentions Légales</a>
|
||||
<a href="#">A propos</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="content">
|
||||
<div class="nav">
|
||||
<div
|
||||
id="nav-enabler"
|
||||
class="nav-item nav-mobile-enabler">
|
||||
<div class="nav-icon">
|
||||
<i class="fas fa-ellipsis-h"></i>
|
||||
</div>
|
||||
<div class="nav-item-content">
|
||||
<div id="nav-enabler-text" class="nav-title">
|
||||
Afficher le menu
|
||||
</div>
|
||||
<div class="nav-access">
|
||||
<i
|
||||
id="nav-enabler-icon"
|
||||
class="fas fa-chevron-down">
|
||||
</i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="nav-content">
|
||||
<div class="nav-item" id="nav-all">
|
||||
<div class="nav-icon">
|
||||
<i class="fas fa-ellipsis-h"></i>
|
||||
</div>
|
||||
<div class="nav-item-content">
|
||||
<div class="nav-title">
|
||||
Toutes
|
||||
</div>
|
||||
<div class="nav-access">
|
||||
<i class="fas fa-chevron-right"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="nav-item" data-tag-id="culturel">
|
||||
<div class="nav-icon">
|
||||
<i class="fas fa-theater-masks"></i>
|
||||
</div>
|
||||
<div class="nav-item-content">
|
||||
<div class="nav-title">
|
||||
Culturelles
|
||||
</div>
|
||||
<div class="nav-access">
|
||||
<i class="fas fa-chevron-right"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="nav-item" data-tag-id="music">
|
||||
<div class="nav-icon">
|
||||
<i class="fas fa-music"></i>
|
||||
</div>
|
||||
<div class="nav-item-content">
|
||||
<div class="nav-title">
|
||||
Danse et musique
|
||||
</div>
|
||||
<div class="nav-access">
|
||||
<i class="fas fa-chevron-right"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mosaic" id="mosaic">
|
||||
<div class="mosaic-header" id="mosaic-header">
|
||||
</div>
|
||||
<div class="card-container">
|
||||
<!--
|
||||
<div class="card">
|
||||
<div class="card-image">
|
||||
<img src="./assets/img/cross.png" />
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<div>
|
||||
<div class="card-title-container">
|
||||
<h2 class="card-title">
|
||||
Croix-rouge gaillonaise
|
||||
</h2>
|
||||
<div class="card-icon">
|
||||
<i class="fas fa-hands-helping"></i>
|
||||
</div>
|
||||
</div>
|
||||
<p class="card-description">
|
||||
Qui totam quibusdam ut. Provident sint est inventore quod deleniti labore. Nemo voluptate deserunt in dolorem doloremque corrupti asperiores. Aut consequatur ea eum. Aut sint dolore numquam saepe qui earum officia eius
|
||||
</p>
|
||||
</div>
|
||||
<div class="card-link">
|
||||
<a href="#link">En savoir plus</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-image">
|
||||
<img src="./assets/img/adam.png" />
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<div>
|
||||
<div class="card-title-container">
|
||||
<h2 class="card-title">
|
||||
Association des amis de la musique
|
||||
</h2>
|
||||
<div class="card-icon">
|
||||
<i class="fas fa-hands-helping"></i>
|
||||
</div>
|
||||
</div>
|
||||
<p class="card-description">
|
||||
Qui totam quibusdam ut. Provident sint est inventore quod deleniti labore. Nemo voluptate deserunt in dolorem doloremque corrupti asperiores. Aut consequatur ea eum. Aut sint dolore numquam saepe qui earum officia eius...
|
||||
</p>
|
||||
</div>
|
||||
<div class="card-link">
|
||||
<a href="#link">En savoir plus</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card">
|
||||
<div class="card-image">
|
||||
<img src="./assets/img/werobot.png" />
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<div>
|
||||
<div class="card-title-container">
|
||||
<h2 class="card-title">
|
||||
We Robot
|
||||
</h2>
|
||||
<div class="card-icon">
|
||||
<i class="fas fa-hands-helping"></i>
|
||||
</div>
|
||||
</div>
|
||||
<p class="card-description">
|
||||
Qui totam quibusdam ut. Provident sint est inventore quod deleniti labore. Nemo voluptate deserunt in dolorem doloremque corrupti asperiores. Aut consequatur ea eum. Aut sint dolore numquam saepe qui earum officia eius...
|
||||
</p>
|
||||
</div>
|
||||
<div class="card-link">
|
||||
<a href="#link">En savoir plus</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
let tags = [
|
||||
{
|
||||
"id": "culturel",
|
||||
"icon": "fas fa-theater-masks",
|
||||
"name": "Culturelles"
|
||||
},
|
||||
{
|
||||
"id": "music",
|
||||
"icon": "fas fa-music",
|
||||
"name": "Danse et musique"
|
||||
},
|
||||
{
|
||||
"id": "maritime",
|
||||
"icon": "fas fa-anchor",
|
||||
"name": "Maritime"
|
||||
}
|
||||
]
|
||||
let organizations = [
|
||||
{
|
||||
"name": "Croix-rouge gaillonaise",
|
||||
"slug": "croix-rouge",
|
||||
"icon": "fas fa-hands-helping",
|
||||
"thumbnail": "./assets/img/cross.png",
|
||||
"descriptionShort": "Qui totam quibusdam ut. Provident sint est inventore quod deleniti labore. Nemo voluptate deserunt in dolorem doloremque corrupti asperiores. Aut consequatur ea eum. Aut sint dolore numquam saepe qui earum officia eius",
|
||||
"tag": tags[0]
|
||||
},
|
||||
{
|
||||
"name": "Association des amis de la musique",
|
||||
"slug": "adam",
|
||||
"thumbnail": "./assets/img/adam.png",
|
||||
"descriptionShort": "Qui totam quibusdam ut. Provident sint est inventore quod deleniti labore. Nemo voluptate deserunt in dolorem doloremque corrupti asperiores. Aut consequatur ea eum. Aut sint dolore numquam saepe qui earum officia eius",
|
||||
"tag": tags[1]
|
||||
},
|
||||
{
|
||||
"name": "We Robot",
|
||||
"slug": "werobot",
|
||||
"thumbnail": "./assets/img/werobot.png",
|
||||
"descriptionShort": "Qui totam quibusdam ut. Provident sint est inventore quod deleniti labore. Nemo voluptate deserunt in dolorem doloremque corrupti asperiores. Aut consequatur ea eum. Aut sint dolore numquam saepe qui earum officia eius",
|
||||
"tag": tags[0]
|
||||
},
|
||||
{
|
||||
"name": "Hello world",
|
||||
"slug": "autre-assos",
|
||||
"thumbnail": "./assets/img/cross.png",
|
||||
"descriptionShort": "Qui totam quibusdam ut. Provident sint est inventore quod deleniti labore. Nemo voluptate deserunt in dolorem doloremque corrupti asperiores. Aut consequatur ea eum. Aut sint dolore numquam saepe qui earum officia eius",
|
||||
"tag": tags[2]
|
||||
},
|
||||
// {
|
||||
// "name": "Jean paul lel",
|
||||
// "slug": "jean-paul-lel",
|
||||
// "thumbnail": "https://randomuser.me/api/portraits/men/93.jpg",
|
||||
// "descriptionShort": "Qui totam quibusdam ut. Provident sint est inventore quod deleniti labore. Nemo voluptate deserunt in dolorem doloremque corrupti asperiores. Aut consequatur ea eum. Aut sint dolore numquam saepe qui earum officia eius",
|
||||
// "tag": tags[2]
|
||||
// },
|
||||
// {
|
||||
// "name": "WOWO",
|
||||
// "slug": "wowo",
|
||||
// "thumbnail": "https://randomuser.me/api/portraits/men/84.jpg",
|
||||
// "descriptionShort": "Qui totam quibusdam ut. Provident sint est inventore quod deleniti labore. Nemo voluptate deserunt in dolorem doloremque corrupti asperiores. Aut consequatur ea eum. Aut sint dolore numquam saepe qui earum officia eius",
|
||||
// "tag": tags[0]
|
||||
// }
|
||||
]
|
||||
</script>
|
||||
<script src="assets/js/home.js"></script>
|
||||
</body>
|
||||
</html>
|
|
@ -1,288 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Association</title>
|
||||
<meta charset="UTF-8" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Roboto&family=Roboto+Slab&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.1/css/all.min.css" />
|
||||
<link rel="stylesheet" href="./assets/main.css" />
|
||||
<link rel="stylesheet" href="./assets/organization.css" />
|
||||
<meta name="viewport" content="width=device-width">
|
||||
</head>
|
||||
<body>
|
||||
<div class="header">
|
||||
<div class="container header-container">
|
||||
<div class="return">
|
||||
<div class="return-icon"><i class="fas fa-chevron-circle-left"></i></div>
|
||||
<div class="return-title">Revenir à la liste</div>
|
||||
</div>
|
||||
<div class="header-title">
|
||||
Forum des associations
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cover-background" style="background-image: url('https://s.werobot.fr/headerCover.jpeg')"></div>
|
||||
<div class="cover">
|
||||
<div class="cover-content container">
|
||||
<div class="cover-image" style="background-image: url('./assets/img/werobot.png');">
|
||||
</div>
|
||||
<div class="cover-title-container">
|
||||
<h1 class="cover-title">
|
||||
We Robot
|
||||
</h1>
|
||||
<h4 class="cover-sub-title">
|
||||
Association de robotique
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="media-mosaic">
|
||||
<div class="media-container media-main">
|
||||
<div class="media" style="background-image: url('assets/img/dummy-1.jpg')"></div>
|
||||
</div>
|
||||
<div class="media-container media-1-1">
|
||||
<div class="media" style="background-image: url('assets/img/dummy-3.jpg')"></div>
|
||||
</div>
|
||||
<div class="media-container media-1-2">
|
||||
<div class="media" style="background-image: url('assets/img/dummy-2.jpg')"></div>
|
||||
<div class="media-overlay"><i class="fas fa-play-circle"></i></div>
|
||||
</div>
|
||||
<div class="media-container media-2-1">
|
||||
<div class="media" style="background-image: url('assets/img/dummy-4.jpg')"></div>
|
||||
</div>
|
||||
<div class="media-container media-2-2">
|
||||
<div class="media" style="background-image: url('assets/img/dummy-5.jpg')"></div>
|
||||
</div>
|
||||
</div>
|
||||
<section>
|
||||
<div class="section-title">
|
||||
<h2>Présentation</h2>
|
||||
<div class="section-divider"></div>
|
||||
</div>
|
||||
<div class="description">
|
||||
<p>
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Officia minima aliquam corporis fugit repellat obcaecati consequatur cumque, dolore omnis et porro, sit iusto similique blanditiis vel, alias quam ducimus voluptates.
|
||||
</p>
|
||||
<p>
|
||||
Unde neque adipisci et. Consequatur labore similique quia. Rerum nihil eius assumenda quae. Non vel sapiente omnis. Eum explicabo neque maxime sapiente et perspiciatis et.
|
||||
</p>
|
||||
<p>
|
||||
Delectus unde inventore similique ut quo. Consequatur assumenda quaerat aliquid velit et corrupti. Laboriosam qui magnam culpa est amet nobis tenetur. Ducimus a sint ea. Expedita omnis libero ipsum dolor ipsam dolor beatae.
|
||||
</p>
|
||||
<p>
|
||||
Qui vel sit expedita eum recusandae nemo. Facere quas dolor eum ut. Aut omnis et qui repellat nihil accusantium. Et vitae beatae ratione. Tenetur sit omnis sa
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<div class="section-title">
|
||||
<h2>Crénaux</h2>
|
||||
<div class="section-divider"></div>
|
||||
</div>
|
||||
<div class="schedule">
|
||||
<div class="schedule-category">
|
||||
<div class="schedule-category-header" title="Déroulez">
|
||||
<div class="schedule-category-name">
|
||||
Création de robots super cool
|
||||
</div>
|
||||
<i class="schedule-category-collapse-icon fas fa-chevron-circle-up"></i>
|
||||
</div>
|
||||
<div class="schedule-category-table">
|
||||
<div class="schedule-category-days-container">
|
||||
<div class="schedule-category-day-container">
|
||||
<div class="schedule-category-day">
|
||||
Lundi
|
||||
</div>
|
||||
<div class="schedule-category-hours">
|
||||
17:00 <span class="separator">-</span> 18:00
|
||||
</div>
|
||||
</div>
|
||||
<div class="schedule-category-day-container">
|
||||
<div class="schedule-category-day">
|
||||
Mardi
|
||||
</div>
|
||||
<div class="schedule-category-hours">
|
||||
14:00 <span class="separator">-</span> 15:00
|
||||
</div>
|
||||
</div>
|
||||
<div class="schedule-category-day-container">
|
||||
<div class="schedule-category-day">
|
||||
Samedi
|
||||
</div>
|
||||
<div class="schedule-category-hours">
|
||||
16:00 <span class="separator">-</span> 17:00
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="schedule-category">
|
||||
<div class="schedule-category-header" title="Déroulez">
|
||||
<div class="schedule-category-name">
|
||||
Cours de programmation de gros expert
|
||||
</div>
|
||||
<i class="schedule-category-collapse-icon fas fa-chevron-circle-up"></i>
|
||||
</div>
|
||||
<div class="schedule-category-table">
|
||||
<div class="schedule-category-days-container">
|
||||
<div class="schedule-category-day-container">
|
||||
<div class="schedule-category-day">
|
||||
Lundi
|
||||
</div>
|
||||
<div class="schedule-category-hours">
|
||||
17:00 <span class="separator">-</span> 18:00
|
||||
</div>
|
||||
</div>
|
||||
<div class="schedule-category-day-container">
|
||||
<div class="schedule-category-day">
|
||||
Mardi
|
||||
</div>
|
||||
<div class="schedule-category-hours">
|
||||
14:00 <span class="separator">-</span> 15:00
|
||||
</div>
|
||||
</div>
|
||||
<div class="schedule-category-day-container">
|
||||
<div class="schedule-category-day">
|
||||
Samedi
|
||||
</div>
|
||||
<div class="schedule-category-hours">
|
||||
16:00 <span class="separator">-</span> 17:00
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
<section>
|
||||
<div class="section-title">
|
||||
<h2>Tarifs</h2>
|
||||
<div class="section-divider"></div>
|
||||
</div>
|
||||
<div class="pricing">
|
||||
<div class="pricing-card">
|
||||
<div class="pricing-label">
|
||||
12 €
|
||||
</div>
|
||||
<div class="pricing-name">
|
||||
Enfants
|
||||
</div>
|
||||
<div class="pricing-description">
|
||||
Facere quas dolor eum ut.
|
||||
</div>
|
||||
</div>
|
||||
<div class="pricing-card">
|
||||
<div class="pricing-label">
|
||||
12 €
|
||||
</div>
|
||||
<div class="pricing-name">
|
||||
Enfants
|
||||
</div>
|
||||
<div class="pricing-description">
|
||||
Facere quas dolor eum ut.
|
||||
</div>
|
||||
</div>
|
||||
<div class="pricing-card">
|
||||
<div class="pricing-label">
|
||||
12 €
|
||||
</div>
|
||||
<div class="pricing-name">
|
||||
Enfants
|
||||
</div>
|
||||
<div class="pricing-description">
|
||||
Facere quas dolor eum ut.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
<section>
|
||||
<div class="section-title">
|
||||
<h2>Contact</h2>
|
||||
<div class="section-divider"></div>
|
||||
</div>
|
||||
<div class="contact">
|
||||
<div class="contact-item">
|
||||
<div class="contact-icon">
|
||||
<i class="fas fa-user"></i>
|
||||
</div>
|
||||
<div class="contact-content">
|
||||
Frank GITON
|
||||
</div>
|
||||
</div>
|
||||
<div class="contact-item">
|
||||
<div class="contact-icon">
|
||||
<i class="fas fa-at"></i>
|
||||
</div>
|
||||
<div class="contact-content">
|
||||
<a href="mailto:contact@werobot.fr">contact@werobot.fr</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="contact-item">
|
||||
<div class="contact-icon">
|
||||
<i class="fas fa-map-marker-alt"></i>
|
||||
</div>
|
||||
<div class="contact-content">
|
||||
<p>
|
||||
6, Rue qui fait des efforts
|
||||
</p>
|
||||
<p>
|
||||
27940 Gaillon
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="contact-item">
|
||||
<div class="contact-icon">
|
||||
<i class="fas fa-globe"></i>
|
||||
</div>
|
||||
<div class="contact-content">
|
||||
<a href="https://werobot.fr">https://werobot.fr <i class="external-link fa fa-external-link-alt"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="contact-item">
|
||||
<div class="contact-icon">
|
||||
<i class="fas fa-phone"></i>
|
||||
</div>
|
||||
<div class="contact-content">
|
||||
<a href="telto:+33783424852">07 81 42 88 42</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="contact-item facebook">
|
||||
<div class="contact-icon">
|
||||
<i class="fab fa-facebook-square"></i>
|
||||
</div>
|
||||
<div class="contact-content">
|
||||
<a href="https://www.facebook.com/WeRobot/">https://www.facebook.com/WeRobot/ <i class="external-link fa fa-external-link-alt"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="contact-item instagram">
|
||||
<div class="contact-icon">
|
||||
<i class="fab fa-instagram"></i>
|
||||
</div>
|
||||
<div class="contact-content">
|
||||
<a href="https://www.instagram.com/werobot/">https://www.instagram.com/werobot/ <i class="external-link fa fa-external-link-alt"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="contact-item twitter">
|
||||
<div class="contact-icon">
|
||||
<i class="fab fa-twitter"></i>
|
||||
</div>
|
||||
<div class="contact-content">
|
||||
<a href="https://www.twitter.com/werobot_FR/">https://www.twitter.com/werobot_FR/ <i class="external-link fa fa-external-link-alt"></i></a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
|
||||
<div class="footer">
|
||||
<div></div>
|
||||
<div></div>
|
||||
<div></div>
|
||||
</div>
|
||||
<script src="assets/js/organization.js"></script>
|
||||
</body>
|
||||
</html>
|
15
views/about.twig
Normal file
15
views/about.twig
Normal file
|
@ -0,0 +1,15 @@
|
|||
{% extends "./base.twig" %}
|
||||
{% block title %}A propos{% endblock %}
|
||||
{% block content %}
|
||||
<div>
|
||||
<p>
|
||||
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Autem alias sapiente neque? Dignissimos harum blanditiis fugiat eius alias nam repudiandae, et explicabo nihil eos, quos reprehenderit nobis aperiam quibusdam ad?
|
||||
</p>
|
||||
<p>
|
||||
Takimata dolores sanctus lorem dolor labore dolores lorem voluptua diam ipsum, at accusam sed tempor accusam ea clita et tempor. Duo kasd eirmod at amet sed sed sanctus sit, sed kasd eos dolore amet diam nonumy est ipsum diam, lorem tempor dolore sed tempor sed eos justo no amet. Est.Lorem, ipsum dolor sit amet consectetur adipisicing elit. Autem alias sapiente neque? Dignissimos harum blanditiis fugiat eius alias nam repudiandae, et explicabo nihil eos, quos reprehenderit nobis aperiam quibusdam ad?
|
||||
</p>
|
||||
<p>
|
||||
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Autem alias sapiente neque? Dignissimos harum blanditiis fugiat eius alias nam repudiandae, et explicabo nihil eos, quos reprehenderit nobis aperiam quibusdam ad?
|
||||
</p>
|
||||
</div>
|
||||
{% endblock %}
|
|
@ -1,11 +1,55 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>{% block title %}{% endblock %} - Forum des associations 2020</title>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width">
|
||||
<link rel="icon" type="image/png" href="/assets/img/favicon.png" />
|
||||
|
||||
<title>{% block title %}{% endblock %} | Forum des associations 2020</title>
|
||||
|
||||
<link href="https://fonts.googleapis.com/css2?family=Roboto&family=Roboto+Slab&display=swap" rel="stylesheet">
|
||||
<link rel="stylesheet" href="/assets/main.css" />
|
||||
{% if layout is not defined %}
|
||||
<link rel="stylesheet" href="/assets/home.css" />
|
||||
{% endif %}
|
||||
|
||||
{% block head %}{% endblock %}
|
||||
</head>
|
||||
<body>
|
||||
<div id="content">{% block content %}{% endblock %}</div>
|
||||
{% block script %}{% endblock %}
|
||||
{% if layout is not defined %}
|
||||
<div class="header">
|
||||
<div class="container header-container">
|
||||
<div class="header-left">
|
||||
<div class="header-image">
|
||||
<a href="/"><img src="/assets/img/espace_condorcet_logo.jpg" /></a>
|
||||
</div>
|
||||
<div class="header-content">
|
||||
<a
|
||||
href="https://www.espacecondorcet.org/"
|
||||
class="header-sub-title">
|
||||
Espace Condorcet Centre Social
|
||||
</a>
|
||||
<h1 class="header-title">Forum des associations</h1>
|
||||
<div class="header-description">
|
||||
Cette année nous vous invitons à découvrir le forum virtuel des associations.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="header-menu">
|
||||
<a href="/mentions-legales">Mentions Légales</a>
|
||||
<a href="/a-propos">A propos</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="content">
|
||||
{% block content %}{% endblock %}
|
||||
</div>
|
||||
</div>
|
||||
{% else %}
|
||||
{% block content %}{% endblock %}
|
||||
{% endif %}
|
||||
|
||||
{% block scripts %}{% endblock %}
|
||||
</body>
|
||||
</html>
|
|
@ -20,5 +20,9 @@ La personne vérifiant ces modifications a laissé un message indiquant la raiso
|
|||
N'hésitez pas à corriger les informations et à resoumettre pour une nouvelle verification et peut être cette fois ci vous serez publiés...
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Pour rappel, vous pouvez utiliser ce lien pour vous connecter sur votre interface : <a href="{{ link }}">{{ link }}</a>
|
||||
</p>
|
||||
|
||||
<p>Coordialement</p>
|
||||
|
||||
|
|
|
@ -4,7 +4,9 @@
|
|||
Ceci est un email automatique afin de communiquer le lien au gérant de l'association nommée "{{ adminName }}" dans le but de modifier les informations concernant cette association sur la platforme de espace condorcet.
|
||||
</p>
|
||||
|
||||
<a href="{{ link }}">{{ link }}</a>
|
||||
<p>
|
||||
Vous pouvez utilisez ce lien pour vous connecter sur l'interface web permettant de modifier votre association sur la platforme : <a href="{{ link }}">{{ link }}</a>
|
||||
</p>
|
||||
|
||||
<p>Voici votre clée: {{ token }}</p>
|
||||
|
||||
|
|
104
views/home.twig
104
views/home.twig
|
@ -1,13 +1,97 @@
|
|||
{% extends "./base.twig" %}
|
||||
{% block title %}Index{% endblock %}
|
||||
{% block head %}
|
||||
<style type="text/css">
|
||||
.important { color: #336699; }
|
||||
</style>
|
||||
{% endblock %}
|
||||
{% block title %}Accueil{% endblock %}
|
||||
{% block head %}{% endblock %}
|
||||
{% block content %}
|
||||
<h1>Index</h1>
|
||||
<p class="important">
|
||||
Welcome on my awesome homepage.
|
||||
</p>
|
||||
<div class="nav">
|
||||
<div
|
||||
id="nav-enabler"
|
||||
class="nav-item nav-mobile-enabler">
|
||||
<div class="nav-icon">
|
||||
<i class="fas fa-ellipsis-h"></i>
|
||||
</div>
|
||||
<div class="nav-item-content">
|
||||
<div id="nav-enabler-text" class="nav-title">
|
||||
Afficher le menu
|
||||
</div>
|
||||
<div class="nav-access">
|
||||
<i
|
||||
id="nav-enabler-icon"
|
||||
class="fas fa-chevron-down">
|
||||
</i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="nav-content">
|
||||
<div class="nav-item" id="nav-all">
|
||||
<div class="nav-icon">
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
focusable="false"
|
||||
role="img"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512">
|
||||
<path fill="currentColor" d="M328 256c0 39.8-32.2 72-72 72s-72-32.2-72-72 32.2-72 72-72 72 32.2 72 72zm104-72c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72zm-352 0c-39.8 0-72 32.2-72 72s32.2 72 72 72 72-32.2 72-72-32.2-72-72-72z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="nav-item-content">
|
||||
<div class="nav-title">
|
||||
Toutes
|
||||
</div>
|
||||
<div class="nav-access">
|
||||
<i class="fas fa-chevron-right"></i>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% for tag in tags %}
|
||||
<div class="nav-item" data-tag-id="{{ tag._id }}">
|
||||
<div class="nav-icon">
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
focusable="false"
|
||||
role="img"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 {{ tag.icon.width }} {{ tag.icon.height }}">
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="{{ tag.icon.path }}"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="nav-item-content">
|
||||
<div class="nav-title">
|
||||
{{ tag.name }}
|
||||
</div>
|
||||
<div class="nav-access">
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
focusable="false"
|
||||
data-prefix="fas"
|
||||
data-icon="chevron-right"
|
||||
class="svg-inline--fa fa-chevron-right fa-w-10"
|
||||
role="img"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 320 512">
|
||||
<path
|
||||
fill="currentColor"
|
||||
d="M285.476 272.971L91.132 467.314c-9.373 9.373-24.569 9.373-33.941 0l-22.667-22.667c-9.357-9.357-9.375-24.522-.04-33.901L188.505 256 34.484 101.255c-9.335-9.379-9.317-24.544.04-33.901l22.667-22.667c9.373-9.373 24.569-9.373 33.941 0L285.475 239.03c9.373 9.372 9.373 24.568.001 33.941z"
|
||||
></path>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="mosaic" id="mosaic">
|
||||
<div class="mosaic-header" id="mosaic-header"></div>
|
||||
<div class="card-container"></div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script>
|
||||
let tags = JSON.parse(`{{ tagsJSON }}`)
|
||||
let organizations = JSON.parse(`{{ organizationsJSON }}`)
|
||||
</script>
|
||||
<script src="/assets/js/home.js"></script>
|
||||
{% endblock %}
|
43
views/legals.twig
Normal file
43
views/legals.twig
Normal file
|
@ -0,0 +1,43 @@
|
|||
{% extends "./base.twig" %}
|
||||
{% block title %}Informations légales{% endblock %}
|
||||
{% block content %}
|
||||
<div>
|
||||
<h1>Informations légales</h1>
|
||||
|
||||
<h3>Siège social</h3>
|
||||
|
||||
<p>
|
||||
Espace Condorcet Centre Social<br>
|
||||
12 rue Jean Moulin,<br>
|
||||
27600 GAILLON
|
||||
</p>
|
||||
|
||||
<h3>Contact</h3>
|
||||
|
||||
<p>
|
||||
Téléphone : 02 32 77 50 80<br>
|
||||
Fax : 02 32 77 50 99
|
||||
</p>
|
||||
|
||||
<h3>Représentant légal</h3>
|
||||
|
||||
<p>Liliane COQUET</p>
|
||||
|
||||
|
||||
<h3>Immatriculation</h3>
|
||||
|
||||
<p>
|
||||
Numéro SIREN : 338 248 206 000 25<br>
|
||||
|
||||
Code APE 88 99 B
|
||||
</p>
|
||||
|
||||
<h3>Hébergement</h3>
|
||||
|
||||
<p>
|
||||
Scaleway<br>
|
||||
|
||||
ONLINE SAS BP 438 75366 PARIS CEDEX 08 FRANCE
|
||||
</p>
|
||||
</div>
|
||||
{% endblock %}
|
7
views/not-found.twig
Normal file
7
views/not-found.twig
Normal file
|
@ -0,0 +1,7 @@
|
|||
{% extends "./base.twig" %}
|
||||
{% block title %}Page introuvable{% endblock %}
|
||||
{% block content %}
|
||||
<div>
|
||||
<h1>Page introuvable</h1>
|
||||
</div>
|
||||
{% endblock %}
|
272
views/organization.twig
Normal file
272
views/organization.twig
Normal file
|
@ -0,0 +1,272 @@
|
|||
{% extends "./base.twig" %}
|
||||
{% block title %}Association{% endblock %}
|
||||
{% block head %}
|
||||
<link rel="stylesheet" href="/assets/organization.css" />
|
||||
{% endblock %}
|
||||
{% block content %}
|
||||
<div class="header">
|
||||
<div class="container header-container">
|
||||
<a href="/" class="return">
|
||||
<div class="return-icon">
|
||||
<svg
|
||||
aria-hidden="true"
|
||||
focusable="false"
|
||||
role="img"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512">
|
||||
<path fill="currentColor" d="M256 504C119 504 8 393 8 256S119 8 256 8s248 111 248 248-111 248-248 248zM142.1 273l135.5 135.5c9.4 9.4 24.6 9.4 33.9 0l17-17c9.4-9.4 9.4-24.6 0-33.9L226.9 256l101.6-101.6c9.4-9.4 9.4-24.6 0-33.9l-17-17c-9.4-9.4-24.6-9.4-33.9 0L142.1 239c-9.4 9.4-9.4 24.6 0 34z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="return-title">Revenir à la liste</div>
|
||||
</a>
|
||||
<div class="header-title">
|
||||
Forum des associations
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="cover-background" style="background-image: url({{ data.cover.location }})"></div>
|
||||
<div class="cover">
|
||||
<div class="cover-content container">
|
||||
<div class="cover-image" style="background-image: url({{ data.thumbnail.location }});">
|
||||
</div>
|
||||
<div class="cover-title-container">
|
||||
<h1 class="cover-title">
|
||||
{{ data.name }}
|
||||
</h1>
|
||||
<h4 class="cover-sub-title">
|
||||
|
||||
</h4>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container">
|
||||
<div class="media-mosaic">
|
||||
{% for media in data.gallery %}
|
||||
<div class="media-container">
|
||||
<div class="media" style="background-image: url({{ media.location }})"></div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
{# <div class="media-container media-1-2">
|
||||
<div class="media" style="background-image: url({{ data.gallery[2].location }})"></div>
|
||||
<div class="media-overlay"><i class="fas fa-play-circle"></i></div>
|
||||
</div> #}
|
||||
</div>
|
||||
|
||||
{% if data.descriptionLong|length > 0 %}
|
||||
<section>
|
||||
<div class="section-title">
|
||||
<h2>Présentation</h2>
|
||||
<div class="section-divider"></div>
|
||||
</div>
|
||||
<div class="description">
|
||||
{{ data.descriptionLong|raw }}
|
||||
</div>
|
||||
</section>
|
||||
{% endif %}
|
||||
|
||||
{% if data.schedule|length > 0 %}
|
||||
<section>
|
||||
<div class="section-title">
|
||||
<h2>Crénaux</h2>
|
||||
<div class="section-divider"></div>
|
||||
</div>
|
||||
<div class="schedule">
|
||||
{% for item in data.schedule %}
|
||||
<div class="schedule-category">
|
||||
<div class="schedule-category-header" title="Déroulez">
|
||||
<div class="schedule-category-name">
|
||||
{{ item.name }}
|
||||
</div>
|
||||
<svg
|
||||
class="schedule-category-collapse-icon"
|
||||
aria-hidden="true"
|
||||
focusable="false"
|
||||
role="img"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512">
|
||||
<path fill="currentColor" d="M8 256C8 119 119 8 256 8s248 111 248 248-111 248-248 248S8 393 8 256zm231-113.9L103.5 277.6c-9.4 9.4-9.4 24.6 0 33.9l17 17c9.4 9.4 24.6 9.4 33.9 0L256 226.9l101.6 101.6c9.4 9.4 24.6 9.4 33.9 0l17-17c9.4-9.4 9.4-24.6 0-33.9L273 142.1c-9.4-9.4-24.6-9.4-34 0z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="schedule-category-table">
|
||||
<div class="schedule-category-days-container">
|
||||
{% for when in item.when %}
|
||||
<div class="schedule-category-day-container">
|
||||
<div class="schedule-category-day">
|
||||
{{ when.day }}
|
||||
</div>
|
||||
<div class="schedule-category-hours">
|
||||
{{ when.from }} <span class="separator">-</span> {{ when.to }}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</section>
|
||||
{% endif %}
|
||||
|
||||
{% if data.pricing|length > 0 %}
|
||||
<section>
|
||||
<div class="section-title">
|
||||
<h2>Tarifs</h2>
|
||||
<div class="section-divider"></div>
|
||||
</div>
|
||||
<div class="pricing">
|
||||
{% for item in data.pricing %}
|
||||
<div class="pricing-card">
|
||||
<div class="pricing-label">
|
||||
{{ item.priceLabel }}
|
||||
</div>
|
||||
<div class="pricing-name">
|
||||
{{ item.name }}
|
||||
</div>
|
||||
<div class="pricing-description">
|
||||
{{ item.description }}
|
||||
</div>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</section>
|
||||
{% endif %}
|
||||
|
||||
{% if data.contacts is defined %}
|
||||
<section>
|
||||
<div class="section-title">
|
||||
<h2>Contact</h2>
|
||||
<div class="section-divider"></div>
|
||||
</div>
|
||||
<div class="contact">
|
||||
{% if data.contacts.person|length > 0 %}
|
||||
<div class="contact-item person">
|
||||
<div class="contact-icon">
|
||||
<svg aria-hidden="true" focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
|
||||
<path fill="currentColor" d="M224 256c70.7 0 128-57.3 128-128S294.7 0 224 0 96 57.3 96 128s57.3 128 128 128zm89.6 32h-16.7c-22.2 10.2-46.9 16-72.9 16s-50.6-5.8-72.9-16h-16.7C60.2 288 0 348.2 0 422.4V464c0 26.5 21.5 48 48 48h352c26.5 0 48-21.5 48-48v-41.6c0-74.2-60.2-134.4-134.4-134.4z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="contact-content">
|
||||
{{ data.contacts.person }}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if data.contacts.email|length > 0 %}
|
||||
<div class="contact-item email">
|
||||
<div class="contact-icon">
|
||||
<svg aria-hidden="true" focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
||||
<path fill="currentColor" d="M256 8C118.941 8 8 118.919 8 256c0 137.059 110.919 248 248 248 48.154 0 95.342-14.14 135.408-40.223 12.005-7.815 14.625-24.288 5.552-35.372l-10.177-12.433c-7.671-9.371-21.179-11.667-31.373-5.129C325.92 429.757 291.314 440 256 440c-101.458 0-184-82.542-184-184S154.542 72 256 72c100.139 0 184 57.619 184 160 0 38.786-21.093 79.742-58.17 83.693-17.349-.454-16.91-12.857-13.476-30.024l23.433-121.11C394.653 149.75 383.308 136 368.225 136h-44.981a13.518 13.518 0 0 0-13.432 11.993l-.01.092c-14.697-17.901-40.448-21.775-59.971-21.775-74.58 0-137.831 62.234-137.831 151.46 0 65.303 36.785 105.87 96 105.87 26.984 0 57.369-15.637 74.991-38.333 9.522 34.104 40.613 34.103 70.71 34.103C462.609 379.41 504 307.798 504 232 504 95.653 394.023 8 256 8zm-21.68 304.43c-22.249 0-36.07-15.623-36.07-40.771 0-44.993 30.779-72.729 58.63-72.729 22.292 0 35.601 15.241 35.601 40.77 0 45.061-33.875 72.73-58.161 72.73z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="contact-content">
|
||||
<a href="mailto:{{ data.contacts.email }}">{{ data.contacts.email }}</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if data.contacts.address|length > 0 %}
|
||||
<div class="contact-item address">
|
||||
<div class="contact-icon">
|
||||
<svg aria-hidden="true"focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512">
|
||||
<path fill="currentColor" d="M172.268 501.67C26.97 291.031 0 269.413 0 192 0 85.961 85.961 0 192 0s192 85.961 192 192c0 77.413-26.97 99.031-172.268 309.67-9.535 13.774-29.93 13.773-39.464 0zM192 272c44.183 0 80-35.817 80-80s-35.817-80-80-80-80 35.817-80 80 35.817 80 80 80z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="contact-content">
|
||||
{% for line in data.contacts.address %}
|
||||
<span>{{ line }}</span><br>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if data.contacts.phone|length > 0 %}
|
||||
<div class="contact-item phone">
|
||||
<div class="contact-icon">
|
||||
<svg aria-hidden="true"focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
||||
<path fill="currentColor" d="M493.4 24.6l-104-24c-11.3-2.6-22.9 3.3-27.5 13.9l-48 112c-4.2 9.8-1.4 21.3 6.9 28l60.6 49.6c-36 76.7-98.9 140.5-177.2 177.2l-49.6-60.6c-6.8-8.3-18.2-11.1-28-6.9l-112 48C3.9 366.5-2 378.1.6 389.4l24 104C27.1 504.2 36.7 512 48 512c256.1 0 464-207.5 464-464 0-11.2-7.7-20.9-18.6-23.4z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="contact-content">
|
||||
<a href="telto:{{ data.contacts.phoneInt }}">{{ data.contacts.phoneSplit }}</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if data.contacts.website|length > 0 %}
|
||||
<div class="contact-item website">
|
||||
<div class="contact-icon">
|
||||
<svg aria-hidden="true"focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512">
|
||||
<path fill="currentColor" d="M336.5 160C322 70.7 287.8 8 248 8s-74 62.7-88.5 152h177zM152 256c0 22.2 1.2 43.5 3.3 64h185.3c2.1-20.5 3.3-41.8 3.3-64s-1.2-43.5-3.3-64H155.3c-2.1 20.5-3.3 41.8-3.3 64zm324.7-96c-28.6-67.9-86.5-120.4-158-141.6 24.4 33.8 41.2 84.7 50 141.6h108zM177.2 18.4C105.8 39.6 47.8 92.1 19.3 160h108c8.7-56.9 25.5-107.8 49.9-141.6zM487.4 192H372.7c2.1 21 3.3 42.5 3.3 64s-1.2 43-3.3 64h114.6c5.5-20.5 8.6-41.8 8.6-64s-3.1-43.5-8.5-64zM120 256c0-21.5 1.2-43 3.3-64H8.6C3.2 212.5 0 233.8 0 256s3.2 43.5 8.6 64h114.6c-2-21-3.2-42.5-3.2-64zm39.5 96c14.5 89.3 48.7 152 88.5 152s74-62.7 88.5-152h-177zm159.3 141.6c71.4-21.2 129.4-73.7 158-141.6h-108c-8.8 56.9-25.6 107.8-50 141.6zM19.3 352c28.6 67.9 86.5 120.4 158 141.6-24.4-33.8-41.2-84.7-50-141.6h-108z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="contact-content">
|
||||
<a href="{{ data.contacts.website }}">
|
||||
{{ data.contacts.website }}
|
||||
<svg class="external-link" aria-hidden="true"focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512">
|
||||
<path fill="currentColor" d="M432,320H400a16,16,0,0,0-16,16V448H64V128H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V336A16,16,0,0,0,432,320ZM488,0h-128c-21.37,0-32.05,25.91-17,41l35.73,35.73L135,320.37a24,24,0,0,0,0,34L157.67,377a24,24,0,0,0,34,0L435.28,133.32,471,169c15,15,41,4.5,41-17V24A24,24,0,0,0,488,0Z"></path>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if data.contacts.facebook|length > 0 %}
|
||||
<div class="contact-item facebook">
|
||||
<div class="contact-icon">
|
||||
<svg aria-hidden="true"focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
|
||||
<path fill="currentColor" d="M279.14 288l14.22-92.66h-88.91v-60.13c0-25.35 12.42-50.06 52.24-50.06h40.42V6.26S260.43 0 225.36 0c-73.22 0-121.08 44.38-121.08 124.72v70.62H22.89V288h81.39v224h100.17V288z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="contact-content">
|
||||
<a href="{{ data.contacts.facebook }}">
|
||||
{{ data.contacts.facebook }}
|
||||
<svg class="external-link" aria-hidden="true"focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512">
|
||||
<path fill="currentColor" d="M432,320H400a16,16,0,0,0-16,16V448H64V128H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V336A16,16,0,0,0,432,320ZM488,0h-128c-21.37,0-32.05,25.91-17,41l35.73,35.73L135,320.37a24,24,0,0,0,0,34L157.67,377a24,24,0,0,0,34,0L435.28,133.32,471,169c15,15,41,4.5,41-17V24A24,24,0,0,0,488,0Z"></path>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if data.contacts.instagram|length > 0 %}
|
||||
<div class="contact-item instagram">
|
||||
<div class="contact-icon">
|
||||
<svg aria-hidden="true"focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512">
|
||||
<path fill="currentColor" d="M224.1 141c-63.6 0-114.9 51.3-114.9 114.9s51.3 114.9 114.9 114.9S339 319.5 339 255.9 287.7 141 224.1 141zm0 189.6c-41.1 0-74.7-33.5-74.7-74.7s33.5-74.7 74.7-74.7 74.7 33.5 74.7 74.7-33.6 74.7-74.7 74.7zm146.4-194.3c0 14.9-12 26.8-26.8 26.8-14.9 0-26.8-12-26.8-26.8s12-26.8 26.8-26.8 26.8 12 26.8 26.8zm76.1 27.2c-1.7-35.9-9.9-67.7-36.2-93.9-26.2-26.2-58-34.4-93.9-36.2-37-2.1-147.9-2.1-184.9 0-35.8 1.7-67.6 9.9-93.9 36.1s-34.4 58-36.2 93.9c-2.1 37-2.1 147.9 0 184.9 1.7 35.9 9.9 67.7 36.2 93.9s58 34.4 93.9 36.2c37 2.1 147.9 2.1 184.9 0 35.9-1.7 67.7-9.9 93.9-36.2 26.2-26.2 34.4-58 36.2-93.9 2.1-37 2.1-147.8 0-184.8zM398.8 388c-7.8 19.6-22.9 34.7-42.6 42.6-29.5 11.7-99.5 9-132.1 9s-102.7 2.6-132.1-9c-19.6-7.8-34.7-22.9-42.6-42.6-11.7-29.5-9-99.5-9-132.1s-2.6-102.7 9-132.1c7.8-19.6 22.9-34.7 42.6-42.6 29.5-11.7 99.5-9 132.1-9s102.7-2.6 132.1 9c19.6 7.8 34.7 22.9 42.6 42.6 11.7 29.5 9 99.5 9 132.1s2.7 102.7-9 132.1z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="contact-content">
|
||||
<a href="{{ data.contacts.instagram }}">
|
||||
{{ data.contacts.instagram }}
|
||||
<svg class="external-link" aria-hidden="true"focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512">
|
||||
<path fill="currentColor" d="M432,320H400a16,16,0,0,0-16,16V448H64V128H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V336A16,16,0,0,0,432,320ZM488,0h-128c-21.37,0-32.05,25.91-17,41l35.73,35.73L135,320.37a24,24,0,0,0,0,34L157.67,377a24,24,0,0,0,34,0L435.28,133.32,471,169c15,15,41,4.5,41-17V24A24,24,0,0,0,488,0Z"></path>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% if data.contacts.twitter|length > 0 %}
|
||||
<div class="contact-item twitter">
|
||||
<div class="contact-icon">
|
||||
<svg aria-hidden="true"focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
||||
<path fill="currentColor" d="M459.37 151.716c.325 4.548.325 9.097.325 13.645 0 138.72-105.583 298.558-298.558 298.558-59.452 0-114.68-17.219-161.137-47.106 8.447.974 16.568 1.299 25.34 1.299 49.055 0 94.213-16.568 130.274-44.832-46.132-.975-84.792-31.188-98.112-72.772 6.498.974 12.995 1.624 19.818 1.624 9.421 0 18.843-1.3 27.614-3.573-48.081-9.747-84.143-51.98-84.143-102.985v-1.299c13.969 7.797 30.214 12.67 47.431 13.319-28.264-18.843-46.781-51.005-46.781-87.391 0-19.492 5.197-37.36 14.294-52.954 51.655 63.675 129.3 105.258 216.365 109.807-1.624-7.797-2.599-15.918-2.599-24.04 0-57.828 46.782-104.934 104.934-104.934 30.213 0 57.502 12.67 76.67 33.137 23.715-4.548 46.456-13.32 66.599-25.34-7.798 24.366-24.366 44.833-46.132 57.827 21.117-2.273 41.584-8.122 60.426-16.243-14.292 20.791-32.161 39.308-52.628 54.253z"></path>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="contact-content">
|
||||
<a href="{{ data.contacts.twitter }}">
|
||||
{{ data.contacts.twitter }}
|
||||
<svg class="external-link" aria-hidden="true"focusable="false" role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 496 512">
|
||||
<path fill="currentColor" d="M432,320H400a16,16,0,0,0-16,16V448H64V128H208a16,16,0,0,0,16-16V80a16,16,0,0,0-16-16H48A48,48,0,0,0,0,112V464a48,48,0,0,0,48,48H400a48,48,0,0,0,48-48V336A16,16,0,0,0,432,320ZM488,0h-128c-21.37,0-32.05,25.91-17,41l35.73,35.73L135,320.37a24,24,0,0,0,0,34L157.67,377a24,24,0,0,0,34,0L435.28,133.32,471,169c15,15,41,4.5,41-17V24A24,24,0,0,0,488,0Z"></path>
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</section>
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="footer">
|
||||
<div></div>
|
||||
<div></div>
|
||||
<div></div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
|
||||
{% block scripts %}
|
||||
<script src="/assets/js/organization.js"></script>
|
||||
{% endblock %}
|
Loading…
Reference in a new issue