diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..b4334a9 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,3 @@ +*.ttf filter=lfs diff=lfs merge=lfs -text +*.jpg filter=lfs diff=lfs merge=lfs -text +*.png filter=lfs diff=lfs merge=lfs -text diff --git a/components/Element.tsx b/components/Element.tsx index 86861c8..0d8c9a0 100644 --- a/components/Element.tsx +++ b/components/Element.tsx @@ -1,11 +1,13 @@ import React from 'react' import Link from 'next/link' import { ChevronRight } from 'react-feather' +import next from 'next' interface Props { title: string date: Date image?: string + alt?: string link: string } @@ -30,30 +32,40 @@ export default class Element extends React.Component { super(props) } render() { + let date = this.props.date + if (typeof this.props.date === "string") { + date = new Date(this.props.date) + } + const t = `${date.getDate()} ${months[date.getMonth()]} ${date.getFullYear()}` return (
{this.props.image ? ( - + {this.props.alt}/ ) : (
)} - Le {this.props.date.getDate()} {months[this.props.date.getMonth()]} {this.props.date.getFullYear()} + Le {t} {this.props.title} - + diff --git a/components/Footer.tsx b/components/Footer.tsx new file mode 100644 index 0000000..bb5adbc --- /dev/null +++ b/components/Footer.tsx @@ -0,0 +1,72 @@ +import React from 'react' +import { PhoneCall, Mail, GitHub, Twitter, Linkedin } from 'react-feather' +import Link from 'next/link' + +interface Props {} + +interface States {} + +export default class Footer extends React.Component { + constructor(props: Props) { + super(props) + } + render() { + return ( +
+
+
+ + + + + + + + + + + + + + + + + +
+ +
+ ) + } +} diff --git a/components/Header.tsx b/components/Header.tsx index 1df62d0..156e66b 100644 --- a/components/Header.tsx +++ b/components/Header.tsx @@ -10,20 +10,27 @@ export default class Header extends React.Component { render() { return (
- - - + {/*

Bienvenue sur le Portfolio de Florian BOUILLON !

*/}
diff --git a/components/Layout.tsx b/components/Layout.tsx new file mode 100644 index 0000000..5fabf4f --- /dev/null +++ b/components/Layout.tsx @@ -0,0 +1,55 @@ +import React from 'react' +import Navbar from './Navbar' +import Menu from './Menu' +import Header from './Header' +import Footer from './Footer' + +interface Props { + hasHeader?: boolean + headerChild?: JSX.Element +} + +export default class Layout extends React.Component { + constructor(props: Props) { + super(props) + } + render() { + return ( +
+ + + + {this.props.hasHeader && this.props.headerChild ? ( +
{this.props.headerChild}
+ ) : ( +
+ )} + {this.props.children} +
+ + +
+ + ) + } +} diff --git a/components/Navbar.tsx b/components/Navbar.tsx index d8d00b1..72f77f5 100644 --- a/components/Navbar.tsx +++ b/components/Navbar.tsx @@ -1,6 +1,7 @@ import React from 'react' import { Menu } from 'react-feather' import { timingSafeEqual } from 'crypto' +import Link from 'next/link' interface Props { height?: number @@ -59,11 +60,19 @@ export default class Navbar extends React.Component { margin-top: ${height}px; overflow-x: hidden; } + .menu * { + pointer-events: none; + } + .menu.shown * { + pointer-events: initial; + } `}
- + + + @@ -84,8 +93,11 @@ export default class Navbar extends React.Component { nav.scrolled { box-shadow: 0 0 10px 5px #00000040 } - img { - height: 80%; + a { + height: 100%; + flex-grow: 1; + display: flex; + justify-content: center; } hr { height: 10px; @@ -94,10 +106,14 @@ export default class Navbar extends React.Component { background: linear-gradient(90deg, #45CAFC 0%, #4285F4 92.19%); } .menu { - display: none + opacity: 0; + pointer-event: none; + height: 0; + transition: opacity 200ms cubic-bezier(.2,0,.6,1); } .menu.shown { - display: block + opacity: 1; + height: initial; } .head { display: flex; @@ -109,10 +125,13 @@ export default class Navbar extends React.Component { } img { flex-grow: 1; + height: 100%; + } span { width: ${height-10}px; height: ${height-10}px; + cursor: pointer; display: flex; justify-content: center; align-items: center; diff --git a/components/Post.ts b/components/Post.ts index 991d919..6f5575d 100644 --- a/components/Post.ts +++ b/components/Post.ts @@ -7,8 +7,15 @@ interface PostInterface { content: any } -interface PostHeader { +export interface PostHeader { title: string + id: string + category: string + image?: string + imageAlt?: string + date: Date + url?: string + tags?: string[] } export default class Post implements PostInterface { @@ -18,23 +25,27 @@ export default class Post implements PostInterface { public content: string public isStarted = false + public header: PostHeader + constructor(slug: string) { this.slug = slug } public async fetch() { - console.log(this.slug) - const content = await import(`../posts/${this.slug}.md`) + if (!this.slug.endsWith(".md")) this.slug = "portfolio/" + this.slug + ".md" + const content = await import(`../posts/${this.slug}`) const md = matter(content.default) this.title = md.data.title + this.header = (md.data as PostHeader) this.content = md.content } public fetchSync() { - console.log(this.slug) - const content = require(`../posts/${this.slug}.md`) + if (!this.slug.endsWith(".md")) this.slug = "portfolio/" + this.slug + ".md" + const content = require(`../posts/${this.slug}`) const md = matter(content.default) this.title = md.data.title + this.header = (md.data as PostHeader) this.content = md.content } @@ -44,10 +55,7 @@ export default class Post implements PostInterface { for (const file of files) { posts.push( new Post( - file.replace(/^.*[\\\/]/, '') - .split('.') - .slice(0, -1) - .join('.') + file.replace("./", '') ) ) } diff --git a/components/default.tsx b/components/default.tsx index 7b10527..b76ea88 100644 --- a/components/default.tsx +++ b/components/default.tsx @@ -1,9 +1,10 @@ import React from 'react' -interface Props { -} +interface Props {} -export default class Name extends React.Component { +interface States {} + +export default class Name extends React.Component { constructor(props: Props) { super(props) } diff --git a/components/interfaces/Category.ts b/components/interfaces/Category.ts deleted file mode 100644 index 73d5b95..0000000 --- a/components/interfaces/Category.ts +++ /dev/null @@ -1,4 +0,0 @@ -export default interface Category { - name: string - slug: string -} diff --git a/export.js b/export.js index 4de11ce..01fd21b 100755 --- a/export.js +++ b/export.js @@ -36,13 +36,15 @@ const options3 = { async function run() { try { const res3 = await replace(options3) - console.log(res3) + // console.log(res3) const res2 = await replace(options2) - console.log(res2) + // console.log(res2) const results = await replace(options) - console.log(results) + // console.log(results) + process.exit(0) } catch (error) { console.error(error) + process.exit(1) } } diff --git a/next.config.js b/next.config.js index abc3a4d..db40a48 100644 --- a/next.config.js +++ b/next.config.js @@ -1,6 +1,8 @@ const withCSS = require('@zeit/next-stylus') const glob = require('glob') const withOffline = require('next-offline') +const matter = require('gray-matter') +const fs = require('fs') // import posts from './posts/pages.json.ts' // const posts = require('./posts/pages.json.ts') // const t = require('./pages/portfolio/') @@ -22,17 +24,20 @@ module.exports = withOffline(withCSS({ exportPathMap: async function() { const paths = { '/': { page: '/'}, - '/portfolio': { page: '/portfolio'}, } const posts = glob.sync('./posts/**/*.md') posts.forEach(element => { + const datas = matter(fs.readFileSync(element)).data element = element.replace(/^.*[\\\/]/, '') .split('.') .slice(0, -1) .join('.') - paths[`/portfolio/${element}`] = { page: '/portfolio/[slug]', query: { slug: element}} + paths[`/${datas.category.toLowerCase()}/${datas.id}`] = { page: '/[category]/[slug]', query: {category: datas.category.toLowerCase(), slug: datas.id}} + for (const tg of datas.tags) { + paths[`/tag/${tg.toLowerCase()}`] = { page: '/tag/[tag]', query: {tag: tg}} + } }); return paths diff --git a/package.json b/package.json index 91f1079..3c031ba 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "dependencies": { "@zeit/next-css": "^1.0.1", "@zeit/next-stylus": "^1.0.1", + "fs": "^0.0.1-security", "glob": "^7.1.6", "gray-matter": "^4.0.2", "next": "9.1.5", diff --git a/pages/[category]/[slug].tsx b/pages/[category]/[slug].tsx new file mode 100644 index 0000000..a577f6b --- /dev/null +++ b/pages/[category]/[slug].tsx @@ -0,0 +1,128 @@ +import { NextPageContext } from "next" + +import{ Component } from 'react' +import Post from "../../components/Post" +import ReactMarkdown from 'react-markdown' +import Error from "../_error" +import Link from "next/link" + +interface Props { + post: Post +} + +interface States { + imgHeight: number +} + +export default class PostPage extends Component { + public render() { + return ( +
+ {this.props.post === undefined ? ( + + ) : ( +
+ {this.props.post.header.imageAlt} + +

Détails

+

Tags:

+
    + {this.props.post.header.tags.map((el) => ( +
  • + + {el} + +
  • + ))} +
+ {this.props.post.header.url ? ( + Visiter le site :D + ) : undefined} +
+ )} + + +
+ ) + } + + public static async getInitialProps(context: NextPageContext) { + const { slug } = context.query + if (typeof slug === "object" || slug === "[slug]") return {post: undefined} + const post = new Post(slug) + await post.fetch() + return {post} + } +} diff --git a/pages/portfolio/index.tsx b/pages/[category]/index.tsx similarity index 84% rename from pages/portfolio/index.tsx rename to pages/[category]/index.tsx index 3d5c297..a42023a 100644 --- a/pages/portfolio/index.tsx +++ b/pages/[category]/index.tsx @@ -26,7 +26,7 @@ const PortfolioIndex: NextPage = (props: Props) => {
    {props.files.map(post => (
  • - + {post.title}
  • @@ -41,7 +41,7 @@ PortfolioIndex.getInitialProps = async (context: NextPageContext) => { for (const post of await Post.fetchAll()) { if (!post.isStarted) await post.fetch() arr.push({ - slug: post.slug, + slug: post.slug.replace(".md", ""), title: post.title }) } @@ -49,10 +49,3 @@ PortfolioIndex.getInitialProps = async (context: NextPageContext) => { } export default PortfolioIndex - -function l(args: any) { - console.log(arguments) -} - -async function test() { -} diff --git a/pages/_app.tsx b/pages/_app.tsx index c4f965f..62ec26f 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -1,23 +1,17 @@ import React from 'react' import App from 'next/app' +import '../styl/styl.styl' +import Layout from '../components/Layout' class MyApp extends App { - // Only uncomment this method if you have blocking data requirements for - // every single page in your application. This disables the ability to - // perform automatic static optimization, causing every page in your app to - // be server-side rendered. - // - // static async getInitialProps(appContext) { - // // calls page's `getInitialProps` and fills `appProps.pageProps` - // const appProps = await App.getInitialProps(appContext); - // - // return { ...appProps } - // } - - render() { - const { Component, pageProps } = this.props - return - } + render() { + const { Component, pageProps } = this.props + return( + + + + ) + } } export default MyApp diff --git a/pages/_document.tsx b/pages/_document.tsx index 2f75841..cf80161 100644 --- a/pages/_document.tsx +++ b/pages/_document.tsx @@ -5,22 +5,24 @@ import Document, { Html, Head, Main, NextScript } from 'next/document' class MyDocument extends Document { - static async getInitialProps(ctx) { - const initialProps = await Document.getInitialProps(ctx) - return { ...initialProps } - } + static async getInitialProps(ctx) { + const initialProps = await Document.getInitialProps(ctx) + return { ...initialProps } + } - render() { - return ( - - - -
    - - - - ) - } + render() { + return ( + + + + + +
    + + + + ) + } } export default MyDocument diff --git a/pages/_error.tsx b/pages/_error.tsx new file mode 100644 index 0000000..bc31281 --- /dev/null +++ b/pages/_error.tsx @@ -0,0 +1,58 @@ +import React, { Component } from 'react' +import { NextPageContext } from 'next' +import Head from 'next/head' +import Layout from '../components/Layout' + +interface Props { + statusCode: number +} + +const codesTexts = { + 404: "Page non trouvé !", + 500: "Le serveur n'a pas pu répondre a ta demande :O" +} + +export default class Error extends Component { + public render = () => { + const statusCode = this.props.statusCode + return ( +
    + + Pouet :D + +
    +

    {statusCode ? statusCode : "404"}

    +

    {statusCode ? codesTexts[statusCode] : codesTexts[404]}

    +
    + +
    + ) + } + + getInitialProps = ({ res, err }: NextPageContext) => { + const statusCode = res ? res.statusCode : err ? err.statusCode : 404 + return { statusCode } + } +} diff --git a/pages/index.tsx b/pages/index.tsx index 964ca83..d8219db 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -1,124 +1,119 @@ -import { NextPage } from 'next' -import Head from 'next/head' -import Link from 'next/link' -import '../styl/styl.styl' import Element from '../components/Element' -import Navbar from '../components/Navbar' -import Header from '../components/Header' -import Menu from '../components/Menu' import Filters from '../components/Filters' -import Category from '../components/interfaces/Category' import { Component } from 'react' +import Post, { PostHeader } from '../components/Post' interface Props { userAgent?: string } -interface el { - link: string, - title: string, - img: string, - date: Date -} +interface el extends PostHeader {} interface States { elements: el[] + loaded: boolean asideHeight: number + categories: string[] } // export const config = {amp: 'hybrid'} -const categories: Category[] = [ - { - name: "test", - slug: "pouet" - } -] - -const elements: el[] = [ - {link:"/studiomoto", title:"Studiomoto, Site de référencement d'événement moto en France", img:"/uploads/stm.png", date: new Date()}, - {link:"/studiomoto", title:"Studiomoto, Site de référencement d'événement moto en France", img:"/uploads/stm.png", date: new Date()}, - {link:"/studiomoto", title:"Studiomoto, Site de référencement d'événement moto en France", img:"/uploads/stm.png", date: new Date()}, - {link:"/studiomoto", title:"Studiomoto, Site de référencement d'événement moto en France", img:"/uploads/stm.png", date: new Date()}, - {link:"/studiomoto", title:"Studiomoto, Site de référencement d'événement moto en France", img:"/uploads/stm.png", date: new Date()}, - {link:"/studiomoto", title:"Studiomoto, Site de référencement d'événement moto en France", img:"/uploads/stm.png", date: new Date()}, - {link:"/studiomoto", title:"Dzeio.io, Services en ligne pour vous simplifier la vie !", img:"/sea.jpg", date: new Date()}, - {link:"/studiomoto", title:"Loram ipsum dolor sit amet", img:"/uploads/stm.png", date: new Date()}, - {link:"/studiomoto", title:"j'aime les licornes et leurs jolie corne", img:"/uploads/stm.png", date: new Date()}, - {link:"/studiomoto", title:"Pokémon ! attrapez les tous !", img:"/uploads/stm.png", date: new Date()}, - {link:"/studiomoto", title:"abcde", img:"/uploads/stm.png", date: new Date()}, - {link:"/studiomoto", title:"def", img:"/uploads/stm.png", date: new Date()}, - {link:"/studiomoto", title:"abc", img:"/uploads/stm.png", date: new Date()}, - {link:"/studiomoto", title:"Studiomoto, Site de référencement d'événement moto en France", img:"/uploads/stm.png", date: new Date()}, - {link:"/studiomoto", title:"Studiomoto, Site de référencement d'événement moto en France", img:"/uploads/stm.png", date: new Date()}, - {link:"/studiomoto", title:"Studiomoto, Site de référencement d'événement moto en France", img:"/uploads/stm.png", date: new Date()}, - {link:"/studiomoto", title:"Studiomoto, Site de référencement d'événement moto en France", img:"/uploads/stm.png", date: new Date()} -] +let elements: PostHeader[] = [] export default class Page extends Component { - onQuery = (query: string) => { - console.log(`query: ${query}`) + onQuery = async (query: string, recent: boolean = true) => { + // console.log(`query: ${query}`) const t= elements.filter(el => { return el.title.toLowerCase().includes(query.toLowerCase()) }) + if (recent) { + t.sort((a, b) => { + return (a.date < b.date) ? 1 : -1 + }) + } else { + t.sort((a, b) => { + return (a.date > b.date) ? 1 : -1 + }) + } this.setState({ elements: t }) } - onHeight = (height: number) => { + onHeight = async (height: number) => { this.setState({ asideHeight: height }) } - componentDidMount() { + async componentDidMount() { + const posts = await Post.fetchAll() + const header: Array = [] + let cats: Array = [] + posts.forEach(el => { + el.fetchSync() + header.push(el.header) + cats.push(...el.header.tags) + }) + header.sort((a, b) => { + return (a.date < b.date) ? 1 : -1 + }) + + cats.sort((a, b) => (a < b) ? -1 : 1) + + elements = header this.setState({ - elements + elements: header, + loaded: true, + categories: cats.filter((item, pos) => {return cats.indexOf(item) === pos}) }) } render() { return ( -
    - - - - - - -
    -
    - - {this.state && this.state.elements.map((el, index) => ( - - ))} - - -
    +
    + + {this.state && this.state.elements && this.state.elements.length !== 0 ? this.state.elements.map((el, index) => ( + + )) : this.state && this.state.loaded ? ( +
    La recherche n'a rien donnée 😢
    + ) : ( +
    Chargement en cours... 😃
    + )} +
    + -
    +
    + ) } } diff --git a/pages/portfolio/[slug].tsx b/pages/portfolio/[slug].tsx deleted file mode 100644 index 1cce362..0000000 --- a/pages/portfolio/[slug].tsx +++ /dev/null @@ -1,28 +0,0 @@ -import { NextPage, NextPageContext } from "next" - -import React from 'react' -import Post from "../../components/Post" -import ReactMarkdown from 'react-markdown' - -interface Props { - post: Post -} - -const PostPage: NextPage = (props: Props) => { - // React. - return ( -
    - -
    - ) -} - -PostPage.getInitialProps = async (context: NextPageContext) => { - const { slug } = context.query - if (typeof slug === "object") throw new Error("Slug is not correct") - const post = new Post(slug) - await post.fetch() - return {post} -} - -export default PostPage diff --git a/pages/tag/[tag].tsx b/pages/tag/[tag].tsx new file mode 100644 index 0000000..e87dedf --- /dev/null +++ b/pages/tag/[tag].tsx @@ -0,0 +1,85 @@ +import { NextPage, NextPageContext } from "next" +import Link from 'next/link' +import Post from "../../components/Post" +import Element from '../../components/Element' +import Error from "../_error" +// import posts from '../../posts/pages.json' +// import firstline from 'firstline' +// import 'fs' + +interface Props { + files: Post[], + tag: string +} + +const PortfolioIndex: NextPage = (props: Props) => { + + const el: JSX.Element[] = [] + for (const post of props.files) { + el.push( + ) + } + + if (props.files.length === 0) { + return ( + + ) + } + + return ( +
    +

    Tag: {props && props.tag}

    +
    + {props.files.map((post, index) => ( + + ))} +
    + +
    + ) +} + +PortfolioIndex.getInitialProps = async (context: NextPageContext) => { + const { tag } = context.query + if (typeof tag === "object" || tag === "[tag]") return {files: [], tag: ""} + const arr: Post[] = [] + for (const post of await Post.fetchAll()) { + if (!post.isStarted) await post.fetch() + let tags = [] + for (const tg of post.header.tags) { + tags.push(tg.toLowerCase()) + } + if (!tags.includes(tag)) continue + arr.push(post) + } + return {files: arr, tag: tag} as Props +} + +export default PortfolioIndex diff --git a/posts/portfolio/dzeio.md b/posts/portfolio/dzeio.md new file mode 100644 index 0000000..4b0d755 --- /dev/null +++ b/posts/portfolio/dzeio.md @@ -0,0 +1,12 @@ +--- +title: DZE.IO +id: dzeio +image: /uploads/dzeio.png +imageAlt: Logo & Description de dze.io +date: 2020-06-01 +category: Portfolio +url: https://dze.io/ +tags: ["Golang", "Javascript", "Typescript", "CSS", "Stylus"] +--- + +# Dze.io, Page en cours 😄 diff --git a/posts/portfolio/studiomoto.md b/posts/portfolio/studiomoto.md new file mode 100644 index 0000000..d12bcd7 --- /dev/null +++ b/posts/portfolio/studiomoto.md @@ -0,0 +1,28 @@ +--- +title: Studiomoto +id: studiomoto +image: /uploads/stm.png +imageAlt: Logo & Description de studiomoto +date: 2018-10-10 +category: Portfolio +url: https://www.studiomoto.fr/ +tags: ["PHP", "Symfony", "Javascript", "Typescript", "CSS", "Stylus"] +--- + +# Studiomoto, Site de référencement d’événement Moto en France + +## Objectifs premiers + +L’idée était de transformer un encien site sous Wordpress en un site construit de zéro afin de pouvoir en faire un système facilement ajustable, plus customisable et plus rapide. + +Afin d’atteindre ces trois points il a été choisis de partir sur Symfony afin de pouvoir avoir un site fonctionnel rapidement. + +## Développement + +Le site est en constante évolution et la roadmap est la suivant : + +- Visualisation des évènement en front pour le public et un dashboard pour les Administrateurs afin de pouvoir ajouter et modifier le évenements + +- Les utilisateurs et organisations peuvent se connecter au site et peuvent rajouter des évènements + +- Plus d’interaction entre le site et les utilisateurs en ajoutant une fonctionnalité de balade. diff --git a/posts/test.md b/posts/test.md deleted file mode 100644 index b0975f9..0000000 --- a/posts/test.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -title: pouet :D ---- - -# Pouet :D diff --git a/public/fonts/Aileron-Black.ttf b/public/fonts/Aileron-Black.ttf new file mode 100644 index 0000000..4d384b2 --- /dev/null +++ b/public/fonts/Aileron-Black.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b4ade4e081b12facd22a9e7ffddb10bdf32d978024ba4cd6a06cae5c971da0ef +size 38088 diff --git a/public/fonts/Aileron-BlackItalic.ttf b/public/fonts/Aileron-BlackItalic.ttf new file mode 100644 index 0000000..bb5cfaf --- /dev/null +++ b/public/fonts/Aileron-BlackItalic.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:35ed03e1600c62124e5a967b2445565289dbff87363f091f72061ecbbb4a697f +size 39996 diff --git a/public/fonts/Aileron-Bold.ttf b/public/fonts/Aileron-Bold.ttf new file mode 100644 index 0000000..ae1f729 --- /dev/null +++ b/public/fonts/Aileron-Bold.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:8122bfa8c6570dfefbd6b38d1ae6a24f0c81c75a1a8e57b8e6a2f46c625ef979 +size 38304 diff --git a/public/fonts/Aileron-BoldItalic.ttf b/public/fonts/Aileron-BoldItalic.ttf new file mode 100644 index 0000000..171df46 --- /dev/null +++ b/public/fonts/Aileron-BoldItalic.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9107717e3528638dd53a4f56aa0bdd5411ef277c071a4f42f8a3f9c86568538a +size 40620 diff --git a/public/fonts/Aileron-Heavy.ttf b/public/fonts/Aileron-Heavy.ttf new file mode 100644 index 0000000..50c4260 --- /dev/null +++ b/public/fonts/Aileron-Heavy.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:71177b607e4053a8c472a68d94a6efba29919f54838d4724ba86cd362ccc6d51 +size 38416 diff --git a/public/fonts/Aileron-HeavyItalic.ttf b/public/fonts/Aileron-HeavyItalic.ttf new file mode 100644 index 0000000..670e4bb --- /dev/null +++ b/public/fonts/Aileron-HeavyItalic.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2f43776004e78088aa1adf1c7935ccf70743f6e9032301f21f334be7a7dd72bf +size 40440 diff --git a/public/fonts/Aileron-Italic.ttf b/public/fonts/Aileron-Italic.ttf new file mode 100644 index 0000000..4196cae --- /dev/null +++ b/public/fonts/Aileron-Italic.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d8eb6984408b33575359478bf531e78fd3535b08797784aef54b1847e5511705 +size 41032 diff --git a/public/fonts/Aileron-Light.ttf b/public/fonts/Aileron-Light.ttf new file mode 100644 index 0000000..81a1592 --- /dev/null +++ b/public/fonts/Aileron-Light.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:85c9c438bc11f0d54065e60f7c884f420f7487a4e921c04334ac944b1613b405 +size 38876 diff --git a/public/fonts/Aileron-LightItalic.ttf b/public/fonts/Aileron-LightItalic.ttf new file mode 100644 index 0000000..b1b58be --- /dev/null +++ b/public/fonts/Aileron-LightItalic.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:05377820e3ee66a23bb0d40e0caefba8f1579bfb0dbcd2b0cc4e84d0c7de084a +size 41220 diff --git a/public/fonts/Aileron-Regular.ttf b/public/fonts/Aileron-Regular.ttf new file mode 100644 index 0000000..7011104 --- /dev/null +++ b/public/fonts/Aileron-Regular.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:47d06f5a02e49f34766f0f8e746f3c6ec641b9930278772e84c26e6df25bf14d +size 38168 diff --git a/public/fonts/Aileron-SemiBold.ttf b/public/fonts/Aileron-SemiBold.ttf new file mode 100644 index 0000000..6b93684 --- /dev/null +++ b/public/fonts/Aileron-SemiBold.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:cb795f523fcd07ffda06179b4649605d5552916e018dec9dce5e2a59ce64ae28 +size 38612 diff --git a/public/fonts/Aileron-SemiBoldItalic.ttf b/public/fonts/Aileron-SemiBoldItalic.ttf new file mode 100644 index 0000000..959b2aa --- /dev/null +++ b/public/fonts/Aileron-SemiBoldItalic.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b73a0b7dbb381344b1f9b32406be8b4d065073f1fbbc586dcc686c4df292cb28 +size 41184 diff --git a/public/fonts/Aileron-Thin.ttf b/public/fonts/Aileron-Thin.ttf new file mode 100644 index 0000000..457a1d7 --- /dev/null +++ b/public/fonts/Aileron-Thin.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5d04db6398893af7c86bb0aff112589c4ff529b56fac128346ff72819a3132b9 +size 39056 diff --git a/public/fonts/Aileron-ThinItalic.ttf b/public/fonts/Aileron-ThinItalic.ttf new file mode 100644 index 0000000..a8821a4 --- /dev/null +++ b/public/fonts/Aileron-ThinItalic.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:80d0f93f3f4f029ee0f45fe0ad68c8caf3fbaa739dc61912013d4bf718e34fc6 +size 41308 diff --git a/public/fonts/Aileron-UltraLight.ttf b/public/fonts/Aileron-UltraLight.ttf new file mode 100644 index 0000000..1ad4e38 --- /dev/null +++ b/public/fonts/Aileron-UltraLight.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b68177274ef371eadec5cff5672c9230e94faea0afb1557af79a5eb95c4f53f7 +size 39136 diff --git a/public/fonts/Aileron-UltraLightItalic.ttf b/public/fonts/Aileron-UltraLightItalic.ttf new file mode 100644 index 0000000..fcb8452 --- /dev/null +++ b/public/fonts/Aileron-UltraLightItalic.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0ddcffab417bd4cd18f31474363162cf5e0fb8165ede8ca50d9afde666cc1d84 +size 41472 diff --git a/public/fonts/Blobmoji.ttf b/public/fonts/Blobmoji.ttf new file mode 100644 index 0000000..2153241 --- /dev/null +++ b/public/fonts/Blobmoji.ttf @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:702d0521c6f58476abc9f16f09b6a2943850b1b54cf098f573f6ee4a5ff5db6a +size 8305868 diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..c2a49f4 --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Allow: / diff --git a/public/sea.jpg b/public/sea.jpg index c06a384..4b6872f 100644 Binary files a/public/sea.jpg and b/public/sea.jpg differ diff --git a/public/uploads/dzeio.png b/public/uploads/dzeio.png new file mode 100644 index 0000000..bef1a88 --- /dev/null +++ b/public/uploads/dzeio.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1fdb6128c4505163e416216b96f2139214fa1d589f39e8ad01da842e42e4d319 +size 1556838 diff --git a/public/uploads/stm.png b/public/uploads/stm.png index 7a75b5d..e2630cd 100644 Binary files a/public/uploads/stm.png and b/public/uploads/stm.png differ diff --git a/styl/include/_aileron.styl b/styl/include/_aileron.styl new file mode 100644 index 0000000..43d90ec --- /dev/null +++ b/styl/include/_aileron.styl @@ -0,0 +1,110 @@ +@font-face + font-family: 'Aileron' + src: local('Aileron Bold'), local('Aileron-Bold'), url('/fonts/Aileron-Bold.ttf') format('truetype') + font-weight: bold + font-style: normal + + +@font-face + font-family: 'Aileron' + src: local('Aileron Italic'), local('Aileron-Italic'), url('/fonts/Aileron-Italic.ttf') format('truetype') + font-weight: normal + font-style: italic + + +@font-face + font-family: 'Aileron' + src: local('Aileron Black Italic'), local('Aileron-BlackItalic'), url('/fonts/Aileron-BlackItalic.ttf') format('truetype') + font-weight: 900 + font-style: italic + + +@font-face + font-family: 'Aileron' + src: local('Aileron Bold Italic'), local('Aileron-BoldItalic'), url('/fonts/Aileron-BoldItalic.ttf') format('truetype') + font-weight: bold + font-style: italic + + +@font-face + font-family: 'Aileron' + src: local('Aileron Light'), local('Aileron-Light'), url('/fonts/Aileron-Light.ttf') format('truetype') + font-weight: 300 + font-style: normal + + +@font-face + font-family: 'Aileron' + src: local('Aileron Black'), local('Aileron-Black'), url('/fonts/Aileron-Black.ttf') format('truetype') + font-weight: 900 + font-style: normal + + +@font-face + font-family: 'Aileron' + src: local('Aileron Heavy Italic'), local('Aileron-HeavyItalic'), url('/fonts/Aileron-HeavyItalic.ttf') format('truetype') + font-weight: 900 + font-style: italic + + +@font-face + font-family: 'Aileron' + src: local('Aileron UltraLight Italic'), local('Aileron-UltraLightItalic'), url('/fonts/Aileron-UltraLightItalic.ttf') format('truetype') + font-weight: 200 + font-style: italic + + +@font-face + font-family: 'Aileron' + src: local('Aileron Heavy'), local('Aileron-Heavy'), url('/fonts/Aileron-Heavy.ttf') format('truetype') + font-weight: 900 + font-style: normal + + +@font-face + font-family: 'Aileron' + src: local('Aileron Thin'), local('Aileron-Thin'), url('/fonts/Aileron-Thin.ttf') format('truetype') + font-weight: 100 + font-style: normal + + +@font-face + font-family: 'Aileron' + src: local('Aileron UltraLight'), local('Aileron-UltraLight'), url('/fonts/Aileron-UltraLight.ttf') format('truetype') + font-weight: 200 + font-style: normal + + +@font-face + font-family: 'Aileron' + src: local('Aileron SemiBold'), local('Aileron-SemiBold'), url('/fonts/Aileron-SemiBold.ttf') format('truetype') + font-weight: 600 + font-style: normal + + +@font-face + font-family: 'Aileron' + src: local('Aileron Regular'), local('Aileron-Regular'), url('/fonts/Aileron-Regular.ttf') format('truetype') + font-weight: normal + font-style: normal + + +@font-face + font-family: 'Aileron' + src: local('Aileron Thin Italic'), local('Aileron-ThinItalic'), url('/fonts/Aileron-ThinItalic.ttf') format('truetype') + font-weight: 100 + font-style: italic + + +@font-face + font-family: 'Aileron' + src: local('Aileron Light Italic'), local('Aileron-LightItalic'), url('/fonts/Aileron-LightItalic.ttf') format('truetype') + font-weight: 300 + font-style: italic + + +@font-face + font-family: 'Aileron' + src: local('Aileron SemiBold Italic'), local('Aileron-SemiBoldItalic'), url('/fonts/Aileron-SemiBoldItalic.ttf') format('truetype') + font-weight: 600 + font-style: italic diff --git a/styl/include/_blobmoji.styl b/styl/include/_blobmoji.styl new file mode 100644 index 0000000..e2f8dec --- /dev/null +++ b/styl/include/_blobmoji.styl @@ -0,0 +1,8 @@ +@font-face + font-family: "Blobmoji" + // TODO: find a way to use it internally + src: local('Blobmoji') + src: url('/fonts/Blobmoji.ttf') + +.emoji + font-family: 'Blobmoji' diff --git a/styl/include/_button.styl b/styl/include/_button.styl index a4dc0a0..6cae8af 100644 --- a/styl/include/_button.styl +++ b/styl/include/_button.styl @@ -12,7 +12,7 @@ button, a.button cursor: pointer color: #FFF background-color: $color - border-radius: 5px + border-radius: 10px border: none padding: 7px 14px transition-property: box-shadow, background-color @@ -26,6 +26,12 @@ button, a.button line-height: 22px text-decoration: none box-sizing: border-box + justify-content center + + &.large + padding 20px 25px + text-transform uppercase + font-size 20px &:hover background-color: $hover diff --git a/styl/include/_input.styl b/styl/include/_input.styl index 147eda9..cd59674 100644 --- a/styl/include/_input.styl +++ b/styl/include/_input.styl @@ -11,8 +11,7 @@ $color = #4285F4 &:not(:last-of-type) margin-right 10px - - input + input, select display block border-radius 10px background-color #EEE @@ -45,6 +44,13 @@ $color = #4285F4 background-color #FFF box-shadow inset 0 0 0 2px $color, 0 0 0 3px rgba(204,204,204, .75) + + select + -webkit-appearance none + -moz-appearance none + appearance none + display inline-flex + label text-transform uppercase margin auto @@ -60,13 +66,12 @@ $color = #4285F4 font-weight 300 font-style italic - // Icons - i - width 25px + width 24px + height 24px position absolute - left 28px + left 20px top 18px // pointer-events none color #666 @@ -74,17 +79,25 @@ $color = #4285F4 &.icon-right i left initial - right 28px + right 20px - &.icon-left input + &.icon-left input, + &.icon-left select padding-left 50px - &.icon-right input + &.icon-right input, + &.icon-right select padding-right 50px - &.icon-right input, &.icon-left input + &.icon-right input, &.icon-left input, + &.icon-right select, &.icon-left select max-width calc(100% - 76px) - input:focus:not([readonly]) + i + &.icon-right select, &.icon-left select + max-width 100% + + + input:focus:not([readonly]) + i, + select:focus:not([readonly]) + i color $color diff --git a/styl/styl.styl b/styl/styl.styl index ebfaf63..5cba6e1 100644 --- a/styl/styl.styl +++ b/styl/styl.styl @@ -1,6 +1,16 @@ +@import "include/_aileron" +@import "include/_blobmoji" @import "include/_button" @import "include/_input" html, body { margin 0 } + +div, span, a, p, h1, h2, h3, h4, h5, h6, i { + font-family Aileron, BlinkMacSystemFont, -apple-system, "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", "Helvetica", "Arial", sans-serif +} + +::selection + background #4285F4 + color white diff --git a/yarn.lock b/yarn.lock index 2397080..2e0b3e7 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2911,6 +2911,11 @@ fs.realpath@^1.0.0: resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= +fs@^0.0.1-security: + version "0.0.1-security" + resolved "https://registry.yarnpkg.com/fs/-/fs-0.0.1-security.tgz#8a7bd37186b6dddf3813f23858b57ecaaf5e41d4" + integrity sha1-invTcYa23d84E/I4WLV+yq9eQdQ= + fsevents@^1.2.7: version "1.2.9" resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.9.tgz#3f5ed66583ccd6f400b5a00db6f7e861363e388f"