From 359cc430f51d7d172eee1944f1019d9e0ae351fa Mon Sep 17 00:00:00 2001 From: Roman Timashev Date: Thu, 3 Mar 2016 01:34:45 +0300 Subject: [PATCH] FUCKING BIG UPDATE: server, parallax, apis, new data models, style, layout, other --- src/client/api/API.js | 12 +- src/client/api/APIAlbum.js | 16 +++ src/client/api/APICollective.js | 2 +- src/client/api/APIDocument.js | 4 +- src/client/api/APIEvent.js | 4 +- src/client/api/APIFeed.js | 13 -- src/client/api/APIGallery.js | 4 +- src/client/api/APISchedule.js | 12 +- src/client/api/APITeacher.js | 14 +++ src/client/api/APITimeline.js | 9 ++ src/client/api/EndPoint.js | 4 + src/client/app.js | 118 +++++++++++++++++- src/client/components/Album.js | 26 ++++ src/client/components/AlbumCollection.js | 3 +- src/client/components/Award.js | 5 +- src/client/components/GalleryItem.js | 8 +- src/client/components/Navigation.js | 3 +- src/client/components/PageAlbum.js | 31 +++++ src/client/components/PageCollective.js | 16 +-- src/client/components/PageDocuments.js | 47 ++++--- src/client/components/PageEvents.js | 11 +- src/client/components/PageGallery.js | 44 ++++--- src/client/components/PageSchedule.js | 96 +++++++------- src/client/components/PageSchool.js | 11 +- src/client/components/PageTeacher.js | 14 +++ src/client/components/Parallax.js | 82 ++++++++++++ src/client/components/Schedule.js | 5 +- src/client/components/ScheduleSlider.js | 4 +- src/client/components/TeacherProfile.js | 16 ++- src/client/components/Timeline.js | 8 +- src/client/components/TimelineRecordPost.js | 2 +- src/client/config.js | 43 +------ src/client/controllers/AppController.js | 12 +- src/core/schedule.js | 26 ++-- src/instagram/publish.js | 4 +- src/models/schedule.js | 21 +++- src/routes/documents.js | 2 +- src/routes/events.js | 11 +- src/routes/gallery.js | 102 +++++++++------ src/routes/index.js | 9 +- src/routes/news.js | 112 ++++++++--------- src/routes/teachers.js | 51 ++++++++ src/server.js | 4 +- src/style/album.scss | 15 +-- src/style/body-wrapper.scss | 8 +- src/style/components/album-collection.scss | 3 +- src/style/components/album.scss | 48 +++++++ src/style/components/document.scss | 2 +- .../documents-container.scss} | 7 +- src/style/components/event-post.scss | 26 +++- src/style/components/gallery-item.scss | 27 +++- src/style/components/main-menu.scss | 24 ++-- src/style/components/navigation.scss | 16 ++- src/style/components/page-collective.scss | 14 +++ src/style/components/page-school.scss | 29 ++++- src/style/components/parallax.scss | 19 +++ src/style/components/teacher-proifile.scss | 27 ++-- src/style/style.scss | 5 +- .../components/album-collection.html | 4 +- src/templates/components/album.html | 15 +++ src/templates/components/award.html | 8 +- src/templates/components/event-post.html | 8 +- src/templates/components/gallery-item.html | 9 +- src/templates/components/navigation.html | 2 +- src/templates/components/page-album.html | 34 +++++ src/templates/components/page-collective.html | 13 +- src/templates/components/page-documents.html | 6 +- src/templates/components/page-event.html | 4 +- src/templates/components/page-events.html | 6 +- src/templates/components/page-gallery.html | 8 +- src/templates/components/page-schedule.html | 10 +- src/templates/components/page-school.html | 10 +- src/templates/components/page-teacher.html | 3 + src/templates/components/parallax.html | 6 + src/templates/components/schedule-record.html | 2 +- src/templates/components/schedule-table.html | 19 +-- src/templates/components/teacher-profile.html | 17 +-- src/templates/main.html | 13 +- 78 files changed, 1063 insertions(+), 445 deletions(-) create mode 100644 src/client/api/APIAlbum.js delete mode 100644 src/client/api/APIFeed.js create mode 100644 src/client/api/APITeacher.js create mode 100644 src/client/api/APITimeline.js create mode 100644 src/client/components/Album.js create mode 100644 src/client/components/PageAlbum.js create mode 100644 src/client/components/PageTeacher.js create mode 100644 src/client/components/Parallax.js create mode 100644 src/routes/teachers.js create mode 100644 src/style/components/album.scss rename src/style/{documents.scss => components/documents-container.scss} (54%) create mode 100644 src/style/components/parallax.scss create mode 100644 src/templates/components/album.html create mode 100644 src/templates/components/page-album.html create mode 100644 src/templates/components/page-teacher.html create mode 100644 src/templates/components/parallax.html diff --git a/src/client/api/API.js b/src/client/api/API.js index d7356cc1..5040cddc 100644 --- a/src/client/api/API.js +++ b/src/client/api/API.js @@ -1,16 +1,16 @@ -import APIFeed from './APIFeed'; -import APIGallery from './APIGallery'; +import APITimeline from './APITimeline'; +import APIAlbum from './APIAlbum'; import APIDocument from './APIDocument'; -import APICollective from './APICollective'; +import APITeacher from './APITeacher'; import APISchedule from './APISchedule'; import APIEvent from './APIEvent'; export default class API { constructor(request) { - this.news = new APIFeed(request); - this.gallery = new APIGallery(request); + this.timeline = new APITimeline(request); + this.album = new APIAlbum(request); this.document = new APIDocument(request); - this.collective = new APICollective(request); + this.teacher = new APITeacher(request); this.schedule = new APISchedule(request); this.event = new APIEvent(request); } diff --git a/src/client/api/APIAlbum.js b/src/client/api/APIAlbum.js new file mode 100644 index 00000000..58ec4c15 --- /dev/null +++ b/src/client/api/APIAlbum.js @@ -0,0 +1,16 @@ +import EndPoint from './EndPoint'; + +export default class APIAlbum extends EndPoint { + list(){ + return this.get(`/gallery`); + } + + year(year) { + return this.get(`/gallery/${year}`); + } + + fetch(id, doPopulate) { + let url = `/album/${id}?populate=${doPopulate}`; + return this.get(url); + } +} diff --git a/src/client/api/APICollective.js b/src/client/api/APICollective.js index f144603f..a4a208ef 100644 --- a/src/client/api/APICollective.js +++ b/src/client/api/APICollective.js @@ -4,6 +4,6 @@ export default class APICollective extends EndPoint { list(sort=null) { let url = '/collective'; if(sort) url = `/collective?sort=${sort.join(',')}`; - return this.request.get(url, {cache: true}); + return this.get(url); } } \ No newline at end of file diff --git a/src/client/api/APIDocument.js b/src/client/api/APIDocument.js index 25e8b6ac..2c1149bf 100644 --- a/src/client/api/APIDocument.js +++ b/src/client/api/APIDocument.js @@ -3,11 +3,11 @@ import EndPoint from './EndPoint'; export default class APIDocument extends EndPoint { documents(){ let url = '/documents/type/document'; - return this.request.get(url, {cache: true}); + return this.get(url); } awards() { let url = '/documents/type/award'; - return this.request.get(url, {cache: true}); + return this.get(url); } } \ No newline at end of file diff --git a/src/client/api/APIEvent.js b/src/client/api/APIEvent.js index 721cee85..f0ba7a28 100644 --- a/src/client/api/APIEvent.js +++ b/src/client/api/APIEvent.js @@ -3,11 +3,11 @@ import EndPoint from './EndPoint'; export default class APIEvent extends EndPoint { list(skip=1, limit=10) { let url = `/events?skip=${skip}&limit=${limit}`; - return this.request.get(url, {cache: true}); + return this.get(url); } post(id) { let url = `/event/${id}`; - return this.request.get(url, {cache: true}); + return this.get(url); } } \ No newline at end of file diff --git a/src/client/api/APIFeed.js b/src/client/api/APIFeed.js deleted file mode 100644 index 4e6d0ffe..00000000 --- a/src/client/api/APIFeed.js +++ /dev/null @@ -1,13 +0,0 @@ -/** - * Created by tmshv on 22/11/14. - */ - -import {query} from '../../utils/net'; -import EndPoint from './EndPoint'; - -export default class APIFeed extends EndPoint{ - feed(count, portion) { - let q = query([['count', count], ['portion', portion]]); - return this.request.get(`/news?${q}`); - } -} diff --git a/src/client/api/APIGallery.js b/src/client/api/APIGallery.js index e124cfe9..def3b32f 100644 --- a/src/client/api/APIGallery.js +++ b/src/client/api/APIGallery.js @@ -2,11 +2,11 @@ import EndPoint from './EndPoint'; export default class APIGallery extends EndPoint { year(year) { - return this.request.get(`/gallery/${year}`, {cache: true}); + return this.get(`/gallery/${year}`); } album(year, course, album, doPopulate) { let url = `/gallery/${year}/${course}/${album}?populate=${doPopulate}`; - return this.request.get(url, {cache: true}); + return this.get(url); } } diff --git a/src/client/api/APISchedule.js b/src/client/api/APISchedule.js index 5a8b3e56..3bc66cc2 100644 --- a/src/client/api/APISchedule.js +++ b/src/client/api/APISchedule.js @@ -1,17 +1,17 @@ import EndPoint from './EndPoint'; export default class APISchedule extends EndPoint { - get(period, semester, doPopulate=true) { - let url = `/schedule/${period}/${semester}?populate=${doPopulate}`; - return this.request.get(url, {cache: true}); + static buildScheduleUrl(period, semester) { + return `/schedule/${period}/${semester}`; } - buildScheduleUrl(period, semester) { - return `/schedule/${period}/${semester}`; + fetch(period, semester, doPopulate=true) { + let url = `/schedule/${period}/${semester}?populate=${doPopulate}`; + return this.get(url); } list() { let url = '/schedule/list'; - return this.request.get(url, {cache: true}); + return this.get(url); } } \ No newline at end of file diff --git a/src/client/api/APITeacher.js b/src/client/api/APITeacher.js new file mode 100644 index 00000000..74029681 --- /dev/null +++ b/src/client/api/APITeacher.js @@ -0,0 +1,14 @@ +import EndPoint from './EndPoint'; + +export default class APITeacher extends EndPoint { + list(sort=null) { + let url = '/teacher/list'; + if(sort) url = `/teacher/list?sort=${sort.join(',')}`; + return this.get(url); + } + + fetch(id) { + let url = `/teacher/${id}`; + return this.get(url); + } +} \ No newline at end of file diff --git a/src/client/api/APITimeline.js b/src/client/api/APITimeline.js new file mode 100644 index 00000000..b270d0b1 --- /dev/null +++ b/src/client/api/APITimeline.js @@ -0,0 +1,9 @@ +import {query} from '../../utils/net'; +import EndPoint from './EndPoint'; + +export default class APITimeline extends EndPoint{ + feed(limit=10, skip=0) { + let q = query([['limit', limit], ['skip', skip]]); + return this.get(`/news?${q}`); + } +} diff --git a/src/client/api/EndPoint.js b/src/client/api/EndPoint.js index 4e5b0b59..8984c513 100644 --- a/src/client/api/EndPoint.js +++ b/src/client/api/EndPoint.js @@ -2,4 +2,8 @@ export default class EndPoint{ constructor(http){ this.request = http; } + + get(url){ + return this.request.get(url, {cache: true}); + } } \ No newline at end of file diff --git a/src/client/app.js b/src/client/app.js index 7f10e14c..6d64a362 100644 --- a/src/client/app.js +++ b/src/client/app.js @@ -19,14 +19,17 @@ import ScheduleSlide from './components/ScheduleSlide'; import ScheduleRecord from './components/ScheduleRecord'; import FooterLinks from './components/FooterLinks'; import EventPost from './components/EventPost'; +import Album from './components/Album'; +import Parallax from './components/Parallax'; import PageSchool from './components/PageSchool'; import PageEvents from './components/PageEvents'; import PageEvent from './components/PageEvent'; import PageSchedule from './components/PageSchedule'; import PageCollective from './components/PageCollective'; +import PageTeacher from './components/PageTeacher'; import PageGallery from './components/PageGallery'; -import PageGalleryAlbum from './components/PageGalleryAlbum'; +import PageAlbum from './components/PageAlbum'; import PageDocuments from './components/PageDocuments'; import AppController from './controllers/AppController'; @@ -45,7 +48,7 @@ import IOService from './services/io'; import MenuService from './services/menu'; import API from './services/api'; -import {routes} from './config'; +import {collectiveSortPattern} from './config'; let app = angular.module('hudozka', [ 'ngRoute', @@ -58,9 +61,109 @@ app.config(($locationProvider, $routeProvider) => { $locationProvider.hashPrefix('!'); $locationProvider.html5Mode(true); - routes.forEach(route => { - if (typeof route === 'function') route = route(); - $routeProvider.when(route.name, route); + let routers = [ + { + name: '/', + template: '', + title: 'ДХШ Шлиссельбурга' + }, + { + name: '/events/:page?/:pageNumber?', + template: '', + title: 'События Школы', + + resolve: { + posts: api => api.event + .list() + .then(i => i.data) + } + }, + { + name: '/event/:event', + template: '' + }, + { + name: '/schedule/:period?/:semester?', + template: '', + title: 'Расписание', + resolve: { + list: api => api.schedule + .list() + .then(i => i.data) + } + }, + { + name: '/collective', + template: '', + title: 'Преподаватели', + resolve: { + list: api => api.teacher + .list(collectiveSortPattern) + .then(i => i.data) + } + }, + { + name: '/teacher/:id', + template: '', + title: 'Преподаватели', + resolve: { + profile: ($route, api) => { + let id = $route.current.params.id; + return api.teacher + .fetch(id) + .then(i => i.data); + } + } + }, + { + name: '/gallery', + template: '', + title: 'Работы учащихся', + resolve: { + list: api => api.album + .list() + .then(i => i.data) + } + }, + { + name: '/album/:id', + template: '', + resolve: { + album: ($route, api) => { + let id = $route.current.params.id; + + return api.album + .fetch(id) + .then(i => i.data) + } + } + }, + { + name: '/documents', + template: '', + title: 'Документы', + resolve: { + awards: api => api.document + .awards() + .then(i => i.data), + + documents: api => api.document + .documents() + .then(i => i.data) + } + } + ] + .map(i => { + let path = i.name; + delete i.name; + return { + path: path, + route: i + } + }); + + routers.forEach(i => { + $routeProvider.when(i.path, i.route); }); $routeProvider.otherwise({ @@ -96,6 +199,8 @@ app.run(($location, $rootScope, $http) => { TimelineRecordPost, TimelineRecordInstagram, EventPost, + Album, + Parallax, Document, Award, GalleryItem, @@ -106,8 +211,9 @@ app.run(($location, $rootScope, $http) => { PageEvents, PageSchedule, PageCollective, + PageTeacher, PageGallery, - PageGalleryAlbum, + PageAlbum, PageDocuments, AppController, CopyrightController, diff --git a/src/client/components/Album.js b/src/client/components/Album.js new file mode 100644 index 00000000..6be23280 --- /dev/null +++ b/src/client/components/Album.js @@ -0,0 +1,26 @@ +import template from '../../templates/components/album.html'; + +export class AlbumController { + constructor($sce) { + if(this.album){ + //this.post = $sce.trustAsHtml(this.album.post); + } + } +} + +export default function (app) { + app.component('album', { + bindings: { + //album: '<' + title: '@' + }, + transclude: true, + template: template, + controllerAs: '$', + //controller: function ($sce) { + // if(this.album){ + // this.post = $sce.trustAsHtml(this.album.post); + // } + //} + }); +}; \ No newline at end of file diff --git a/src/client/components/AlbumCollection.js b/src/client/components/AlbumCollection.js index c054a103..d32cf511 100644 --- a/src/client/components/AlbumCollection.js +++ b/src/client/components/AlbumCollection.js @@ -6,6 +6,7 @@ export default function (app) { title: '@', albums: '<' }, - template: template + template: template, + controllerAs: '$' }); }; \ No newline at end of file diff --git a/src/client/components/Award.js b/src/client/components/Award.js index d8add583..e7e5b571 100644 --- a/src/client/components/Award.js +++ b/src/client/components/Award.js @@ -3,8 +3,9 @@ import template from '../../templates/components/award.html'; export default function (app) { app.component('award', { bindings: { - document: '=' + document: '<' }, - template: template + template: template, + controllerAs: '$' }); }; \ No newline at end of file diff --git a/src/client/components/GalleryItem.js b/src/client/components/GalleryItem.js index 7e7b5fbe..0448b9df 100644 --- a/src/client/components/GalleryItem.js +++ b/src/client/components/GalleryItem.js @@ -3,8 +3,12 @@ import template from '../../templates/components/gallery-item.html'; export default function (app) { app.component('galleryItem', { bindings: { - record: '=' + record: '<' }, - template: template + template: template, + controllerAs: '$', + controller: function () { + this.previewImage = this.record.preview.url; + } }); }; \ No newline at end of file diff --git a/src/client/components/Navigation.js b/src/client/components/Navigation.js index 4d222284..7715fd78 100644 --- a/src/client/components/Navigation.js +++ b/src/client/components/Navigation.js @@ -5,6 +5,7 @@ export default function (app) { bindings: { menu: '<' }, - template: template + template: template, + controllerAs: '$' }); }; \ No newline at end of file diff --git a/src/client/components/PageAlbum.js b/src/client/components/PageAlbum.js new file mode 100644 index 00000000..b4906bf6 --- /dev/null +++ b/src/client/components/PageAlbum.js @@ -0,0 +1,31 @@ +import template from '../../templates/components/page-album.html'; + +export default function (app) { + app.component('pageAlbum', { + bindings: { + album: '<' + }, + template: template, + controllerAs: '$', + controller: function ($rootScope,$sce, menu) { + menu.activate('/gallery'); + + this.post = $sce.trustAsHtml(this.album.post); + + //this.crumbs = [ + // { + // url: '/gallery', + // name: 'Галерея' + // }, + // { + // name: 1010 + // }, + // { + // name: album.title + // } + //]; + + $rootScope.title = this.album.title; + } + }); +}; \ No newline at end of file diff --git a/src/client/components/PageCollective.js b/src/client/components/PageCollective.js index 494f153b..f30f5519 100644 --- a/src/client/components/PageCollective.js +++ b/src/client/components/PageCollective.js @@ -1,16 +1,16 @@ import template from '../../templates/components/page-collective.html'; -import {collectiveSortPattern} from '../config'; export default function (app) { app.component('pageCollective', { + bindings:{ + members: '<' + }, template: template, - controller: function(api) { - this.pageClass = 'page-collective'; - - api.collective.list(collectiveSortPattern) - .success(collective => { - this.members = collective; - }); + controller: function() { + //api.collective.list(collectiveSortPattern) + // .success(collective => { + // this.members = collective; + // }); //let rangelen = r => r[1] - r[0]; //let interpolate = (r, i) => (i - r[0]) / rangelen(r); diff --git a/src/client/components/PageDocuments.js b/src/client/components/PageDocuments.js index 6c38b926..ca1735c3 100644 --- a/src/client/components/PageDocuments.js +++ b/src/client/components/PageDocuments.js @@ -1,40 +1,37 @@ import template from '../../templates/components/page-documents.html'; - -let unique = fn => list => [...new Set(list.map(fn))]; +import {unique} from '../../utils/common'; export default function (app) { app.component('pageDocuments', { + bindings: { + awards: '<', + documents: '<' + }, template: template, - controller: function (api) { + controllerAs: '$', + controller: function () { this.pageClass = 'page-documents'; let categories = unique(i => i.category); this.collections = []; - api.document.documents() - .success(documents => { - let cats = categories(documents) - .map(cat => new Object({ - name: cat, - documents: [] - })); + let documents = this.documents; + let cats = categories(documents) + .map(cat => new Object({ + name: cat, + documents: [] + })); - let docCollections = documents.reduce( - (cats, doc) => { - let c = cats.find(i => i.name === doc.category); - c.documents.push(doc); - return cats; - }, - cats - ); + let docCollections = documents.reduce( + (cats, doc) => { + let c = cats.find(i => i.name === doc.category); + c.documents.push(doc); + return cats; + }, + cats + ); - this.collections = this.collections.concat(docCollections); - }); - - api.document.awards() - .success(data => { - this.awards = data; - }); + this.collections = this.collections.concat(docCollections); } }); }; \ No newline at end of file diff --git a/src/client/components/PageEvents.js b/src/client/components/PageEvents.js index 22303860..a68541c9 100644 --- a/src/client/components/PageEvents.js +++ b/src/client/components/PageEvents.js @@ -2,16 +2,19 @@ import template from '../../templates/components/page-events.html'; export default function (app) { app.component('pageEvents', { + bindings: { + events: '<' + }, template: template, controllerAs: '$', controller: function (api, menu) { this.pageClass = 'page-events'; menu.activate('/events'); - api.event.list() - .success(posts => { - this.posts = posts; - }); + //api.event.list() + // .success(posts => { + // this.posts = posts; + // }); } }); }; \ No newline at end of file diff --git a/src/client/components/PageGallery.js b/src/client/components/PageGallery.js index 97dc219d..316b24f3 100644 --- a/src/client/components/PageGallery.js +++ b/src/client/components/PageGallery.js @@ -1,27 +1,37 @@ import template from '../../templates/components/page-gallery.html'; +import {branch} from '../../utils/common'; export default function (app) { + let branchYears = branch( + i => 'date' in i ? i.date.getFullYear() : 'XXXX' + ); + app.component('pageGallery', { + bindings: { + albums: '<' + }, template: template, - controller: function (api) { + controllerAs: '$', + controller: function () { this.pageClass = 'page-gallery'; - this.years = []; - [2015, 2014, 2013, 2012, 2011, 2010] - .forEach((year, year_index) => { - api.gallery.year(year) - .success(albums => { - if (albums.length) { - this.years[year_index] = { - year: year, - albums: albums.map(album => { - let preview = album.content[0]; - album.preview_url = preview.content.medium.url; - return album; - }) - }; - } - }) + let years = branchYears( + this.albums + .map(i => { + i['date'] = new Date(i['date']); + return i; + }) + ); + + this.collections = Object + .keys(years) + .map(i => parseInt(i)) + .sort((a, b) => b - a) + .map(i => { + return { + title: i, + albums: years[i] + } }); } }); diff --git a/src/client/components/PageSchedule.js b/src/client/components/PageSchedule.js index d62663d3..07ea39e6 100644 --- a/src/client/components/PageSchedule.js +++ b/src/client/components/PageSchedule.js @@ -1,74 +1,62 @@ import template from '../../templates/components/page-schedule.html'; +import APISchedule from '../api/APISchedule'; import {populate} from '../../utils/populate'; import {getCourseNameByID} from '../../models/course'; import {indexEquals} from '../../utils/common'; import {select, choise} from '../../utils/common'; -function isRequested(period, semester) { - return function (schedule) { - return schedule.period === period && schedule.semester === semester; - } -} - export default function (app) { app.component('pageSchedule', { template: template, + bindings: { + //currentSchedule: '<', + schedules: '<' + }, controller: function($http, $location, $routeParams, api, menu) { this.pageClass = 'page-schedule'; menu.activate('/schedule'); - let current_period = $routeParams.period; - let current_semester = $routeParams.semester; - let isScheduleRequested = current_period && current_semester; + const period = $routeParams.period; + const semester = $routeParams.semester; + const useRoute = period && semester; - this.schedules = []; - let getScheduleByID = (id) => choise( - this.schedules, - select(i => i._id === id) - ); - - api.schedule.list() - .success(schedules => { - // By url params or last element - let selector = isScheduleRequested ? isRequested(current_period, current_semester) : indexEquals(schedules.length - 1); - - schedules = schedules.map(schedule => { - let sem = [['spring', 'Весна'], ['autumn', 'Осень']] - .reduce(select( - i => i[0] === schedule.semester, - i => i[1] - )); - schedule.text = `${sem} ${schedule.period} года`; - - return schedule; - }); - - schedules.forEach((schedule, i) => { - if (selector(schedule, i)) { - this.currentSchedule = schedules[i]; - } - }); - - this.schedules = schedules; - this.loadSchedule(this.currentSchedule, isScheduleRequested); - }); - - this.loadSchedule = (s, doUpdateURL) => { - let id = s._id; - let schedule_item = getScheduleByID(id); - - if (schedule_item) { - let sem = schedule_item.semester; - let period = schedule_item.period; - - api.schedule.get(period, sem, true) - .success(scheduleRecord => { - this.schedule = scheduleRecord.schedule; - - if (doUpdateURL) $location.url(api.schedule.buildScheduleUrl(period, sem)); + this.loadSchedule = (record, doUpdateURL) => { + let id = record._id; + let scheduleItem = getScheduleByID(id); + if (scheduleItem) { + let p = scheduleItem.period; + let s = scheduleItem.semester; + api.schedule.fetch(p, s, true) + .then(i => i.data) + .then(i => { + this.schedule = i.schedule; + if (doUpdateURL) $location.url(APISchedule.buildScheduleUrl(p, s)); }); } }; + + let getScheduleByID = id => this.schedules + .find(i => i._id === id); + + let getRoutedSchedule = list => { + return list.find(i => i.period === period && i.semester === semester) + }; + + let last = list => list.length ? list[list.length - 1] : null; + let getDefaultSchedule = list => last(list); + + let word = semester => [['spring', 'Весна'], ['autumn', 'Осень']] + .find(i => i[0] === semester) + [1]; + + this.schedules.forEach(i => { + let periodIndex = i.semester === 'spring' ? 1 : 0; + let year = i.period.split('-')[periodIndex]; + i.text = `${word(i.semester)} ${year} года`; + }); + this.currentSchedule = useRoute ? getRoutedSchedule(this.schedules) : getDefaultSchedule(this.schedules); + + this.loadSchedule(this.currentSchedule, useRoute); } }); }; \ No newline at end of file diff --git a/src/client/components/PageSchool.js b/src/client/components/PageSchool.js index f9a48e54..e4a2f3d8 100644 --- a/src/client/components/PageSchool.js +++ b/src/client/components/PageSchool.js @@ -1,10 +1,19 @@ import template from '../../templates/components/page-school.html'; +import {mobileMatchSelector} from '../config'; export default function (app) { app.component('pageSchool', { template: template, + controllerAs: '$', controller: function() { - this.pageClass = 'page-school'; + this.helloBlock = 'parallax'; + + try { + if (window.matchMedia(mobileMatchSelector).matches) { + this.helloBlock = 'mobile-image'; + } + } catch (e) { + } //let fotorama; //let $tape = $('.tape-block'); diff --git a/src/client/components/PageTeacher.js b/src/client/components/PageTeacher.js new file mode 100644 index 00000000..5c36fbee --- /dev/null +++ b/src/client/components/PageTeacher.js @@ -0,0 +1,14 @@ +import template from '../../templates/components/page-teacher.html'; + +export default function (app) { + app.component('pageTeacher', { + bindings:{ + member: '<' + }, + template: template, + controllerAs: '$', + controller: function(menu){ + menu.activate('/collective'); + } + }); +}; \ No newline at end of file diff --git a/src/client/components/Parallax.js b/src/client/components/Parallax.js new file mode 100644 index 00000000..b5d66f26 --- /dev/null +++ b/src/client/components/Parallax.js @@ -0,0 +1,82 @@ +import template from '../../templates/components/parallax.html' + +export default function (app) { + app.directive('parallax', function () { + return { + restrict: 'E', + template: template, + controllerAs: '$', + link: function (scope, element) { + let map_range = (i, low1, high1, low2, high2) => low2 + (high2 - low2) * (i - low1) / (high1 - low1); + + scope.layers = [ + {x: 0, y: 0, s: 0, url: 'https://static.shlisselburg.org/art/graphics/main/11.jpg'}, + //{x: 716, y: 127, s: -0.4, url: 'https://static.shlisselburg.org/art/graphics/main/10.png'}, + //{x: 0, y: 216, s: -0.3, url: 'https://static.shlisselburg.org/art/graphics/main/9.png'}, + + {x: 0, y: 450, s: -0.2, url: 'https://static.shlisselburg.org/art/graphics/main/8.png'}, + {x: 683, y: 378, s: -0.25, url: 'https://static.shlisselburg.org/art/graphics/main/7.png'}, + {x: 0, y: 522, s: -0.3, url: 'https://static.shlisselburg.org/art/graphics/main/6.png'}, + {x: 414, y: 585, s: -0.4, url: 'https://static.shlisselburg.org/art/graphics/main/5.png'}, + {x: 0, y: 213, s: -.5, url: 'https://static.shlisselburg.org/art/graphics/main/4.png'}, + {x: 206, y: 667, s: -.6, url: 'https://static.shlisselburg.org/art/graphics/main/3.png'}, + {x: 556, y: 506, s: -0.7, url: 'https://static.shlisselburg.org/art/graphics/main/2.png'}, + {x: 0, y: 914, s: -0.7, url: 'https://static.shlisselburg.org/art/graphics/main/1.png'}, + + {x: 13, y: 88, s: 0, url: 'https://static.shlisselburg.org/art/graphics/main/title.png'} + ]; + + function mapper(range1, range2, fit) { + let [r1, r2] = range1; + let [d1, d2] = range2; + + let constrain = value => { + var min = Math.min(d1, d2); + var max = Math.max(d1, d2); + return Math.min(max, Math.max(min, value)); + }; + + return value => fit ? + constrain(map_range(value, r1, r2, d1, d2)) + : + map_range(value, r1, r2, d1, d2) + } + + let hm = mapper([0, 900], [0, 900], true); + let em = mapper([340, 900], [0, 400], true); + //let pm = mapper([0, 1000], [1000, 900], true); + + function updateHead(value) { + //console.log(value); + + let v = hm(value); + //let v = value; + + try { + [...document.querySelectorAll('.parallax .parallax__layer')] + .forEach((e, i) => { + let layer = scope.layers[i]; + e.style.top = `${layer.y + v * layer.s}px`; + }); + + let end = document.querySelector('.parallax .parallax__end'); + end.style.height = `${em(value)}px`; + + //let container = document.querySelector('.parallax'); + //container.style.height = '1000px'; + //container.style.height = `${pm(value)}px`; + + } catch (error) { + console.log(error); + } + } + + updateHead(0); + $(window).scroll(() => { + updateHead($(window).scrollTop()) + }); + } + }; + } + ); +} diff --git a/src/client/components/Schedule.js b/src/client/components/Schedule.js index e014df3e..c396f830 100644 --- a/src/client/components/Schedule.js +++ b/src/client/components/Schedule.js @@ -1,4 +1,5 @@ import template from '../../templates/components/schedule.html'; +import {mobileMatchSelector} from '../config'; export default function(app) { app.component('schedule', { @@ -10,11 +11,11 @@ export default function(app) { this.type = 'table'; try { - if (window.matchMedia('(max-device-width: 30em)').matches) { + if (window.matchMedia(mobileMatchSelector).matches) { this.type = 'slider'; } } catch (e) { } } }); -}; \ No newline at end of file +}; diff --git a/src/client/components/ScheduleSlider.js b/src/client/components/ScheduleSlider.js index 6503acda..6447cf18 100644 --- a/src/client/components/ScheduleSlider.js +++ b/src/client/components/ScheduleSlider.js @@ -13,9 +13,9 @@ function week(schedule) { date: dates[i], groups: schedule.map(group => { return { - name: group.name, + name: group.group, time: group.time, - content: group.days[i] + content: group.week[i] } }) } diff --git a/src/client/components/TeacherProfile.js b/src/client/components/TeacherProfile.js index 9d5f2bc5..172c4928 100644 --- a/src/client/components/TeacherProfile.js +++ b/src/client/components/TeacherProfile.js @@ -1,23 +1,29 @@ import {splitName} from '../../models/collective'; +import {stringToBoolean} from '../../utils/string'; import template from '../../templates/components/teacher-profile.html'; export default function (app) { app.component('teacherProfile', { bindings: { - member: '=' + profile: '<', + showUrl: '@' }, template: template, + controllerAs: '$', controller: function($sce){ - const [_, first, middle, last] = splitName(this.member.name); + this.url = this.showUrl === 'true'; + //this.showUrl = stringToBoolean(this.showUrl); + + const [_, first, middle, last] = splitName(this.profile.name); this.firstName = first; this.middleName = middle; this.lastName = last; - if(this.member.picture){ - this.image = this.member.picture.big; + if (this.profile.picture) { + this.image = this.profile.picture.data.big; } - this.biography = $sce.trustAsHtml(this.member.biography); + this.biography = $sce.trustAsHtml(this.profile.biography); } }); }; diff --git a/src/client/components/Timeline.js b/src/client/components/Timeline.js index 562a6016..8ba0c507 100644 --- a/src/client/components/Timeline.js +++ b/src/client/components/Timeline.js @@ -28,8 +28,8 @@ export default function(app) { app.component('timeline', { template: template, controller: function($timeout, usSpinnerService, io, api){ - let portion = 0; - let count = 10; + let skip = 0; + let limit = 10; this.feed = []; this.timelineUpdating = false; @@ -59,7 +59,7 @@ export default function(app) { this.timelineUpdating = true; usSpinnerService.spin('timelineMore'); - api.news.feed(count, portion) + api.timeline.feed(limit, skip) .error(error => { console.log(error); }) @@ -72,7 +72,7 @@ export default function(app) { else return post; }); - portion++; + skip++; this.feed = this.feed.concat(feed2); }); }; diff --git a/src/client/components/TimelineRecordPost.js b/src/client/components/TimelineRecordPost.js index fd7bee0d..0fdb36f5 100644 --- a/src/client/components/TimelineRecordPost.js +++ b/src/client/components/TimelineRecordPost.js @@ -7,7 +7,7 @@ export default function (app) { }, template: template, controller: function($sce){ - this.message = $sce.trustAsHtml(this.post.body); + this.message = $sce.trustAsHtml(this.post.message); } }); }; \ No newline at end of file diff --git a/src/client/config.js b/src/client/config.js index ba014eec..3ca08a83 100644 --- a/src/client/config.js +++ b/src/client/config.js @@ -2,6 +2,8 @@ import {stringReplace} from '../utils/string'; const nbsp = 0xA0; +export const mobileMatchSelector = '(max-device-width: 30em)'; + export let contacts = { telephone: '+7 (81362) 76-312', email: 'hudozka@gmail.com', @@ -19,47 +21,6 @@ export let collectiveSortPattern = [ 'nv-andreeva' ]; -export let routes = [ - { - name: '/', - template: '', - title: 'ДХШ Шлиссельбурга' - }, - { - name: '/events/:page?/:pageNumber?', - template: '', - title: 'События Школы' - }, - { - name: '/event/:event', - template: '' - }, - { - name: '/schedule/:period?/:semester?', - template: '', - title: 'Расписание' - }, - { - name: '/collective', - template: '', - title: 'Преподаватели' - }, - { - name: '/gallery', - template: '', - title: 'Работы учащихся' - }, - { - name: '/gallery/:year/:course/:album', - template: '' - }, - { - name: '/documents', - template: '', - title: 'Документы' - } -]; - export const footer = { links: { docs: { diff --git a/src/client/controllers/AppController.js b/src/client/controllers/AppController.js index e96d886a..1ca01187 100644 --- a/src/client/controllers/AppController.js +++ b/src/client/controllers/AppController.js @@ -1,7 +1,17 @@ -import {footer} from '../config'; +import {footer, mobileMatchSelector} from '../config'; export default function (app) { app.controller('AppController', ($scope, menu) => { + try { + if (window.matchMedia(mobileMatchSelector).matches) { + $scope.navigation = 'navigation'; + }else{ + $scope.navigation = 'main-menu'; + } + } catch (e) { + $scope.navigation = 'main-menu'; + } + $scope.menuProvider = menu.items; $scope.footer = footer; }); diff --git a/src/core/schedule.js b/src/core/schedule.js index 959510d2..9bad62c9 100644 --- a/src/core/schedule.js +++ b/src/core/schedule.js @@ -1,7 +1,8 @@ +import co from 'co'; import {c} from '../core/db'; import {getCollective} from './collective'; -import {populate} from '../models/schedule'; +import {populate, scheduleDate} from '../models/schedule'; import {shortifyName} from '../models/collective'; import {courses} from '../models/course'; @@ -15,9 +16,16 @@ export function* getSchedule(period, semester) { } export function* getScheduleList() { - return yield c('schedules') + let list = yield c('schedules') .find({}, {period: 1, semester: 1}) .toArray(); + return list + .sort((a, b) => { + let ad = scheduleDate(a); + let bd = scheduleDate(b); + + return ad.getTime() - bd.getTime(); + }); } export function* populateSchedule(schedule) { @@ -30,11 +38,11 @@ export function* populateSchedule(schedule) { let populateLesson = populate(courses); let populateTeacher = populate(collective_dict, i => shortifyName(i)); - return schedule.map(group => { + return schedule.map(i => { return { - name: group.name, - time: group.time, - days: group.days.map(record => { + group: i.group, + time: i.time, + week: i.week.map(record => { if (!record) return record; let lesson = record.lesson; @@ -44,7 +52,11 @@ export function* populateSchedule(schedule) { return { time: time, lesson: populateLesson(lesson), - teacher: populateTeacher(teacher) + teacher: { + id: teacher, + url: `/teacher/${teacher}`, + name: populateTeacher(teacher) + } }; }) }; diff --git a/src/instagram/publish.js b/src/instagram/publish.js index 7545e1e0..c9a5f0cb 100644 --- a/src/instagram/publish.js +++ b/src/instagram/publish.js @@ -27,7 +27,7 @@ function Publisher() { return uploadInstagrams(posts) .then(function () { - return db.c("posts").find({"data.id": {$in: ids}}).toArray(); + return db.c("timeline").find({"data.id": {$in: ids}}).toArray(); }); }) .then(function (posts) { @@ -91,7 +91,7 @@ function findInstagrams(tag){ function uploadInstagrams(list){ return Promise.all( list.map(function (g) { - return db.c("posts").update({"data.id": g.data.id}, g, {upsert: true}); + return db.c("timeline").update({"data.id": g.data.id}, g, {upsert: true}); }) ); } \ No newline at end of file diff --git a/src/models/schedule.js b/src/models/schedule.js index 57b181df..0e2f919d 100644 --- a/src/models/schedule.js +++ b/src/models/schedule.js @@ -1,5 +1,24 @@ let tryReplace = (dict, record, map = i=>i) => record in dict ? map(dict[record]) : record; +export const autumnMonth = 8; +export const springMonth = 0; + + export const populate = (dict, map) => - id => tryReplace(dict, id, map); \ No newline at end of file + id => tryReplace(dict, id, map); + +export function scheduleDate(schedule){ + let {period, semester} = schedule; + + let i = semester === 'spring' ? 1 : 0; + let year = parseInt( + period.split('-')[i] + ); + + return new Date( + year, + i ? springMonth : autumnMonth , + 1 + ); +} diff --git a/src/routes/documents.js b/src/routes/documents.js index d3a69f1b..b85335c4 100644 --- a/src/routes/documents.js +++ b/src/routes/documents.js @@ -19,7 +19,7 @@ export default function (app) { function *(type) { let types = { 'document': ['documents', {type: 'document'}, populateDocPreview], - 'award': ['awards', {}] + 'award': ['awards', {}, populateDocPreview] }; if (type in types) { diff --git a/src/routes/events.js b/src/routes/events.js index bc090831..87cdb364 100644 --- a/src/routes/events.js +++ b/src/routes/events.js @@ -1,14 +1,23 @@ import route from 'koa-route'; import {c} from '../core/db'; import {json} from './'; +import {sortBy} from '../utils/sort'; export default function (app) { + let sortByDate = sortBy( + i => (new Date(i.date)) + .getTime() + ); + app.use(route.get('/events', json( function *() { let query = {}; - this.body = yield c('events') + let events = yield c('events') .find(query) .toArray(); + + this.body = events + .sort(sortByDate); } ))); diff --git a/src/routes/gallery.js b/src/routes/gallery.js index 78a659c6..261ee6d6 100644 --- a/src/routes/gallery.js +++ b/src/routes/gallery.js @@ -6,47 +6,62 @@ import {json} from './'; export default function (app) { app.use(route.get('/gallery', json( function *() { - var query = {}; - var albums = yield c('albums') - .find(query) - .toArray(); + let query = {}; + let fields = ['_id', 'id', 'title', 'date']; + //.reduce((f, i) => { + // f[i] = 1; + // return f; + //}, {}); - albums = yield albums.map(processAlbum); - this.body = albums; - } - ))); - - app.use(route.get('/gallery/:year', json( - function *(year) { - year = parseInt(year); - let start = new Date(year, 0, 1); - let end = new Date(year, 11, 31); - let query = { - date: {$gte: start, $lt: end} - }; let albums = yield c('albums') .find(query) .toArray(); + //albums = albums.map(i => { + // return fields.reduce((a, key)=> { + // a[key] = i[key]; + // return a; + // }, {}); + //}); + albums = yield albums.map(processAlbum); this.body = albums; } ))); - app.use(route.get('/gallery/:year/:course/:album', json( - function *(year, course, album) { - year = parseInt(year); - course = '/' + course; - album = '/' + album; - let start = new Date(year, 0, 1); - let end = new Date(year, 11, 31); - let query = { - date: {$gte: start, $lt: end}, - course_uri: course, - uri: album - }; + //app.use(route.get('/gallery/:year', json( + // function *(year) { + // year = parseInt(year); + // let start = new Date(year, 0, 1); + // let end = new Date(year, 11, 31); + // let query = { + // date: {$gte: start, $lt: end} + // }; + // let albums = yield c('albums') + // .find(query) + // .toArray(); + // + // albums = yield albums.map(processAlbum); + // this.body = albums; + // } + //))); - let record = yield c('albums').findOne(query); + app.use(route.get('/album/:id', json( + function *(id) { + //year = parseInt(year); + //course = '/' + course; + //album = '/' + album; + //let start = new Date(year, 0, 1); + //let end = new Date(year, 11, 31); + //let query = { + // date: {$gte: start, $lt: end}, + // course_uri: course, + // uri: album + //}; + + let record = yield c('albums').findOne({ + id: id + }); record = yield processAlbum(record); this.body = record; } @@ -54,19 +69,24 @@ export default function (app) { }; let processAlbum = album => co(function *() { - album.url = `/gallery/{year}{course}{album}` - .replace('{year}', album.date.getFullYear()) - .replace('{course}', album.course_uri) - .replace('{album}', album.uri); + //album.url = `/gallery/{year}{course}{album}` + // .replace('{year}', album.date.getFullYear()) + // .replace('{course}', album.course_uri) + // .replace('{album}', album.uri); + album.url = `/album/${album.id}`; - album.content = yield album.content.map(product_id => co(function *() { - let product = yield c('products').findOne({_id: product_id}); - if (product) return product; - else return null; - })); + //album.content = yield album.content.map(product_id => co(function *() { + // let product = yield c('products').findOne({_id: product_id}); + // if (product) return product; + // else return null; + //})); - let teacher = yield c('collective').findOne({id: album.teacher}); - album.teacher = teacher.name; + //let teacher = yield c('collective').findOne({id: album.teacher}); + //album.teacher = teacher.name; + + let previewImageId = album.images[0]; + let image = yield c('images').findOne({_id: previewImageId}); + album.preview = image.data.medium; return album; }); \ No newline at end of file diff --git a/src/routes/index.js b/src/routes/index.js index b19781ed..f0b92d25 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -2,14 +2,9 @@ import path from 'path'; import fs from 'mz/fs'; import config from '../config'; -export function queryObject(){ - let assign = (dict, key, value) => { - dict[key] = value; - return dict; - }; - let map = (v, fn) => - value => fn(value) ? v : value; +import {map, assign} from '../utils/common'; +export function queryObject() { let toTrue = map(true, i => i === 'true'); let toFalse = map(false, i => i === 'false'); const processors = [toTrue, toFalse]; diff --git a/src/routes/news.js b/src/routes/news.js index df0f1f4c..d5cd879b 100644 --- a/src/routes/news.js +++ b/src/routes/news.js @@ -1,78 +1,75 @@ -/** - * Created by tmshv on 22/11/14. - */ +import route from 'koa-route'; +import {accepts, index} from './'; +import {c} from '../core/db'; +import {sortBy} from '../utils/sort'; -var route = require("koa-route"); -var router = require("./"); -var db = require("../core/db"); +export default function (app) { + let sortNewsByDate = sortBy( + i => (new Date(i.date)) + .getTime() + ); -module.exports = function (app) { - app.use(route.get("/news", router.accepts({ - "text/html": function *() { - this.redirect("/"); + app.use(route.get('/news', accepts({ + 'text/html': function *() { + this.redirect('/'); }, - "text/plain": function *() { - this.redirect("/"); + 'text/plain': function *() { + this.redirect('/'); }, - "application/json": function *() { - var count = parseInt(this.query["count"]) || 10; - var portion = parseInt(this.query["portion"]) || 0; - var skip = portion * count; + 'application/json': function *() { + let limit = parseInt(this.query['limit']) || 10; + let skip = parseInt(this.query['skip']) || 0; - var query = {}; + let query = {}; if (this.query.type) query.type = this.query.type; - var pinned = []; - if(portion == 0) { - var now = new Date(); - pinned = yield db.c("posts").find({until: {$gte: now}}).toArray() - .then(function (items) { - return items.sort(sortNewsByDate); - }); + let pinned = []; + if(skip == 0) { + const now = new Date(); + pinned = yield c('timeline') + .find({until: {$gte: now}}) + .toArray() + .then(i => i.sort(sortNewsByDate)); } - var pinned_ids = pinned.map(function (p) { - return p["_id"]+""; - }); - var posts = yield db.c("posts").find(query) + let sid = id => id + ''; + let pinnedIds = pinned.map(p => sid(p['_id'])); + + let posts = yield c('timeline') + .find(query) .sort({date: -1}) .skip(skip) - .limit(count) + .limit(limit) .toArray() - .then(function (items) { - return items.filter(function (i) { - var id = i["_id"]+""; - return pinned_ids.indexOf(id) < 0; - }); - }); + .then(items => items.filter( + i => pinnedIds.indexOf(sid(i['_id'])) < 0 + )); this.body = pinned.concat(posts); - //this.body = pinned_ids } }))); - app.use(route.get("/news/pinned", router.accepts({ - "text/html": function *() { - this.redirect("/"); + app.use(route.get('/news/pinned', accepts({ + 'text/html': function *() { + this.redirect('/'); }, - "text/plain": function *() { - this.redirect("/"); + 'text/plain': function *() { + this.redirect('/'); }, - "application/json": function *() { - var now = new Date(); - var pinned = yield db.c("posts").find({until: {$gte: now}}).toArray() - .then(function (items) { - return items.sort(sortNewsByDate); - }); - this.body = pinned; + 'application/json': function *() { + let now = new Date(); + this.body = yield c('timeline') + .find({until: {$gte: now}}) + .toArray() + .then(i => i.sort(sortNewsByDate)); } }))); - app.use(route.get("/news/:uri", router.accepts({ - "text/html": router.index(), - "text/plain": router.index(), - "application/json": function *(uri) { - var item = yield db.c("posts").findOne({uri: uri}); + app.use(route.get('/news/:id', accepts({ + 'text/html': index(), + 'text/plain': index(), + 'application/json': function *(id) { + let item = yield c('timeline').findOne({uri: id}); if (item) { this.body = item; } else { @@ -81,12 +78,3 @@ module.exports = function (app) { } }))); }; - -function sortNewsByDate(i1, i2) { - var t1 = new Date(i1.date).getTime(); - var t2 = new Date(i2.date).getTime(); - - if (t1 < t2) return 1; - if (t1 > t2) return -1; - return 0; -} \ No newline at end of file diff --git a/src/routes/teachers.js b/src/routes/teachers.js new file mode 100644 index 00000000..97668a3f --- /dev/null +++ b/src/routes/teachers.js @@ -0,0 +1,51 @@ +import co from 'co'; +import route from 'koa-route'; +import {index, json} from './'; +import {sortByPattern} from '../utils/sort'; +import {c} from '../core/db'; + +let split = d => s => s.split(d); +let toArray = split(','); + +export default function (app) { + app.use(route.get('/collective', index())); + + app.use(route.get('/teacher/list', json( + function *() { + this.type = 'application/json'; + let pattern = toArray(this.query.sort || ''); + + let data = yield c('collective').find(); + if (!data) { + this.status = 404; + return; + } + + let collective = yield data + .map(processProfile); + + this.body = sortByPattern(collective, pattern, i => i.id); + } + ))); + + app.use(route.get('/teacher/:id', json( + function *(id) { + this.type = 'application/json'; + + let data = yield c('collective').findOne({id: id}); + if (!data) { + this.status = 404; + return; + } + + this.body = yield processProfile(data); + } + ))) +}; + +let processProfile = profile => co(function *() { + let imageId = profile.picture; + profile.picture = yield c('images').findOne({_id: imageId}); + profile.url = `/teacher/${profile.id}`; + return profile; +}); \ No newline at end of file diff --git a/src/server.js b/src/server.js index d70277eb..d442cfa2 100644 --- a/src/server.js +++ b/src/server.js @@ -22,7 +22,7 @@ import instagram from './instagram/router'; import instagramIO from './instagram/io'; import error404 from './routes/404'; import documents from './routes/documents'; -import collective from './routes/collective'; +import teachers from './routes/teachers'; import events from './routes/events'; export const app = koa(); @@ -58,5 +58,5 @@ instagram(app); instagramIO(app); documents(app); events(app); -app.use(collective()); +teachers(app); app.use(error404()); \ No newline at end of file diff --git a/src/style/album.scss b/src/style/album.scss index e1c543f5..93368807 100644 --- a/src/style/album.scss +++ b/src/style/album.scss @@ -1,26 +1,13 @@ @import "variables"; .album-block { - width: 100%; - margin: 1em auto 2em; + //margin: 1em auto 2em; h3 { text-align: center; margin: 1.5em 0 1em; } - .fotorama__nav-wrap { - margin: 6em 0 0; - } - - .fotorama__stage{ - overflow: inherit; - } - - .fotorama__stage__frame{ - overflow: inherit; - } - .album { display: flex; flex-direction: row; diff --git a/src/style/body-wrapper.scss b/src/style/body-wrapper.scss index 6d6791ef..9e1bcacf 100644 --- a/src/style/body-wrapper.scss +++ b/src/style/body-wrapper.scss @@ -5,5 +5,11 @@ } .body-wrapper__content { - margin: $menu-thickness auto 0; + margin: 0 auto 0; +} + +@media (max-width: $mobile-width) { + .body-wrapper__content { + margin: $menu-thickness auto 0; + } } diff --git a/src/style/components/album-collection.scss b/src/style/components/album-collection.scss index 65dbf9c0..92321171 100644 --- a/src/style/components/album-collection.scss +++ b/src/style/components/album-collection.scss @@ -5,7 +5,8 @@ display: flex; flex-wrap: wrap; position: relative; - align-items:flex-end; + justify-content: center; + align-items:flex-start; } &__title{ diff --git a/src/style/components/album.scss b/src/style/components/album.scss new file mode 100644 index 00000000..fc4313c9 --- /dev/null +++ b/src/style/components/album.scss @@ -0,0 +1,48 @@ +@import "../variables"; + +.album { + margin-bottom: $double-margin; + + &__head { + margin-bottom: 1.25em; + + h3 { + font-size: $big-font-size; + text-align: center; + } + + .date { + text-align: center; + color: #aaa; + } + + a { + color: $dark-color; + border-bottom: none; + } + } + + &__body{ + img { + max-width: 100%; + max-height: 40em; + + display: block; + margin: 1.25em auto $small-margin; + } + + p{ + margin-bottom: 1.25em; + } + } +} + +@media (max-width: $mobile-width) { + .album { + &__body { + img { + max-height: 20em; + } + } + } +} \ No newline at end of file diff --git a/src/style/components/document.scss b/src/style/components/document.scss index 18b26d1a..4b3d145d 100644 --- a/src/style/components/document.scss +++ b/src/style/components/document.scss @@ -23,6 +23,6 @@ @media (max-width: $mobile-width) { .document { - margin: 0 0 $single-margin; + margin: 0 $single-margin/2 $single-margin; } } diff --git a/src/style/documents.scss b/src/style/components/documents-container.scss similarity index 54% rename from src/style/documents.scss rename to src/style/components/documents-container.scss index 2b319cfb..42d1ac73 100644 --- a/src/style/documents.scss +++ b/src/style/components/documents-container.scss @@ -1,3 +1,5 @@ +@import "../variables"; + .documents-container { display: flex; flex-wrap: wrap; @@ -5,8 +7,7 @@ align-items: baseline; } -@media (max-width: 31.25em) { - .documents-block { - margin: 1em 0 0; +@media (max-width: $mobile-width) { + .documents-container { } } diff --git a/src/style/components/event-post.scss b/src/style/components/event-post.scss index f7499114..43d1ff31 100644 --- a/src/style/components/event-post.scss +++ b/src/style/components/event-post.scss @@ -4,10 +4,10 @@ margin-bottom: $double-margin; &__head { - margin-bottom: $small-margin; + margin-bottom: 1.25em; h3 { - font-size: 1.75em; + font-size: $big-font-size; text-align: center; } @@ -25,9 +25,27 @@ &__body{ img { max-width: 100%; - max-height: 100%; + //max-height: 100%; + + max-height: 40em; + display: block; - margin: 0 auto $small-margin; + margin: 1.25em auto $small-margin; + } + + p { + margin-bottom: 1.25em; } } } + +@media (max-width: $mobile-width) { + .event-post { + + &__body { + img { + max-height: 20em; + } + } + } +} \ No newline at end of file diff --git a/src/style/components/gallery-item.scss b/src/style/components/gallery-item.scss index 7986e682..4ab57ff9 100644 --- a/src/style/components/gallery-item.scss +++ b/src/style/components/gallery-item.scss @@ -4,20 +4,35 @@ $img-max-width: 500px; $double-margin-half: $double-margin / 2; $percentage: 25%; -gallery-item { - width: $percentage; - padding: 0 $double-margin-half; +.gallery-item { box-sizing: padding-box; + padding: 0; - margin-bottom: $single-margin; + width: 13em; + height: 15em; + margin: 0 $single-margin $double-margin; - img{ + h3 { + text-align: center; + } + + a { + color: $dark-color; + border-bottom: none; + + &:hover { + border-bottom: none; + color: $blue-color; + } + } + + img { width: 100%; } } @media screen and (max-width: $mobile-width) { .gallery-item { - margin: 0 0 1em; + margin: 0 0 $double-margin; } } diff --git a/src/style/components/main-menu.scss b/src/style/components/main-menu.scss index 7af95495..48b756c7 100644 --- a/src/style/components/main-menu.scss +++ b/src/style/components/main-menu.scss @@ -9,7 +9,7 @@ position: fixed; top: 0; white-space: nowrap; - background-color: $darker-color; + background-color: rgba(255, 255, 255, 0.95); font-size: 1.1em; color: $menu-inactive-item-color; @@ -29,13 +29,15 @@ a { text-decoration: none; - color: $light-color; - border-bottom: 1px solid darken($light-color, 50%); + color: $dark-color; + //border-bottom: 1px solid darken($light-color, 50%); + border-bottom: 1px solid lighten($dark-color, 60%); - &:hover { - color: $lighter-color; - border-bottom: 1px solid darken($lighter-color, 50%); - } + //&:hover { + // color: $dark-color; + // + // border-bottom: 1px solid darken($lighter-color, 50%); + //} } .selected { @@ -43,7 +45,7 @@ border-top: $menu-colored-mark-thickness solid $light-color; a:link, a:visited { - color: $lighter-color; + color: $dark-color; text-decoration: none; border-bottom: none; } @@ -74,8 +76,12 @@ } } -@media (min-width: $mobile-width) { +@media (max-width: $mobile-width) { header{ overflow: hidden; } + + .main-menu{ + background-color: white; + } } diff --git a/src/style/components/navigation.scss b/src/style/components/navigation.scss index 2e83967d..5dec4f3f 100644 --- a/src/style/components/navigation.scss +++ b/src/style/components/navigation.scss @@ -19,20 +19,28 @@ .navigation__right { color: $light-color; margin-right: 3em; + + z-index:1000; } @media (max-width: $mobile-width) { .navigation { overflow: hidden; - display: flex; - justify-content: flex-start; - align-items: center; + width: 100%; + z-index: 100; + position: relative; + top: 0; + + display: block; + //display: flex; + //justify-content: flex-start; + //align-items: center; } .navigation__right { //display: none; - margin-right: 0; + //margin-right: 0; } } diff --git a/src/style/components/page-collective.scss b/src/style/components/page-collective.scss index 4be26ed2..d4d28d72 100644 --- a/src/style/components/page-collective.scss +++ b/src/style/components/page-collective.scss @@ -8,4 +8,18 @@ &.ng-enter { animation: slideInRight $short-duration both ease-in; } +} + +.page-collective { + &__collective-image { + min-height: 40em; + } +} + +@media (max-width: $mobile-width) { + .page-collective { + &__collective-image { + display: none; + } + } } \ No newline at end of file diff --git a/src/style/components/page-school.scss b/src/style/components/page-school.scss index b4ae43af..6e4dac32 100644 --- a/src/style/components/page-school.scss +++ b/src/style/components/page-school.scss @@ -9,4 +9,31 @@ &.ng-enter { animation: scaleUp $short-duration both ease-in; } -} \ No newline at end of file + +} + +.hudozka-title { + padding: $double-margin 0; + + text-align: center; + + p { + color: $light-color; + margin-bottom: $single-margin; + } + + h1 { + margin-top: $single-margin; + font-size: 1.5em; + } +} + +@media (min-width: $mobile-width) { + .hudozka-title { + text-align: center; + + h1 { + font-size: 1em; + } + } +} diff --git a/src/style/components/parallax.scss b/src/style/components/parallax.scss new file mode 100644 index 00000000..189b1828 --- /dev/null +++ b/src/style/components/parallax.scss @@ -0,0 +1,19 @@ +@import "../variables"; + +.parallax { + height: 1000px; + position: relative; + + overflow: hidden; + + &__layer { + position: absolute; + } + + &__end { + position: absolute; + width: 100%; + background-color: white; + bottom: 0; + } +} \ No newline at end of file diff --git a/src/style/components/teacher-proifile.scss b/src/style/components/teacher-proifile.scss index 209ca636..ca119bb5 100644 --- a/src/style/components/teacher-proifile.scss +++ b/src/style/components/teacher-proifile.scss @@ -27,25 +27,34 @@ $info-width: 100% - $picture-width; box-sizing: border-box; h3 { + font-size: $big-font-size; font-weight: 200; strong { font-weight: 600; } - } - .info { - margin-bottom: $single-margin; - } + a { + color: $dark-color; - .biography { - margin-top: $single-margin; - - p{ - margin-bottom: $single-margin; + &:hover{ + border-bottom-color: lighten($dark-color, 40%); + } } } } + + &__position { + font-size: $bigger-font-size; + } + + &__biography { + margin-top: $double-margin; + + p { + margin-bottom: $single-margin; + } + } } @media (max-width: $mobile-width) { diff --git a/src/style/style.scss b/src/style/style.scss index d909d1c1..e7197377 100644 --- a/src/style/style.scss +++ b/src/style/style.scss @@ -1,6 +1,7 @@ @import "components/album-collection"; @import "components/gallery-item"; @import "components/document"; +@import "components/documents-container"; @import "components/teacher-proifile"; @import "components/main-menu"; @import "components/navigation"; @@ -12,6 +13,8 @@ @import "components/schedule-table"; @import "components/footer-links"; @import "components/event-post"; +@import "components/album"; +@import "components/parallax"; @import "components/page-school"; @import "components/page-schedule"; @@ -23,8 +26,6 @@ @import "content"; @import "page-animation"; -@import "documents"; -@import "album"; @import "schedule-selector"; @import "schedule-mobile"; @import "error-404"; diff --git a/src/templates/components/album-collection.html b/src/templates/components/album-collection.html index 2bfe07ec..dd35f9d2 100644 --- a/src/templates/components/album-collection.html +++ b/src/templates/components/album-collection.html @@ -1,6 +1,6 @@
-

{{$ctrl.title}}

+

{{$.title}}

- +
\ No newline at end of file diff --git a/src/templates/components/album.html b/src/templates/components/album.html new file mode 100644 index 00000000..16e9a66f --- /dev/null +++ b/src/templates/components/album.html @@ -0,0 +1,15 @@ +
+ + + + + + + +
+

{{$.title}}

+ +
+ +
+
diff --git a/src/templates/components/award.html b/src/templates/components/award.html index 591c9bd0..757b975c 100644 --- a/src/templates/components/award.html +++ b/src/templates/components/award.html @@ -1,5 +1,7 @@
- - - +
+ +
\ No newline at end of file diff --git a/src/templates/components/event-post.html b/src/templates/components/event-post.html index 6e63087f..b3f4f43f 100644 --- a/src/templates/components/event-post.html +++ b/src/templates/components/event-post.html @@ -1,8 +1,8 @@ -
-
+
+
-
+ diff --git a/src/templates/components/gallery-item.html b/src/templates/components/gallery-item.html index cf242be8..75c88927 100644 --- a/src/templates/components/gallery-item.html +++ b/src/templates/components/gallery-item.html @@ -1,9 +1,6 @@ \ No newline at end of file diff --git a/src/templates/components/navigation.html b/src/templates/components/navigation.html index 2496a232..02516a0b 100644 --- a/src/templates/components/navigation.html +++ b/src/templates/components/navigation.html @@ -1,5 +1,5 @@