diff --git a/README.md b/README.md index 5ab92d0..7336f6c 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,15 @@ # PhotoView -![screenshot](/screenshots/main-window.png) +**SERVER REWRITE. The api is currently being rewritten in Golang, use branch `old-nodejs-server` for the most stable release** + +![screenshot](./screenshots/main-window.png) ## Demo site + Visit https://photos.qpqp.dk/ -Username: __demo__ -Password: __demo__ +Username: **demo** +Password: **demo** ## Aim of the project @@ -14,7 +17,8 @@ The aim of this project is to make a simple and user-friendly photo gallery appl that is easy to host on a personal server, to easily view the photos located on that server. ## Main features -> The software is still in early development, and many of the following features, have not been implemented yet. + +> The software is still in early development, and many of the following features, may not have been fully implemented yet. - **Closely tied to the file system**. The website presents the images found on the local filesystem of the server, directories are mapped to albums. - **User management**. Each user is created along with a path on the local filesystem, photos within that path can be accessed by that user. @@ -47,7 +51,7 @@ If the endpoint or the port hasn't been changed in the `docker-compose.yml` file If everything is setup correctly, you should be presented with an initial setup wizard, when accessing the website the first time. -![Initial setup](/screenshots/initial-setup.png) +![Initial setup](./screenshots/initial-setup.png) Enter a new username and password. @@ -61,40 +65,23 @@ The photos will have to be scanned for the photos to show up, you can force a sc ## Setup development environment -> This projected is based of the [GrandStack](https://grandstack.io/) starter project. - ### Local setup -1. [Download Neo4j Desktop](https://neo4j.com/download/) -2. Install and open Neo4j Desktop. -3. Create a new DB by clicking "New Graph", and clicking "create local graph". -4. Set password to "letmein" (as suggested by `api/.env`), and click "Create". -5. Make sure that the default credentials in `api/.env` are used. Leave them as follows: `NEO4J_URI=bolt://localhost:7687 NEO4J_USER=neo4j NEO4J_PASSWORD=letmein` -6. Click "Manage". -7. Click "Plugins". -8. Find "APOC" and click "Install". -9. Click the "play" button at the top of left the screen, which should start the server. _(screenshot 2)_ -10. Wait until it says "RUNNING". -11. Proceed forward with the rest of the tutorial. +1. Install a local mysql server, and make a new database +2. Rename `/api/example.env` to `.env` and update the `MYSQL_URL` field +3. Rename `/ui/example.env` to `.env` ### [`/api`](./api) -#### Install dependencies - -```bash -(cd ./ui && npm install) -(cd ./api && npm install) -``` - #### Start API server ```bash -cd ./api && npm start +cd ./api && go run server/server.go ``` ### [`/ui`](./ui) -This will start the GraphQL API in the foreground, so in another terminal session start the UI development server: +The above command will start the GraphQL API in the foreground, so in another terminal session start the UI development server: #### Start UI server @@ -103,4 +90,4 @@ cd ./ui && npm start ``` The site can now be accessed at [localhost:1234](http://localhost:1234). -And the graphql playground at [localhost:4001/graphql](http://localhost:4001/graphql) +And the graphql playground at [localhost:4001](http://localhost:4001) diff --git a/ui/README.md b/ui/README.md index e5cc368..ad82fd5 100644 --- a/ui/README.md +++ b/ui/README.md @@ -1,76 +1,5 @@ -# GRANDstack Starter - UI - -This directory contains a React app (bootstrapped with Create React App) that uses Apollo Client to query a GraphQL API. - -The template app queries for a list of users from the GraphQL API and displays them in a list. - -## Quickstart - -Install dependencies: - -``` -npm install -``` - -Start the development server: - -``` -npm start -``` - -This will serve the app on `http://localhost:3000` - -![](img/default-app.png) - -## Configure - -Configuration is done with environment variables specified in `.env` - -Edit `.env` to specify the URI of the GraphQL API. The default is `http://localhost:4000` - -*.env* - -``` -REACT_APP_GRAPHQL_URI=http://localhost:4000 -``` - -## Build and Deploy (with Zeit Now) - -Be sure you've [deployed the GraphQL Service](../api#deployment) and have the URI of the GraphQL service you've deployed. - -### Configure - -Create `.env.production` to override `.env` used for local development. For example if you've already deployed the GraphQL service, specify the GraphQL service URI in `.env.production`. - -To take advantage of Zeit Now's free hosting tier you'll need to disable source maps (becuase the source map file size exceeds the maximum 1M for Now's free tier). Add `GENERATE_SOURCEMAP=false` to `.env.production`. - -So your `.env.production` should look like this (replacing your own GraphQL API URI): - -*.env.production* - -``` -REACT_APP_GRAPHQL_URI=https://grand-stack-starter-api-pqdeodpvok.now.sh -GENERATE_SOURCEMAP=false -``` - -### Deploy With Zeit Now - -To use [Zeit Now](https://zeit.co/now) you'll need to download Zeit Desktop if you haven't already. And then run: - -``` -now -``` - -this will deploy your React app to Zeit Now and give you a unqiue URL for your app. For example: https://grand-stack-starter-ui-pwntmhvvwr.now.sh - - -## Material-UI - -[Material-UI](https://material-ui.com/) components are included. See [the docs](https://material-ui.com/getting-started/usage/) for an overview of the components included. This starter example makes use of the Material-UI data Table (and related) components. - ## Create React App - This project was bootstrapped with [Create React App](https://github.com/facebookincubator/create-react-app). Below you will find some information on how to perform common tasks.
@@ -180,8 +109,8 @@ You can find the most recent version of this guide [here](https://github.com/fac Create React App is divided into two packages: -* `create-react-app` is a global command-line utility that you use to create new projects. -* `react-scripts` is a development dependency in the generated projects (including this one). +- `create-react-app` is a global command-line utility that you use to create new projects. +- `react-scripts` is a development dependency in the generated projects (including this one). You almost never need to update `create-react-app` itself: it delegates all the setup to `react-scripts`. @@ -220,8 +149,8 @@ my-app/ For the project to build, **these files must exist with exact filenames**: -* `public/index.html` is the page template; -* `src/index.js` is the JavaScript entry point. +- `public/index.html` is the page template; +- `src/index.js` is the JavaScript entry point. You can delete or rename the other files. @@ -282,12 +211,12 @@ You can refer [to the React documentation](https://reactjs.org/docs/react-dom.ht This project supports a superset of the latest JavaScript standard.
In addition to [ES6](https://github.com/lukehoban/es6features) syntax features, it also supports: -* [Exponentiation Operator](https://github.com/rwaldron/exponentiation-operator) (ES2016). -* [Async/await](https://github.com/tc39/ecmascript-asyncawait) (ES2017). -* [Object Rest/Spread Properties](https://github.com/sebmarkbage/ecmascript-rest-spread) (stage 3 proposal). -* [Dynamic import()](https://github.com/tc39/proposal-dynamic-import) (stage 3 proposal) -* [Class Fields and Static Properties](https://github.com/tc39/proposal-class-public-fields) (part of stage 3 proposal). -* [JSX](https://facebook.github.io/react/docs/introducing-jsx.html) and [Flow](https://flowtype.org/) syntax. +- [Exponentiation Operator](https://github.com/rwaldron/exponentiation-operator) (ES2016). +- [Async/await](https://github.com/tc39/ecmascript-asyncawait) (ES2017). +- [Object Rest/Spread Properties](https://github.com/sebmarkbage/ecmascript-rest-spread) (stage 3 proposal). +- [Dynamic import()](https://github.com/tc39/proposal-dynamic-import) (stage 3 proposal) +- [Class Fields and Static Properties](https://github.com/tc39/proposal-class-public-fields) (part of stage 3 proposal). +- [JSX](https://facebook.github.io/react/docs/introducing-jsx.html) and [Flow](https://flowtype.org/) syntax. Learn more about [different proposal stages](https://babeljs.io/docs/plugins/#presets-stage-x-experimental-presets-). @@ -295,9 +224,9 @@ While we recommend using experimental proposals with some caution, Facebook heav Note that **the project only includes a few ES6 [polyfills](https://en.wikipedia.org/wiki/Polyfill)**: -* [`Object.assign()`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) via [`object-assign`](https://github.com/sindresorhus/object-assign). -* [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) via [`promise`](https://github.com/then/promise). -* [`fetch()`](https://developer.mozilla.org/en/docs/Web/API/Fetch_API) via [`whatwg-fetch`](https://github.com/github/fetch). +- [`Object.assign()`](https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Object/assign) via [`object-assign`](https://github.com/sindresorhus/object-assign). +- [`Promise`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) via [`promise`](https://github.com/then/promise). +- [`fetch()`](https://developer.mozilla.org/en/docs/Web/API/Fetch_API) via [`whatwg-fetch`](https://github.com/github/fetch). If you use any other ES6+ features that need **runtime support** (such as `Array.from()` or `Symbol`), make sure you are including the appropriate polyfills manually, or that the browsers you are targeting already support them. @@ -309,8 +238,8 @@ To configure the syntax highlighting in your favorite text editor, head to the [ ## Displaying Lint Output in the Editor ->Note: this feature is available with `react-scripts@0.2.0` and higher.
->It also only works with npm 3 or higher. +> Note: this feature is available with `react-scripts@0.2.0` and higher.
+> It also only works with npm 3 or higher. Some editors, including Sublime Text, Atom, and Visual Studio Code, provide plugins for ESLint. @@ -345,19 +274,22 @@ Then add the block below to your `launch.json` file and put it inside the `.vsco ```json { "version": "0.2.0", - "configurations": [{ - "name": "Chrome", - "type": "chrome", - "request": "launch", - "url": "http://localhost:3000", - "webRoot": "${workspaceRoot}/src", - "sourceMapPathOverrides": { - "webpack:///src/*": "${webRoot}/*" + "configurations": [ + { + "name": "Chrome", + "type": "chrome", + "request": "launch", + "url": "http://localhost:3000", + "webRoot": "${workspaceRoot}/src", + "sourceMapPathOverrides": { + "webpack:///src/*": "${webRoot}/*" + } } - }] + ] } ``` ->Note: the URL may be different if you've made adjustments via the [HOST or PORT environment variables](#advanced-configuration). + +> Note: the URL may be different if you've made adjustments via the [HOST or PORT environment variables](#advanced-configuration). Start your app by running `npm start`, and start debugging in VS Code by pressing `F5` or by clicking the green debug icon. You can now write code, set breakpoints, make changes to the code, and debug your newly modified code—all from your editor. @@ -369,11 +301,11 @@ You would need to have [WebStorm](https://www.jetbrains.com/webstorm/) and [JetB In the WebStorm menu `Run` select `Edit Configurations...`. Then click `+` and select `JavaScript Debug`. Paste `http://localhost:3000` into the URL field and save the configuration. ->Note: the URL may be different if you've made adjustments via the [HOST or PORT environment variables](#advanced-configuration). +> Note: the URL may be different if you've made adjustments via the [HOST or PORT environment variables](#advanced-configuration). Start your app by running `npm start`, then press `^D` on macOS or `F9` on Windows and Linux or click the green debug icon to start debugging in WebStorm. -The same way you can debug your application in IntelliJ IDEA Ultimate, PhpStorm, PyCharm Pro, and RubyMine. +The same way you can debug your application in IntelliJ IDEA Ultimate, PhpStorm, PyCharm Pro, and RubyMine. ## Formatting Code Automatically @@ -391,9 +323,9 @@ Alternatively you may use `yarn`: yarn add husky lint-staged prettier ``` -* `husky` makes it easy to use githooks as if they are npm scripts. -* `lint-staged` allows us to run scripts on staged files in git. See this [blog post about lint-staged to learn more about it](https://medium.com/@okonetchnikov/make-linting-great-again-f3890e1ad6b8). -* `prettier` is the JavaScript formatter we will run before commits. +- `husky` makes it easy to use githooks as if they are npm scripts. +- `lint-staged` allows us to run scripts on staged files in git. See this [blog post about lint-staged to learn more about it](https://medium.com/@okonetchnikov/make-linting-great-again-f3890e1ad6b8). +- `prettier` is the JavaScript formatter we will run before commits. Now we can make sure every file is formatted correctly by adding a few lines to the `package.json` in the project root. @@ -461,7 +393,7 @@ For example: ### `Button.js` ```js -import React, { Component } from 'react'; +import React, { Component } from 'react' class Button extends Component { render() { @@ -469,23 +401,22 @@ class Button extends Component { } } -export default Button; // Don’t forget to use export default! +export default Button // Don’t forget to use export default! ``` ### `DangerButton.js` - ```js -import React, { Component } from 'react'; -import Button from './Button'; // Import a component from another file +import React, { Component } from 'react' +import Button from './Button' // Import a component from another file class DangerButton extends Component { render() { - return - ); + ) } } -export default App; +export default App ``` This will make `moduleA.js` and all its unique dependencies as a separate chunk that only loads after the user clicks the 'Load' button. @@ -568,13 +500,13 @@ This project setup uses [Webpack](https://webpack.js.org/) for handling all asse ### `Button.js` ```js -import React, { Component } from 'react'; -import './Button.css'; // Tell Webpack that Button.js uses these styles +import React, { Component } from 'react' +import './Button.css' // Tell Webpack that Button.js uses these styles class Button extends Component { render() { // You can use them as regular CSS styles - return
; + return
} } ``` @@ -608,11 +540,11 @@ becomes this: display: flex; -webkit-box-orient: horizontal; -webkit-box-direction: normal; - -ms-flex-direction: row; - flex-direction: row; + -ms-flex-direction: row; + flex-direction: row; -webkit-box-align: center; - -ms-flex-align: center; - align-items: center; + -ms-flex-align: center; + align-items: center; } ``` @@ -647,13 +579,13 @@ Then in `package.json`, add the following lines to `scripts`: "test": "react-scripts test --env=jsdom", ``` ->Note: To use a different preprocessor, replace `build-css` and `watch-css` commands according to your preprocessor’s documentation. +> Note: To use a different preprocessor, replace `build-css` and `watch-css` commands according to your preprocessor’s documentation. Now you can rename `src/App.css` to `src/App.scss` and run `npm run watch-css`. The watcher will find every Sass file in `src` subdirectories, and create a corresponding CSS file next to it, in our case overwriting `src/App.css`. Since `src/App.js` still imports `src/App.css`, the styles become a part of your application. You can now edit `src/App.scss`, and `src/App.css` will be regenerated. To share variables between Sass files, you can use Sass imports. For example, `src/App.scss` and other component style files could include `@import "./shared.scss";` with variable definitions. -To enable importing files without using relative paths, you can add the `--include-path` option to the command in `package.json`. +To enable importing files without using relative paths, you can add the `--include-path` option to the command in `package.json`. ``` "build-css": "node-sass-chokidar --include-path ./src --include-path ./node_modules src/ -o src/", @@ -704,13 +636,13 @@ Now running `npm start` and `npm run build` also builds Sass files. `node-sass` has been reported as having the following issues: -- `node-sass --watch` has been reported to have *performance issues* in certain conditions when used in a virtual machine or with docker. +- `node-sass --watch` has been reported to have _performance issues_ in certain conditions when used in a virtual machine or with docker. - Infinite styles compiling [#1939](https://github.com/facebookincubator/create-react-app/issues/1939) - `node-sass` has been reported as having issues with detecting new files in a directory [#1891](https://github.com/sass/node-sass/issues/1891) - `node-sass-chokidar` is used here as it addresses these issues. +`node-sass-chokidar` is used here as it addresses these issues. ## Adding Images, Fonts, and Files @@ -723,17 +655,17 @@ To reduce the number of requests to the server, importing images that are less t Here is an example: ```js -import React from 'react'; -import logo from './logo.png'; // Tell Webpack this JS file uses this image +import React from 'react' +import logo from './logo.png' // Tell Webpack this JS file uses this image -console.log(logo); // /logo.84287d09.png +console.log(logo) // /logo.84287d09.png function Header() { // Import result is the URL of your image - return Logo; + return Logo } -export default Header; +export default Header ``` This ensures that when the project is built, Webpack will correctly move the images into the build folder, and provide us with correct paths. @@ -755,7 +687,7 @@ An alternative way of handling static assets is described in the next section. ## Using the `public` Folder ->Note: this feature is available with `react-scripts@0.5.0` and higher. +> Note: this feature is available with `react-scripts@0.5.0` and higher. ### Changing the HTML @@ -770,18 +702,18 @@ Note that we normally encourage you to `import` assets in JavaScript files inste For example, see the sections on [adding a stylesheet](#adding-a-stylesheet) and [adding images and fonts](#adding-images-fonts-and-files). This mechanism provides a number of benefits: -* Scripts and stylesheets get minified and bundled together to avoid extra network requests. -* Missing files cause compilation errors instead of 404 errors for your users. -* Result filenames include content hashes so you don’t need to worry about browsers caching their old versions. +- Scripts and stylesheets get minified and bundled together to avoid extra network requests. +- Missing files cause compilation errors instead of 404 errors for your users. +- Result filenames include content hashes so you don’t need to worry about browsers caching their old versions. However there is an **escape hatch** that you can use to add an asset outside of the module system. -If you put a file into the `public` folder, it will **not** be processed by Webpack. Instead it will be copied into the build folder untouched. To reference assets in the `public` folder, you need to use a special variable called `PUBLIC_URL`. +If you put a file into the `public` folder, it will **not** be processed by Webpack. Instead it will be copied into the build folder untouched. To reference assets in the `public` folder, you need to use a special variable called `PUBLIC_URL`. Inside `index.html`, you can use it like this: ```html - + ``` Only files inside the `public` folder will be accessible by `%PUBLIC_URL%` prefix. If you need to use a file from `src` or `node_modules`, you’ll have to copy it there to explicitly specify your intention to make this file a part of the build. @@ -801,19 +733,19 @@ render() { Keep in mind the downsides of this approach: -* None of the files in `public` folder get post-processed or minified. -* Missing files will not be called at compilation time, and will cause 404 errors for your users. -* Result filenames won’t include content hashes so you’ll need to add query arguments or rename them every time they change. +- None of the files in `public` folder get post-processed or minified. +- Missing files will not be called at compilation time, and will cause 404 errors for your users. +- Result filenames won’t include content hashes so you’ll need to add query arguments or rename them every time they change. ### When to Use the `public` Folder Normally we recommend importing [stylesheets](#adding-a-stylesheet), [images, and fonts](#adding-images-fonts-and-files) from JavaScript. The `public` folder is useful as a workaround for a number of less common cases: -* You need a file with a specific name in the build output, such as [`manifest.webmanifest`](https://developer.mozilla.org/en-US/docs/Web/Manifest). -* You have thousands of images and need to dynamically reference their paths. -* You want to include a small script like [`pace.js`](http://github.hubspot.com/pace/docs/welcome/) outside of the bundled code. -* Some library may be incompatible with Webpack and you have no other option but to include it as a `