Prechádzať zdrojové kódy

added proxy, working on optics.

Tomi Cvetic 4 rokov pred
rodič
commit
4a983740bc

+ 15 - 16
.vscode/settings.json

@@ -1,17 +1,16 @@
 {
-    "standard.autoFixOnSave": true,
-    "editor.formatOnSave": true,
-    "javascript.validate.enable": false,
-    "emmet.includeLanguages": {
-        "javascript": "javascriptreact"
-    },
-    "prettifySymbolsMode.adjustCursorMovement": true,
-    "editor.fontFamily": "'Fira Code', 'Droid Sans Mono', 'monospace', monospace, 'Droid Sans Fallback'",
-    "editor.fontLigatures": true,
-    "files.trimTrailingWhitespace": true,
-    "workbench.colorTheme": "Cobalt2",
-    "editor.tabSize": 2,
-    "prettier.jsxSingleQuote": true,
-    "prettier.semi": false,
-    "prettier.singleQuote": true
-}
+  "editor.formatOnSave": true,
+  "javascript.validate.enable": false,
+  "emmet.includeLanguages": {
+    "javascript": "javascriptreact"
+  },
+  "prettifySymbolsMode.adjustCursorMovement": true,
+  "editor.fontFamily": "'Fira Code', 'Droid Sans Mono', 'monospace', monospace, 'Droid Sans Fallback'",
+  "editor.fontLigatures": true,
+  "files.trimTrailingWhitespace": true,
+  "workbench.colorTheme": "Cobalt2",
+  "editor.tabSize": 2,
+  "prettier.jsxSingleQuote": true,
+  "prettier.semi": false,
+  "prettier.singleQuote": true
+}

+ 5 - 0
backend/example.env

@@ -0,0 +1,5 @@
+FRONTEND_URL="/graphql"
+PRISMA_ENDPOINT="http://prisma:4466"
+PRISMA_SECRET=
+APP_SECRET=
+PORT=4000

+ 5 - 6
backend/index.ts

@@ -10,7 +10,6 @@ import { authenticate } from './src/user/authenticate'
 import file from './src/file'
 import user from './src/user'
 import history from './src/history'
