diff --git a/picture-gallery-client/.eslintrc.json b/picture-gallery-client/.eslintrc.json
new file mode 100644
index 0000000..ef32c74
--- /dev/null
+++ b/picture-gallery-client/.eslintrc.json
@@ -0,0 +1,51 @@
+{
+ "env": {
+ "browser": true,
+ "es2021": true
+ },
+ "extends": [
+ "plugin:react/recommended",
+ "airbnb",
+ "plugin:prettier/recommended"
+ ],
+ "parser": "@typescript-eslint/parser",
+ "parserOptions": {
+ "ecmaFeatures": {
+ "jsx": true
+ },
+ "ecmaVersion": "latest",
+ "sourceType": "module"
+ },
+ "plugins": [
+ "react",
+ "@typescript-eslint"
+ ],
+ "ignorePatterns": [
+ "**/*.css"
+ ],
+ "rules": {
+ "import/extensions": [
+ "error",
+ "ignorePackages",
+ {
+ "ts": "never",
+ "tsx": "never"
+ }
+ ],
+ "react/jsx-filename-extension": [
+ 1,
+ {
+ "extensions": [
+ ".jsx",
+ ".tsx"
+ ]
+ }
+ ]
+ },
+ "settings": {
+ "import/resolver": {
+ "typescript": {
+ }
+ }
+ }
+}
diff --git a/picture-gallery-client/.prettierignore b/picture-gallery-client/.prettierignore
new file mode 100644
index 0000000..b7dab5e
--- /dev/null
+++ b/picture-gallery-client/.prettierignore
@@ -0,0 +1,2 @@
+node_modules
+build
\ No newline at end of file
diff --git a/picture-gallery-client/package-lock.json b/picture-gallery-client/package-lock.json
index cae6e51..b0fbcb0 100644
--- a/picture-gallery-client/package-lock.json
+++ b/picture-gallery-client/package-lock.json
@@ -27,6 +27,20 @@
"react-scripts": "5.0.0",
"typescript": "^4.6.3",
"web-vitals": "^2.1.4"
+ },
+ "devDependencies": {
+ "@typescript-eslint/eslint-plugin": "^5.18.0",
+ "@typescript-eslint/parser": "^5.18.0",
+ "eslint": "^8.13.0",
+ "eslint-config-airbnb": "^19.0.4",
+ "eslint-config-prettier": "^8.5.0",
+ "eslint-import-resolver-typescript": "^2.7.1",
+ "eslint-plugin-import": "^2.26.0",
+ "eslint-plugin-jsx-a11y": "^6.5.1",
+ "eslint-plugin-prettier": "^4.0.0",
+ "eslint-plugin-react": "^7.29.4",
+ "eslint-plugin-react-hooks": "^4.4.0",
+ "prettier": "^2.6.2"
}
},
"node_modules/@ampproject/remapping": {
@@ -7036,9 +7050,9 @@
}
},
"node_modules/eslint": {
- "version": "8.12.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.12.0.tgz",
- "integrity": "sha512-it1oBL9alZg1S8UycLm5YDMAkIhtH6FtAzuZs6YvoGVldWjbS08BkAdb/ymP9LlAyq8koANu32U7Ib/w+UNh8Q==",
+ "version": "8.13.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.13.0.tgz",
+ "integrity": "sha512-D+Xei61eInqauAyTJ6C0q6x9mx7kTUC1KZ0m0LSEexR0V+e94K12LmWX076ZIsldwfQ2RONdaJe0re0TRGQbRQ==",
"dependencies": {
"@eslint/eslintrc": "^1.2.1",
"@humanwhocodes/config-array": "^0.9.2",
@@ -7086,6 +7100,67 @@
"url": "https://opencollective.com/eslint"
}
},
+ "node_modules/eslint-config-airbnb": {
+ "version": "19.0.4",
+ "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-19.0.4.tgz",
+ "integrity": "sha512-T75QYQVQX57jiNgpF9r1KegMICE94VYwoFQyMGhrvc+lB8YF2E/M/PYDaQe1AJcWaEgqLE+ErXV1Og/+6Vyzew==",
+ "dev": true,
+ "dependencies": {
+ "eslint-config-airbnb-base": "^15.0.0",
+ "object.assign": "^4.1.2",
+ "object.entries": "^1.1.5"
+ },
+ "engines": {
+ "node": "^10.12.0 || ^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "peerDependencies": {
+ "eslint": "^7.32.0 || ^8.2.0",
+ "eslint-plugin-import": "^2.25.3",
+ "eslint-plugin-jsx-a11y": "^6.5.1",
+ "eslint-plugin-react": "^7.28.0",
+ "eslint-plugin-react-hooks": "^4.3.0"
+ }
+ },
+ "node_modules/eslint-config-airbnb-base": {
+ "version": "15.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz",
+ "integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==",
+ "dev": true,
+ "dependencies": {
+ "confusing-browser-globals": "^1.0.10",
+ "object.assign": "^4.1.2",
+ "object.entries": "^1.1.5",
+ "semver": "^6.3.0"
+ },
+ "engines": {
+ "node": "^10.12.0 || >=12.0.0"
+ },
+ "peerDependencies": {
+ "eslint": "^7.32.0 || ^8.2.0",
+ "eslint-plugin-import": "^2.25.2"
+ }
+ },
+ "node_modules/eslint-config-airbnb-base/node_modules/semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true,
+ "bin": {
+ "semver": "bin/semver.js"
+ }
+ },
+ "node_modules/eslint-config-prettier": {
+ "version": "8.5.0",
+ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz",
+ "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==",
+ "dev": true,
+ "bin": {
+ "eslint-config-prettier": "bin/cli.js"
+ },
+ "peerDependencies": {
+ "eslint": ">=7.0.0"
+ }
+ },
"node_modules/eslint-config-react-app": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-7.0.0.tgz",
@@ -7130,6 +7205,26 @@
"ms": "^2.1.1"
}
},
+ "node_modules/eslint-import-resolver-typescript": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-2.7.1.tgz",
+ "integrity": "sha512-00UbgGwV8bSgUv34igBDbTOtKhqoRMy9bFjNehT40bXg6585PNIct8HhXZ0SybqB9rWtXj9crcku8ndDn/gIqQ==",
+ "dev": true,
+ "dependencies": {
+ "debug": "^4.3.4",
+ "glob": "^7.2.0",
+ "is-glob": "^4.0.3",
+ "resolve": "^1.22.0",
+ "tsconfig-paths": "^3.14.1"
+ },
+ "engines": {
+ "node": ">=4"
+ },
+ "peerDependencies": {
+ "eslint": "*",
+ "eslint-plugin-import": "*"
+ }
+ },
"node_modules/eslint-module-utils": {
"version": "2.7.3",
"resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz",
@@ -7326,6 +7421,27 @@
"eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8"
}
},
+ "node_modules/eslint-plugin-prettier": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.0.0.tgz",
+ "integrity": "sha512-98MqmCJ7vJodoQK359bqQWaxOE0CS8paAz/GgjaZLyex4TTk3g9HugoO89EqWCrFiOqn9EVvcoo7gZzONCWVwQ==",
+ "dev": true,
+ "dependencies": {
+ "prettier-linter-helpers": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ },
+ "peerDependencies": {
+ "eslint": ">=7.28.0",
+ "prettier": ">=2.0.0"
+ },
+ "peerDependenciesMeta": {
+ "eslint-config-prettier": {
+ "optional": true
+ }
+ }
+ },
"node_modules/eslint-plugin-react": {
"version": "7.29.4",
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.29.4.tgz",
@@ -7809,6 +7925,12 @@
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
},
+ "node_modules/fast-diff": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz",
+ "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==",
+ "dev": true
+ },
"node_modules/fast-glob": {
"version": "3.2.11",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz",
@@ -13375,6 +13497,33 @@
"node": ">= 0.8.0"
}
},
+ "node_modules/prettier": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz",
+ "integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==",
+ "dev": true,
+ "bin": {
+ "prettier": "bin-prettier.js"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ },
+ "node_modules/prettier-linter-helpers": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
+ "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
+ "dev": true,
+ "dependencies": {
+ "fast-diff": "^1.1.2"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
"node_modules/pretty-bytes": {
"version": "5.6.0",
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz",
@@ -21559,9 +21708,9 @@
}
},
"eslint": {
- "version": "8.12.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.12.0.tgz",
- "integrity": "sha512-it1oBL9alZg1S8UycLm5YDMAkIhtH6FtAzuZs6YvoGVldWjbS08BkAdb/ymP9LlAyq8koANu32U7Ib/w+UNh8Q==",
+ "version": "8.13.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.13.0.tgz",
+ "integrity": "sha512-D+Xei61eInqauAyTJ6C0q6x9mx7kTUC1KZ0m0LSEexR0V+e94K12LmWX076ZIsldwfQ2RONdaJe0re0TRGQbRQ==",
"requires": {
"@eslint/eslintrc": "^1.2.1",
"@humanwhocodes/config-array": "^0.9.2",
@@ -21676,6 +21825,44 @@
}
}
},
+ "eslint-config-airbnb": {
+ "version": "19.0.4",
+ "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-19.0.4.tgz",
+ "integrity": "sha512-T75QYQVQX57jiNgpF9r1KegMICE94VYwoFQyMGhrvc+lB8YF2E/M/PYDaQe1AJcWaEgqLE+ErXV1Og/+6Vyzew==",
+ "dev": true,
+ "requires": {
+ "eslint-config-airbnb-base": "^15.0.0",
+ "object.assign": "^4.1.2",
+ "object.entries": "^1.1.5"
+ }
+ },
+ "eslint-config-airbnb-base": {
+ "version": "15.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz",
+ "integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==",
+ "dev": true,
+ "requires": {
+ "confusing-browser-globals": "^1.0.10",
+ "object.assign": "^4.1.2",
+ "object.entries": "^1.1.5",
+ "semver": "^6.3.0"
+ },
+ "dependencies": {
+ "semver": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
+ "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "dev": true
+ }
+ }
+ },
+ "eslint-config-prettier": {
+ "version": "8.5.0",
+ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz",
+ "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==",
+ "dev": true,
+ "requires": {}
+ },
"eslint-config-react-app": {
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/eslint-config-react-app/-/eslint-config-react-app-7.0.0.tgz",
@@ -21716,6 +21903,19 @@
}
}
},
+ "eslint-import-resolver-typescript": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-2.7.1.tgz",
+ "integrity": "sha512-00UbgGwV8bSgUv34igBDbTOtKhqoRMy9bFjNehT40bXg6585PNIct8HhXZ0SybqB9rWtXj9crcku8ndDn/gIqQ==",
+ "dev": true,
+ "requires": {
+ "debug": "^4.3.4",
+ "glob": "^7.2.0",
+ "is-glob": "^4.0.3",
+ "resolve": "^1.22.0",
+ "tsconfig-paths": "^3.14.1"
+ }
+ },
"eslint-module-utils": {
"version": "2.7.3",
"resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz",
@@ -21857,6 +22057,15 @@
"minimatch": "^3.0.4"
}
},
+ "eslint-plugin-prettier": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.0.0.tgz",
+ "integrity": "sha512-98MqmCJ7vJodoQK359bqQWaxOE0CS8paAz/GgjaZLyex4TTk3g9HugoO89EqWCrFiOqn9EVvcoo7gZzONCWVwQ==",
+ "dev": true,
+ "requires": {
+ "prettier-linter-helpers": "^1.0.0"
+ }
+ },
"eslint-plugin-react": {
"version": "7.29.4",
"resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.29.4.tgz",
@@ -22117,6 +22326,12 @@
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
},
+ "fast-diff": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz",
+ "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==",
+ "dev": true
+ },
"fast-glob": {
"version": "3.2.11",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz",
@@ -25977,6 +26192,21 @@
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
"integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g=="
},
+ "prettier": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz",
+ "integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==",
+ "dev": true
+ },
+ "prettier-linter-helpers": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz",
+ "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==",
+ "dev": true,
+ "requires": {
+ "fast-diff": "^1.1.2"
+ }
+ },
"pretty-bytes": {
"version": "5.6.0",
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz",
diff --git a/picture-gallery-client/package.json b/picture-gallery-client/package.json
index a8f4601..8b9b17c 100644
--- a/picture-gallery-client/package.json
+++ b/picture-gallery-client/package.json
@@ -28,7 +28,10 @@
"start-client": "react-scripts start",
"build-client": "react-scripts build",
"test-client": "react-scripts test",
- "eject-client": "react-scripts eject"
+ "eject-client": "react-scripts eject",
+ "lint": "eslint src/*",
+ "lint:fix": "eslint --fix src/*",
+ "format": "prettier --write \"**/*.+(ts|tsx)\""
},
"eslintConfig": {
"extends": [
@@ -47,5 +50,19 @@
"last 1 firefox version",
"last 1 safari version"
]
+ },
+ "devDependencies": {
+ "@typescript-eslint/eslint-plugin": "^5.18.0",
+ "@typescript-eslint/parser": "^5.18.0",
+ "eslint": "^8.13.0",
+ "eslint-config-airbnb": "^19.0.4",
+ "eslint-config-prettier": "^8.5.0",
+ "eslint-import-resolver-typescript": "^2.7.1",
+ "eslint-plugin-import": "^2.26.0",
+ "eslint-plugin-jsx-a11y": "^6.5.1",
+ "eslint-plugin-prettier": "^4.0.0",
+ "eslint-plugin-react": "^7.29.4",
+ "eslint-plugin-react-hooks": "^4.4.0",
+ "prettier": "^2.6.2"
}
}
diff --git a/picture-gallery-client/src/ImageGallery/ImageGallery.tsx b/picture-gallery-client/src/ImageGallery/ImageGallery.tsx
index 3228a7e..e6a4bd6 100644
--- a/picture-gallery-client/src/ImageGallery/ImageGallery.tsx
+++ b/picture-gallery-client/src/ImageGallery/ImageGallery.tsx
@@ -1,17 +1,22 @@
-import PhotoAlbum, {Photo} from "react-photo-album";
+import PhotoAlbum, { Photo } from "react-photo-album";
-function ImageGallery({images}: { images: Photo[] }) {
- // For all kind of settings see:
- // https://react-photo-album.com/examples/playground
- // https://codesandbox.io/s/github/igordanchenko/react-photo-album/tree/main/examples/playground
+function ImageGallery({ images }: { images: Photo[] }) {
+ // For all kind of settings see:
+ // https://react-photo-album.com/examples/playground
+ // https://codesandbox.io/s/github/igordanchenko/react-photo-album/tree/main/examples/playground
- return (
- <>
- {images.length === 0
- ?
No images available. You may want to add images in your root directory.
- : }
- >
- );
+ return (
+ <>
+ {images.length === 0 ? (
+
+ No images available. You may want to add images in your root
+ directory.
+
+ ) : (
+
+ )}
+ >
+ );
}
export default ImageGallery;
diff --git a/picture-gallery-client/src/ImageGallery/ImageGalleryAppBar.tsx b/picture-gallery-client/src/ImageGallery/ImageGalleryAppBar.tsx
index ff0337f..af36616 100644
--- a/picture-gallery-client/src/ImageGallery/ImageGalleryAppBar.tsx
+++ b/picture-gallery-client/src/ImageGallery/ImageGalleryAppBar.tsx
@@ -4,25 +4,33 @@ import MenuIcon from "@mui/icons-material/Menu";
import Typography from "@mui/material/Typography";
import AppBar from "../MuiLayout/AppBar";
-function ImageGalleryAppBar({open, drawerWidth, onDrawerOpenClick}: { open: boolean, drawerWidth: number, onDrawerOpenClick: () => void }) {
- return (
-
-
-
-
-
-
- {process.env.TITLE ?? "Image Gallery"}
-
-
-
- )
+function ImageGalleryAppBar({
+ open,
+ drawerWidth,
+ onDrawerOpenClick,
+}: {
+ open: boolean;
+ drawerWidth: number;
+ onDrawerOpenClick: () => void;
+}) {
+ return (
+
+
+
+
+
+
+ {process.env.TITLE ?? "Image Gallery"}
+
+
+
+ );
}
-export default ImageGalleryAppBar;
\ No newline at end of file
+export default ImageGalleryAppBar;
diff --git a/picture-gallery-client/src/ImageGallery/ImageGalleryDrawer.tsx b/picture-gallery-client/src/ImageGallery/ImageGalleryDrawer.tsx
index 7777d38..7f1e488 100644
--- a/picture-gallery-client/src/ImageGallery/ImageGalleryDrawer.tsx
+++ b/picture-gallery-client/src/ImageGallery/ImageGalleryDrawer.tsx
@@ -3,100 +3,150 @@ import DrawerHeader from "../MuiLayout/DrawerHeader";
import IconButton from "@mui/material/IconButton";
import ChevronLeftIcon from "@mui/icons-material/ChevronLeft";
import ChevronRightIcon from "@mui/icons-material/ChevronRight";
-import FolderIcon from '@mui/icons-material/Folder';
-import FolderOpenIcon from '@mui/icons-material/FolderOpen';
+import FolderIcon from "@mui/icons-material/Folder";
+import FolderOpenIcon from "@mui/icons-material/FolderOpen";
import Divider from "@mui/material/Divider";
-import {useTheme} from "@mui/material/styles";
-import {TreeItem, TreeView} from '@mui/lab';
-import {Folders} from "./models";
-import {useLocation, useNavigate} from "react-router-dom";
-import {useState} from "react";
+import { useTheme } from "@mui/material/styles";
+import { TreeItem, TreeView } from "@mui/lab";
+import { Folders } from "./models";
+import { useLocation, useNavigate } from "react-router-dom";
+import { useState } from "react";
function getDefaultExpanded(pathname: string): string[] {
- const pathParts = []
- let curPathName = pathname.substring(0, pathname.lastIndexOf("/"))
- while (curPathName.length > 0) {
- pathParts.push(curPathName)
- curPathName = curPathName.substring(0, curPathName.lastIndexOf("/"))
- }
- return pathParts
+ const pathParts = [];
+ let curPathName = pathname.substring(0, pathname.lastIndexOf("/"));
+ while (curPathName.length > 0) {
+ pathParts.push(curPathName);
+ curPathName = curPathName.substring(0, curPathName.lastIndexOf("/"));
+ }
+ return pathParts;
}
-function generateTreeViewChildren(folders: Folders[], navigateAndToggleExpand: (path: string, navigationAllowed: boolean) => void) {
- return (<>
- {folders.map(f => {
- const label = f.numberOfFiles === 0 ? f.name : `${f.name} - (${f.numberOfFiles})`;
- const containsImages = f.numberOfFiles > 0;
- if (f.children.length === 0) {
- return ( navigateAndToggleExpand(f.fullPath, containsImages)}/>)
- }
- return (
- navigateAndToggleExpand(f.fullPath, containsImages)}>
- {generateTreeViewChildren(f.children, navigateAndToggleExpand)}
-
- )
- })}
- >)
-}
-
-function GenerateTreeView({root}: { root: Folders }) {
- const location = useLocation();
- const navigate = useNavigate();
- const [expanded, setExpanded] = useState(getDefaultExpanded(location.pathname))
-
- const toggleExpanded = (path: string) => {
- if (expanded.includes(path)) {
- setExpanded(expanded.filter(p => p !== path))
- } else {
- setExpanded([path, ...expanded])
+function generateTreeViewChildren(
+ folders: Folders[],
+ navigateAndToggleExpand: (path: string, navigationAllowed: boolean) => void
+) {
+ return (
+ <>
+ {folders.map((f) => {
+ const label =
+ f.numberOfFiles === 0 ? f.name : `${f.name} - (${f.numberOfFiles})`;
+ const containsImages = f.numberOfFiles > 0;
+ if (f.children.length === 0) {
+ return (
+
+ navigateAndToggleExpand(f.fullPath, containsImages)
+ }
+ />
+ );
}
- }
-
- const navigateAndToggleExpand = (path: string, navigationAllowed: boolean) => {
- if (!navigationAllowed || location.pathname === path) {
- toggleExpanded(path);
- return;
- }
- toggleExpanded(path);
- navigate(path)
- }
-
- return (
- }
- defaultExpandIcon={}
- expanded={expanded}
- >
- navigate(root.fullPath)}/>
- {root.children.length > 0 ? generateTreeViewChildren(root.children, navigateAndToggleExpand) : <>>}
-
- )
+ return (
+ navigateAndToggleExpand(f.fullPath, containsImages)}
+ >
+ {generateTreeViewChildren(f.children, navigateAndToggleExpand)}
+
+ );
+ })}
+ >
+ );
}
-function ImageGalleryDrawer({open, drawerWidth, folder, onDrawerCloseClick}: { open: boolean, drawerWidth: number, folder: Folders, onDrawerCloseClick: () => void }) {
- const theme = useTheme();
- return ((
+ getDefaultExpanded(location.pathname)
+ );
+
+ const toggleExpanded = (path: string) => {
+ if (expanded.includes(path)) {
+ setExpanded(expanded.filter((p) => p !== path));
+ } else {
+ setExpanded([path, ...expanded]);
+ }
+ };
+
+ const navigateAndToggleExpand = (
+ path: string,
+ navigationAllowed: boolean
+ ) => {
+ if (!navigationAllowed || location.pathname === path) {
+ toggleExpanded(path);
+ return;
+ }
+ toggleExpanded(path);
+ navigate(path);
+ };
+
+ return (
+ }
+ defaultExpandIcon={}
+ expanded={expanded}
>
-
-
- {theme.direction === 'ltr' ? : }
-
-
-
-
- )
+ navigate(root.fullPath)}
+ />
+ {root.children.length > 0 ? (
+ generateTreeViewChildren(root.children, navigateAndToggleExpand)
+ ) : (
+ <>>
+ )}
+
+ );
}
-export default ImageGalleryDrawer;
\ No newline at end of file
+function ImageGalleryDrawer({
+ open,
+ drawerWidth,
+ folder,
+ onDrawerCloseClick,
+}: {
+ open: boolean;
+ drawerWidth: number;
+ folder: Folders;
+ onDrawerCloseClick: () => void;
+}) {
+ const theme = useTheme();
+ return (
+
+
+
+ {theme.direction === "ltr" ? (
+
+ ) : (
+
+ )}
+
+
+
+
+
+ );
+}
+
+export default ImageGalleryDrawer;
diff --git a/picture-gallery-client/src/ImageGallery/models.ts b/picture-gallery-client/src/ImageGallery/models.ts
index a280f54..e2206cd 100644
--- a/picture-gallery-client/src/ImageGallery/models.ts
+++ b/picture-gallery-client/src/ImageGallery/models.ts
@@ -1,6 +1,6 @@
export interface Folders {
- name: string
- fullPath: string
- numberOfFiles: number
- children: Folders[]
+ name: string;
+ fullPath: string;
+ numberOfFiles: number;
+ children: Folders[];
}
diff --git a/picture-gallery-client/src/ImageGalleryLayout.tsx b/picture-gallery-client/src/ImageGalleryLayout.tsx
index d132420..e616e08 100644
--- a/picture-gallery-client/src/ImageGalleryLayout.tsx
+++ b/picture-gallery-client/src/ImageGalleryLayout.tsx
@@ -1,9 +1,9 @@
-import {useEffect, useState} from "react";
-import {Photo} from "react-photo-album";
-import Box from '@mui/material/Box';
-import CssBaseline from '@mui/material/CssBaseline';
-import {Folders} from "./ImageGallery/models";
-import {useLocation} from "react-router-dom";
+import React, { useEffect, useState } from "react";
+import { Photo } from "react-photo-album";
+import Box from "@mui/material/Box";
+import CssBaseline from "@mui/material/CssBaseline";
+import { useLocation } from "react-router-dom";
+import { Folders } from "./ImageGallery/models";
import ImageGalleryAppBar from "./ImageGallery/ImageGalleryAppBar";
import DrawerHeader from "./MuiLayout/DrawerHeader";
import ImageGalleryDrawer from "./ImageGallery/ImageGalleryDrawer";
@@ -13,43 +13,56 @@ import Main from "./MuiLayout/Main";
const drawerWidth = 240;
function ImageGalleryLayout() {
- const [open, setOpen] = useState(true);
- const [folders, setFolders] = useState({name: "Home", fullPath: "/", numberOfFiles: 0, children: []});
- const location = useLocation();
+ const [open, setOpen] = useState(true);
+ const [folders, setFolders] = useState({
+ name: "Home",
+ fullPath: "/",
+ numberOfFiles: 0,
+ children: [],
+ });
+ const location = useLocation();
- const handleDrawerOpen = () => {
- setOpen(true);
- };
+ const handleDrawerOpen = () => {
+ setOpen(true);
+ };
- const handleDrawerClose = () => {
- setOpen(false);
- };
- const [images, setImages] = useState([]);
+ const handleDrawerClose = () => {
+ setOpen(false);
+ };
+ const [images, setImages] = useState([]);
- useEffect(() => {
- fetch(`/api/${location.pathname}`)
- .then((res) => res.json())
- .then((data) => setImages(data.images));
- }, [location.pathname]);
+ useEffect(() => {
+ fetch(`/api/${location.pathname}`)
+ .then((res) => res.json())
+ .then((data) => setImages(data.images));
+ }, [location.pathname]);
- useEffect(() => {
- fetch("/directories")
- .then((res) => res.json())
- .then((data) => setFolders(data));
- }, []);
+ useEffect(() => {
+ fetch("/directories")
+ .then((res) => res.json())
+ .then((data) => setFolders(data));
+ }, []);
- return (
-
-
-
-
-
-
-
-
-
-
- );
+ return (
+
+
+
+
+
+
+
+
+
+ );
}
export default ImageGalleryLayout;
diff --git a/picture-gallery-client/src/MuiLayout/AppBar.tsx b/picture-gallery-client/src/MuiLayout/AppBar.tsx
index d5df586..605cec8 100644
--- a/picture-gallery-client/src/MuiLayout/AppBar.tsx
+++ b/picture-gallery-client/src/MuiLayout/AppBar.tsx
@@ -1,24 +1,24 @@
-import {styled} from "@mui/material/styles";
+import { styled } from "@mui/material/styles";
import MuiAppBar from "@mui/material/AppBar";
const AppBar = styled(MuiAppBar, {
- shouldForwardProp: (prop) => prop !== 'open',
+ shouldForwardProp: (prop) => prop !== "open",
})<{
- open?: boolean;
- drawerwidth: number;
-}>(({theme, open, drawerwidth}) => ({
- transition: theme.transitions.create(['margin', 'width'], {
- easing: theme.transitions.easing.sharp,
- duration: theme.transitions.duration.leavingScreen,
- }),
- ...(open && {
- width: `calc(100% - ${drawerwidth}px)`,
- marginLeft: `${drawerwidth}px`,
- transition: theme.transitions.create(['margin', 'width'], {
- easing: theme.transitions.easing.easeOut,
- duration: theme.transitions.duration.enteringScreen,
- }),
+ open?: boolean;
+ drawerwidth: number;
+}>(({ theme, open, drawerwidth }) => ({
+ transition: theme.transitions.create(["margin", "width"], {
+ easing: theme.transitions.easing.sharp,
+ duration: theme.transitions.duration.leavingScreen,
+ }),
+ ...(open && {
+ width: `calc(100% - ${drawerwidth}px)`,
+ marginLeft: `${drawerwidth}px`,
+ transition: theme.transitions.create(["margin", "width"], {
+ easing: theme.transitions.easing.easeOut,
+ duration: theme.transitions.duration.enteringScreen,
}),
+ }),
}));
-export default AppBar;
\ No newline at end of file
+export default AppBar;
diff --git a/picture-gallery-client/src/MuiLayout/DrawerHeader.tsx b/picture-gallery-client/src/MuiLayout/DrawerHeader.tsx
index b3ffc0b..12b437b 100644
--- a/picture-gallery-client/src/MuiLayout/DrawerHeader.tsx
+++ b/picture-gallery-client/src/MuiLayout/DrawerHeader.tsx
@@ -1,12 +1,12 @@
-import {styled} from "@mui/material/styles";
+import { styled } from "@mui/material/styles";
-const DrawerHeader = styled('div')(({theme}) => ({
- display: 'flex',
- alignItems: 'center',
- padding: theme.spacing(0, 1),
- // necessary for content to be below app bar
- ...theme.mixins.toolbar,
- justifyContent: 'flex-end',
+const DrawerHeader = styled("div")(({ theme }) => ({
+ display: "flex",
+ alignItems: "center",
+ padding: theme.spacing(0, 1),
+ // necessary for content to be below app bar
+ ...theme.mixins.toolbar,
+ justifyContent: "flex-end",
}));
-export default DrawerHeader;
\ No newline at end of file
+export default DrawerHeader;
diff --git a/picture-gallery-client/src/MuiLayout/Main.tsx b/picture-gallery-client/src/MuiLayout/Main.tsx
index 6f8da51..4a627cb 100644
--- a/picture-gallery-client/src/MuiLayout/Main.tsx
+++ b/picture-gallery-client/src/MuiLayout/Main.tsx
@@ -1,25 +1,23 @@
-import {styled} from "@mui/material/styles";
+import { styled } from "@mui/material/styles";
-const Main = styled('main', {shouldForwardProp: (prop) => prop !== 'open'})<{
- open?: boolean;
- drawerwidth: number;
-}>(
- ({theme, open, drawerwidth}) => ({
- flexGrow: 1,
- padding: theme.spacing(3),
- transition: theme.transitions.create('margin', {
- easing: theme.transitions.easing.sharp,
- duration: theme.transitions.duration.leavingScreen,
- }),
- marginLeft: `-${drawerwidth}px`,
- ...(open && {
- transition: theme.transitions.create('margin', {
- easing: theme.transitions.easing.easeOut,
- duration: theme.transitions.duration.enteringScreen,
- }),
- marginLeft: 0,
- }),
+const Main = styled("main", { shouldForwardProp: (prop) => prop !== "open" })<{
+ open?: boolean;
+ drawerwidth: number;
+}>(({ theme, open, drawerwidth }) => ({
+ flexGrow: 1,
+ padding: theme.spacing(3),
+ transition: theme.transitions.create("margin", {
+ easing: theme.transitions.easing.sharp,
+ duration: theme.transitions.duration.leavingScreen,
+ }),
+ marginLeft: `-${drawerwidth}px`,
+ ...(open && {
+ transition: theme.transitions.create("margin", {
+ easing: theme.transitions.easing.easeOut,
+ duration: theme.transitions.duration.enteringScreen,
}),
-);
+ marginLeft: 0,
+ }),
+}));
-export default Main;
\ No newline at end of file
+export default Main;
diff --git a/picture-gallery-client/src/index.tsx b/picture-gallery-client/src/index.tsx
index ef4a76c..2d645eb 100644
--- a/picture-gallery-client/src/index.tsx
+++ b/picture-gallery-client/src/index.tsx
@@ -1,16 +1,18 @@
-import React from 'react';
+import React from "react";
import ReactDOM from "react-dom/client";
-import './index.css';
-import reportWebVitals from './reportWebVitals';
+import "./index.css";
+import { BrowserRouter } from "react-router-dom";
+import reportWebVitals from "./reportWebVitals";
import ImageGalleryLayout from "./ImageGalleryLayout";
-import {BrowserRouter} from "react-router-dom";
-const root = ReactDOM.createRoot(document.getElementById('root') as HTMLElement)
+const root = ReactDOM.createRoot(
+ document.getElementById("root") as HTMLElement
+);
root.render(
-
-
-
-)
+
+
+
+);
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
diff --git a/picture-gallery-client/src/react-app-env.d.ts b/picture-gallery-client/src/react-app-env.d.ts
index ece12df..6431bc5 100644
--- a/picture-gallery-client/src/react-app-env.d.ts
+++ b/picture-gallery-client/src/react-app-env.d.ts
@@ -1 +1 @@
-///
+///
diff --git a/picture-gallery-client/src/reportWebVitals.ts b/picture-gallery-client/src/reportWebVitals.ts
index 49a2a16..5fa3583 100644
--- a/picture-gallery-client/src/reportWebVitals.ts
+++ b/picture-gallery-client/src/reportWebVitals.ts
@@ -1,8 +1,8 @@
-import { ReportHandler } from 'web-vitals';
+import { ReportHandler } from "web-vitals";
const reportWebVitals = (onPerfEntry?: ReportHandler) => {
if (onPerfEntry && onPerfEntry instanceof Function) {
- import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
+ import("web-vitals").then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
getCLS(onPerfEntry);
getFID(onPerfEntry);
getFCP(onPerfEntry);
diff --git a/picture-gallery-client/src/setupTests.ts b/picture-gallery-client/src/setupTests.ts
index 8f2609b..1dd407a 100644
--- a/picture-gallery-client/src/setupTests.ts
+++ b/picture-gallery-client/src/setupTests.ts
@@ -2,4 +2,4 @@
// allows you to do things like:
// expect(element).toHaveTextContent(/react/i)
// learn more: https://github.com/testing-library/jest-dom
-import '@testing-library/jest-dom';
+import "@testing-library/jest-dom";