-//import google from './src/google'
 import training from './src/training'
 
 const resolvers = merge(
@@ -29,7 +28,7 @@ const typeDefs = importSchema('./schema.graphql').replace('scalar Upload', '')
 
 const corsOptions = {
   credentials: true,
-  origin: process.env.FRONTEND_URL
+  /*origin: process.env.FRONTEND_URL*/
 }
 
 const app = express()
@@ -43,15 +42,15 @@ const server = new ApolloServer({
   playground: true,
   context: (req: any) => ({
     ...req,
-    db
+    db,
   }),
   debug: false,
-  engine: { debugPrintReports: false }
+  engine: { debugPrintReports: false },
 } as ApolloServerExpressConfig)
-server.applyMiddleware({ app, cors: corsOptions, path: '/graphql' })
+server.applyMiddleware({ app, cors: corsOptions, path: '/' })
 
 app.listen({ port: process.env.PORT }, () => {
-  console.log(`Server ready 🚀!`)
+  console.log(`Server ready on port ${process.env.PORT} 🚀!`)
 })
 
 export default app

+ 19 - 16
docker-compose.yml

@@ -1,4 +1,4 @@
-version: "3.7"
+version: '3.7'
 
 services:
   frontend:
@@ -6,12 +6,12 @@ services:
     build:
       context: frontend
     volumes:
-      - "./frontend:/app"
-      - "./backend/database:/database"
-      - "frontend-nm:/app/node_modules"
-      - "/app/.next"
+      - './frontend:/app'
+      - './backend/database:/database'
+      - '/app/node_modules'
+      - '/app/.next'
     ports:
-      - "8800:3000"
+      - '127.0.0.1:8800:3000'
     environment:
       - NODE_ENV=development
     depends_on:
@@ -22,10 +22,10 @@ services:
     build:
       context: backend
     volumes:
-      - "./backend:/app"
-      - "/app/node_modules"
+      - './backend:/app'
+      - '/app/node_modules'
     ports:
-      - "127.0.0.1:8801:4000"
+      - '127.0.0.1:8801:4000'
     environment:
       - NODE_ENV=development
       - PRISMA_MANAGEMENT_API_SECRET=PrismaSecret
@@ -36,7 +36,7 @@ services:
     image: prismagraphql/prisma:1.34.10
     restart: always
     ports:
-      - "127.0.0.1:8846:4466"
+      - '127.0.0.1:8846:4466'
     environment:
       PRISMA_CONFIG: |
         port: 4466
@@ -56,10 +56,13 @@ services:
     environment:
       MYSQL_ROOT_PASSWORD: prisma
     volumes:
-      - mysql:/var/lib/mysql
-      - "./dbBackup:/backup"
+      - '/var/lib/mysql'
+      - './dbBackup:/backup'
 
-volumes:
-  mysql:
-  frontend-nm:
-  backend-nm:
+  proxy:
+    image: nginx:alpine
+    restart: always
+    ports:
+      - '8820:8820'
+    volumes:
+      - './proxy/nginx.conf:/etc/nginx/nginx.conf:ro'

+ 179 - 0
frontend/pages/styles.tsx

@@ -0,0 +1,179 @@
+import { AdminPage } from '../src/app'
+import theme from '../src/styles/theme'
+
+const StylePage = () => {
+  return (
+    <div className='page'>
+      <section className='presentation'>
+        <h1>This is the main title.</h1>
+        <p>
+          Lorem ipsum dolor sit amet consectetur adipisicing elit. Eaque, sed
+          perspiciatis. Molestias iusto, dolorem expedita deserunt saepe nostrum
+          ex voluptas, illo consequuntur inventore eius impedit.
+        </p>
+      </section>
+
+      <article>
+        <nav>
+          <h2>Mobile navigation</h2>
+          <ul>
+            <li>This is a mobile navigation item.</li>
+          </ul>
+        </nav>
+      </article>
+
+      <article className='program'>
+        <h2>Program title</h2>
+        <p>stuff</p>
+      </article>
+
+      <article>
+        <form>
+          <fieldset>
+            <label htmlFor='text'>text</label>
+            <input type='text' name='text' id='text' placeholder='text' />
+            <label htmlFor='search'>search</label>
+            <input
+              type='search'
+              name='search'
+              id='search'
+              placeholder='search'
+            />
+            <label htmlFor='password'>password</label>
+            <input
+              type='password'
+              name='password'
+              id='password'
+              placeholder='password'
+            />
+            <label htmlFor='tel'>tel</label>
+            <input type='tel' name='tel' id='tel' placeholder='tel' />
+            <label htmlFor='url'>url</label>
+            <input type='url' name='url' id='url' placeholder='url' />
+            <label htmlFor='email'>email</label>
+            <input type='email' name='email' id='email' placeholder='email' />
+            <label htmlFor='number'>number</label>
+            <input
+              type='number'
+              name='number'
+              id='number'
+              placeholder='number'
+            />
+            <label htmlFor='range'>range</label>
+            <input type='range' name='range' id='range' placeholder='range' />
+            <label htmlFor='date'>date</label>
+            <input type='date' name='date' id='date' placeholder='date' />
+            <label htmlFor='time'>time</label>
+            <input type='time' name='time' id='time' placeholder='time' />
+          </fieldset>
+          <fieldset>
+            <label htmlFor='checkbox'>checkbox</label>
+            <input
+              type='checkbox'
+              name='checkbox'
+              id='checkbox'
+              placeholder='checkbox'
+            />
+
+            <label htmlFor='radio'>radio</label>
+            <input
+              type='radio'
+              name='radio'
+              id='radio'
+              value='radio1'
+              placeholder='radio'
+            />
+            <label htmlFor='radio'>radio</label>
+            <input
+              type='radio'
+              name='radio'
+              id='radio'
+              value='radio2'
+              placeholder='radio'
+            />
+            <label htmlFor='radio'>radio</label>
+            <input
+              type='radio'
+              name='radio'
+              id='radio'
+              value='radio3'
+              placeholder='radio'
+            />
+            <label htmlFor='radio'>radio</label>
+            <input
+              type='radio'
+              name='radio'
+              id='radio'
+              value='radio4'
+              placeholder='radio'
+            />
+
+            <select name='select' id='select'>
+              <optgroup label='Option Group 1'>
+                <option value='option1-1'>1-1</option>
+                <option value='option1-2'>1-2</option>
+                <option value='option1-3'>1-3</option>
+              </optgroup>
+              <optgroup label='Option Group 2'>
+                <option value='option2-1'>2-1</option>
+                <option value='option2-2'>2-2</option>
+                <option value='option2-3'>2-3</option>
+              </optgroup>
+            </select>
+
+            <textarea
+              name='textarea'
+              id='textarea'
+              rows={8}
+              cols={50}
+              placeholder='textarea'
+            ></textarea>
+          </fieldset>
+          <button type='submit'>Submit</button>
+          <button type='reset'>Reset</button>
+        </form>
+      </article>
+
+      <style jsx>{`
+        .page {
+          position: relative;
+          background-image: linear-gradient(
+            to bottom,
+            #84cae7,
+            #84cae7 400px,
+            #ababab 400px,
+            #ebebeb 406px,
+            #ebebeb 406px
+          );
+        }
+        .presentation {
+          height: 300px;
+          padding: 2em 3em;
+          color: ${theme.colors.presentation};
+          background: ${theme.colors.presentationBackground};
+        }
+        .presentation h1 {
+          color: ${theme.colors.presentation};
+          font-size: 4rem;
+          line-height: 1;
+          margin: 0;
+          padding: 0;
+        }
+        .presentation p {
+          max-width: 40%;
+        }
+
+        .program {
+          position: absolute;
+          right: 3em;
+          width: 40%;
+          min-width: 300px;
+          background: ${theme.colors.background};
+          box-shadow: ${theme.bs};
+        }
+      `}</style>
+    </div>
+  )
+}
+
+export default StylePage

+ 11 - 12
frontend/src/app/components/AdminPage.tsx

@@ -2,8 +2,6 @@ import { FunctionComponent, useContext } from 'react'
 import AdminSideBar from './AdminSideBar'
 import { UserContext } from '../../user/hooks'
 import { LoginPage } from '../../user'
-import { Meta, Header, Footer } from '..'
-import GlobalStyle from '../../styles/global'
 
 const AdminPage: FunctionComponent = ({ children }) => {
   const { user } = useContext(UserContext)
@@ -16,18 +14,19 @@ const AdminPage: FunctionComponent = ({ children }) => {
   else content = <LoginPage />
 
   return (
-    <>
-      <Meta />
-
-      <Header />
+    <div className='admin-page'>
       <AdminSideBar />
-      <main>{content}</main>
-      <Footer />
+      <div className='admin-content'>{content}</div>
 
-      <style jsx global>
-        {GlobalStyle}
-      </style>
-    </>
+      <style jsx>{`
+        @media (min-width: 768px) {
+          .admin-page {
+            display: grid;
+            grid-template-columns: 300px 1fr;
+          }
+        }
+      `}</style>
+    </div>
   )
 }
 

+ 13 - 10
frontend/src/app/components/AdminSideBar.tsx

@@ -1,24 +1,27 @@
 import Link from 'next/link'
+import theme from '../../styles/theme'
 
 const AdminSideBar = () => {
   return (
     <nav className='admin-sidebar'>
       <ul className='admin-menu'>
-        <li className='admin-item'>
-          <Link href='training'>
-            <a>Trainings</a>
-          </Link>
-        </li>
-        <li className='admin-item'>
-          <Link href='user'>
-            <a>Users</a>
-          </Link>
-        </li>
+        <Link href='training'>
+          <a>
+            <li className='admin-item'>Trainings</li>
+          </a>
+        </Link>
+        <Link href='user'>
+          <a>
+            <li className='admin-item'>Users</li>
+          </a>
+        </Link>
       </ul>
 
       <style jsx>{`
         nav * {
           all: unset;
+          color: ${theme.colors.mobileNav};
+          background-color: ${theme.colors.mobileNavBackground};
         }
       `}</style>
     </nav>

+ 2 - 2
frontend/src/app/components/Logo.tsx

@@ -27,7 +27,7 @@ const Logo = () => (
           background-color: ${theme.colors.logoRed};
           border-radius: 50%;
           font-weight: 900;
-          padding-right: 0.2em;
+          padding-right: 0.1em;
         }
         .logo-circle::before {
           position: absolute;
@@ -37,7 +37,7 @@ const Logo = () => (
           height: 0.2em;
           border-radius: 50%;
           background-color: white;
-          right: 55%;
+          right: 40%;
           bottom: 55%;
         }
 

+ 6 - 6
frontend/src/app/components/Nav.tsx

@@ -149,26 +149,26 @@ const Nav = () => {
           nav :global(li::after) {
             content: '';
             display: block;
-            height: 1px;
+            height: 3px;
             left: 10%;
             right: 10%;
             transform: scale(0, 1);
             transition: all 300ms ease-in-out;
-            bottom: 0;
-            background-color: ${theme.colors.darkerblue};
+            margin-top: 0.4em;
+            background-color: ${theme.colors.links};
           }
 
           nav :global(li:hover::after) {
-            background-color: ${theme.colors.blue};
+            background-color: ${theme.colors.linksHighlight};
             transform: scale(1, 1);
           }
 
           nav :global(a) {
-            color: ${theme.colors.darkerblue};
+            color: ${theme.colors.links};
           }
 
           nav :global(a:hover) {
-            color: ${theme.colors.blue};
+            color: ${theme.colors.linksHighlight};
           }
         }
       `}</style>

+ 1 - 1
frontend/src/lib/apollo.js

@@ -24,7 +24,7 @@ const client = new ApolloClient({
       }
     }),
     new HttpLink({
-      uri: 'http://localhost:8801/graphql',
+      uri: '/graphql/',
       credentials: 'include',
       fetch,
     }),

+ 18 - 30
frontend/src/styles/global.ts

@@ -3,7 +3,8 @@ import css from 'styled-jsx/css'
 
 const GlobalStyle = css.global`
   /* normalize.css is imported in meta.js */
-  @import url('https://fonts.googleapis.com/css?family=Roboto+Mono:300|Roboto:300,900&display=swap');
+  /*@import url('https://fonts.googleapis.com/css?family=Roboto+Mono:300|Roboto:300,900&display=swap');*/
+  @import url('https://fonts.googleapis.com/css2?family=Exo+2:wght@700&family=Open+Sans&family=Source+Code+Pro&display=swap');
 
   /* Use border-box sizing instead of context-box.
    This includes border and padding in the calculation.
@@ -11,9 +12,9 @@ const GlobalStyle = css.global`
    Also define a default font. */
   html {
     box-sizing: border-box;
-    font-family: 'Roboto', sans-serif;
-    font-weight: 300;
-    /*font-size: 12px;*/
+    font-family: 'Open Sans', sans-serif;
+    font-size: 16px;
+    font-weight: 400;
   }
 
   *,
@@ -32,22 +33,11 @@ const GlobalStyle = css.global`
 
     min-height: 100vh;
 
-    background: ${theme.colors.offWhite};
-    color: ${theme.colors.black};
+    background: ${theme.colors.background};
+    color: ${theme.colors.color};
     box-shadow: ${theme.bs};
   }
 
-  #__next.admin {
-    grid-template-areas:
-      'header header'
-      'sidebar main'
-      'footer footer';
-  }
-
-  #__next.admin :global(nav.admin-sidebar) {
-    grid-area: sidebar;
-  }
-
   header {
     grid-area: header;
   }
@@ -65,18 +55,16 @@ const GlobalStyle = css.global`
   h3,
   h4,
   h5,
-  h6 {
-    font-weight: 900;
+  h6,
+  th {
+    font-family: 'Exo 2', sans-serif;
+    font-weight: 700;
     color: ${theme.colors.darkerblue};
   }
 
   /* Use monospace font for pre */
   pre {
-    font-family: 'Roboto Mono', monospace;
-  }
-
-  form label {
-    display: none;
+    font-family: 'Source Code Pro', monospace;
   }
 
   form input,
@@ -86,18 +74,18 @@ const GlobalStyle = css.global`
     width: 100%;
     margin: 0.8em auto;
     padding: 0.3em;
-    border: 2px solid ${theme.colors.darkerblue}00;
-    color: ${theme.colors.darkerblue};
-    background-color: ${theme.colors.darkerblue}27;
+    border: 2px solid ${theme.colors.formBackground}00;
+    color: ${theme.colors.formColor};
+    background-color: ${theme.colors.formBackground};
     transition: all 250ms ease-in-out;
   }
 
   form input:focus,
   form select:focus,
   form textbox:focus {
-    color: ${theme.colors.blue};
-    background-color: ${theme.colors.blue}15;
-    border-bottom: 2px solid ${theme.colors.blue}44;
+    color: ${theme.colors.formHighlight};
+    background-color: ${theme.colors.formHighlightBackground}55;
+    border-bottom: 2px solid ${theme.colors.formHighlightBackground}ff;
   }
 
   button {

+ 30 - 0
frontend/src/styles/theme.ts

@@ -14,6 +14,36 @@ const theme = {
     darkerblue: '#204567',
     offWhite: '#EDEDED',
     nav: '#393939e7',
+
+    color: '#424242',
+    background: '#ededed',
+    links: '#4e386b',
+    linksHighlight: '#6a4c93',
+    headerColor: '#424242',
+    headerBackground: '#efefef',
+    footerBackground: '#393939',
+    formColor: '#204567',
+    formBackground: '#b0d3f0',
+    formHighlight: '#ffca3a',
+    formHighlightBackground: '#f4f1bb',
+    mobileNav: '#efefef',
+    mobileNavBackground: '#393939e7',
+    presentation: '#e6ebe0',
+    presentationBackground: '#31afd4',
+  },
+  theme2: {
+    terraCotta: '#ed6a5a',
+    blond: '#f4f1bb',
+    brightCerulean: '#31afd4',
+    cambridgeBlue: '#9bc1bc',
+    platinum: '#e6ebe0',
+  },
+  theme3: {
+    sunsetOrange: '#ff595e',
+    sunGlow: '#ffca3a',
+    brightCerulean: '#31afd4',
+    yellowGreen: '#8ac926',
+    darkLavender: '#6a4c93',
   },
   maxWidth: '1000px',
   bs: '0 8px 12px 0 rgba(0,0,0,0.09)',

+ 36 - 0
proxy/nginx.conf

@@ -0,0 +1,36 @@
+worker_processes 1;
+
+events {
+  worker_connections 1024;
+}
+
+http{
+  sendfile on;
+
+  upstream docker-backend {
+    server backend:4000;
+  }
+
+  upstream docker-frontend {
+    server frontend:3000;
+  }
+
+  proxy_set_header   Host $host;
+  proxy_set_header   X-Real-IP $remote_addr;
+  proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
+  proxy_set_header   X-Forwarded-Host $server_name;
+
+  server {
+    listen 8820;
+
+    location / {
+      proxy_pass      http://frontend:3000;
+      proxy_redirect  off;
+    }
+
+    location /graphql/ {
+      proxy_pass      http://backend:4000/graphql;
+      proxy_redirect  off;
+    }
+  }
+}