diff --git a/package-lock.json b/package-lock.json index 1ee136628..9e586df59 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1380,7 +1380,6 @@ "version": "7.13.9", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.13.9.tgz", "integrity": "sha512-aY2kU+xgJ3dJ1eU6FMB9EH8dIe8dmusF1xEku52joLvw6eAFN0AI+WxCLDnpev2LEejWBAy2sBvBOBAjI3zmvA==", - "dev": true, "requires": { "regenerator-runtime": "^0.13.4" }, @@ -1388,8 +1387,7 @@ "regenerator-runtime": { "version": "0.13.7", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz", - "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==", - "dev": true + "integrity": "sha512-a54FxoJDIr27pgf7IgeQGxmqUNYrcV338lf/6gH456HZ/PhX+5BcwHXG9ajESmwe6WRO0tAzRUrRmNONWgkrew==" } } }, @@ -10928,6 +10926,19 @@ "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true }, + "history": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/history/-/history-4.10.1.tgz", + "integrity": "sha512-36nwAD620w12kuzPAsyINPWJqlNbij+hpK1k9XRloDtym8mxzGYl2c17LnV6IAGB2Dmg4tEa7G7DlawS0+qjew==", + "requires": { + "@babel/runtime": "^7.1.2", + "loose-envify": "^1.2.0", + "resolve-pathname": "^3.0.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0", + "value-equal": "^1.0.1" + } + }, "hmac-drbg": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", @@ -14929,6 +14940,15 @@ "dom-walk": "^0.1.0" } }, + "mini-create-react-context": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.1.tgz", + "integrity": "sha512-YWCYEmd5CQeHGSAKrYvXgmzzkrvssZcuuQDDeqkT+PziKGMgE+0MCCtcKbROzocGBG1meBLl2FotlRwf4gAzbQ==", + "requires": { + "@babel/runtime": "^7.12.1", + "tiny-warning": "^1.0.3" + } + }, "minilog": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/minilog/-/minilog-2.0.8.tgz", @@ -18764,6 +18784,82 @@ "prop-types": "^15.5.7" } }, + "react-router": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.2.0.tgz", + "integrity": "sha512-smz1DUuFHRKdcJC0jobGo8cVbhO3x50tCL4icacOlcwDOEQPq4TMqwx3sY1TP+DvtTgz4nm3thuo7A+BK2U0Dw==", + "requires": { + "@babel/runtime": "^7.1.2", + "history": "^4.9.0", + "hoist-non-react-statics": "^3.1.0", + "loose-envify": "^1.3.1", + "mini-create-react-context": "^0.4.0", + "path-to-regexp": "^1.7.0", + "prop-types": "^15.6.2", + "react-is": "^16.6.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + }, + "dependencies": { + "hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "requires": { + "react-is": "^16.7.0" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + }, + "path-to-regexp": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", + "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "requires": { + "isarray": "0.0.1" + } + }, + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + } + } + }, + "react-router-dom": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-5.2.0.tgz", + "integrity": "sha512-gxAmfylo2QUjcwxI63RhQ5G85Qqt4voZpUXSEqCwykV0baaOTQDR1f0PmY8AELqIyVc0NEZUj0Gov5lNGcXgsA==", + "requires": { + "@babel/runtime": "^7.1.2", + "history": "^4.9.0", + "loose-envify": "^1.3.1", + "prop-types": "^15.6.2", + "react-router": "5.2.0", + "tiny-invariant": "^1.0.2", + "tiny-warning": "^1.0.0" + }, + "dependencies": { + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + } + } + }, "react-side-effect": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/react-side-effect/-/react-side-effect-1.1.5.tgz", @@ -20018,6 +20114,11 @@ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, + "resolve-pathname": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-pathname/-/resolve-pathname-3.0.0.tgz", + "integrity": "sha512-C7rARubxI8bXFNB/hqcp/4iUeIXJhJZvFPFPiSPRnhU5UPxzMFIl+2E6yY6c4k9giDJAhtV+enfA+G89N6Csng==" + }, "resolve-protobuf-schema": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz", @@ -25451,6 +25552,11 @@ "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==", "dev": true }, + "tiny-invariant": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/tiny-invariant/-/tiny-invariant-1.1.0.tgz", + "integrity": "sha512-ytxQvrb1cPc9WBEI/HSeYYoGD0kWnGEOR8RY6KomWLBVhqz0RgTwVO9dLrGz7dC+nN9llyI7OKAgRq8Vq4ZBSw==" + }, "tiny-sdf": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/tiny-sdf/-/tiny-sdf-1.0.2.tgz", @@ -25460,8 +25566,7 @@ "tiny-warning": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/tiny-warning/-/tiny-warning-1.0.3.tgz", - "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==", - "dev": true + "integrity": "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA==" }, "tinycolor2": { "version": "1.4.2", @@ -26408,6 +26513,11 @@ "integrity": "sha1-uBNbn7E3K94C/dU60dDM1t55j+4=", "dev": true }, + "value-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/value-equal/-/value-equal-1.0.1.tgz", + "integrity": "sha512-NOJ6JZCAWr0zlxZt+xqCHNTEKOsrks2HQd4MqhP1qy4z1SkbEP467eNx6TgDKXMvUOb+OENfJCZwM+16n7fRfw==" + }, "vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", diff --git a/package.json b/package.json index 5e0d35a20..cd7d01460 100644 --- a/package.json +++ b/package.json @@ -49,6 +49,7 @@ "express-http-proxy": "1.1.0", "lodash.defaults": "4.0.1", "react-helmet": "5.2.0", + "react-router-dom": "^5.2.0", "scratch-parser": "^5.0.0", "scratch-storage": "^0.5.1" }, diff --git a/src/routes-dev.json b/src/routes-dev.json index 4dc57aeaf..5d6755c26 100644 --- a/src/routes-dev.json +++ b/src/routes-dev.json @@ -4,5 +4,12 @@ "pattern": "^/components/?$", "view": "components/components", "title": "Components" + }, + { + "name": "studio", + "pattern": "^/studios-playground/\\d+(/projects|/curators|/activity|/comments)?/?(\\?.*)?$", + "routeAlias": "/studios-playground/?$", + "view": "studio/studio", + "title": "Studio Playground" } ] \ No newline at end of file diff --git a/src/views/studio/studio-activity.jsx b/src/views/studio/studio-activity.jsx new file mode 100644 index 000000000..70fb94aca --- /dev/null +++ b/src/views/studio/studio-activity.jsx @@ -0,0 +1,15 @@ +import React from 'react'; +import {useParams} from 'react-router-dom'; + +const StudioActivity = () => { + const {studioId} = useParams(); + + return ( +
+

Activity

+

Studio {studioId}

+
+ ); +}; + +export default StudioActivity; diff --git a/src/views/studio/studio-comments.jsx b/src/views/studio/studio-comments.jsx new file mode 100644 index 000000000..e4c84d490 --- /dev/null +++ b/src/views/studio/studio-comments.jsx @@ -0,0 +1,15 @@ +import React from 'react'; +import {useParams} from 'react-router-dom'; + +const StudioComments = () => { + const {studioId} = useParams(); + + return ( +
+

Comments

+

Studio {studioId}

+
+ ); +}; + +export default StudioComments; diff --git a/src/views/studio/studio-curators.jsx b/src/views/studio/studio-curators.jsx new file mode 100644 index 000000000..54751a224 --- /dev/null +++ b/src/views/studio/studio-curators.jsx @@ -0,0 +1,16 @@ +import React from 'react'; +import {useParams} from 'react-router-dom'; + +const StudioCurators = () => { + const {studioId} = useParams(); + + return ( +
+

Curators

+

Studio {studioId}

+ +
+ ); +}; + +export default StudioCurators; diff --git a/src/views/studio/studio-info.jsx b/src/views/studio/studio-info.jsx new file mode 100644 index 000000000..01381340b --- /dev/null +++ b/src/views/studio/studio-info.jsx @@ -0,0 +1,15 @@ +import React from 'react'; +import {useParams} from 'react-router-dom'; + +const StudioInfo = () => { + const {studioId} = useParams(); + + return ( +
+

Studio Info

+

Studio {studioId}

+
+ ); +}; + +export default StudioInfo; diff --git a/src/views/studio/studio-projects.jsx b/src/views/studio/studio-projects.jsx new file mode 100644 index 000000000..d4ec0eba5 --- /dev/null +++ b/src/views/studio/studio-projects.jsx @@ -0,0 +1,15 @@ +import React from 'react'; +import {useParams} from 'react-router-dom'; + +const StudioProjects = () => { + const {studioId} = useParams(); + + return ( +
+

Projects

+

Studio {studioId}

+
+ ); +}; + +export default StudioProjects; diff --git a/src/views/studio/studio-tab-nav.jsx b/src/views/studio/studio-tab-nav.jsx new file mode 100644 index 000000000..00e5d9854 --- /dev/null +++ b/src/views/studio/studio-tab-nav.jsx @@ -0,0 +1,41 @@ +import React from 'react'; +import {useRouteMatch, NavLink} from 'react-router-dom'; + +const StudioTabNav = () => { + const match = useRouteMatch(); + + return ( +
+ + Projects + +  |  + + Curators + +  |  + + Comments + +  |  + + Activity + +
+ ); +}; + +export default StudioTabNav; diff --git a/src/views/studio/studio.jsx b/src/views/studio/studio.jsx new file mode 100644 index 000000000..5a1ec7403 --- /dev/null +++ b/src/views/studio/studio.jsx @@ -0,0 +1,63 @@ +import React from 'react'; +import { + BrowserRouter as Router, + Switch, + Route, + Redirect, + useRouteMatch +} from 'react-router-dom'; + +import Page from '../../components/page/www/page.jsx'; +import render from '../../lib/render.jsx'; +import StudioTabNav from './studio-tab-nav.jsx'; +import StudioProjects from './studio-projects.jsx'; +import StudioInfo from './studio-info.jsx'; +import StudioCurators from './studio-curators.jsx'; +import StudioComments from './studio-comments.jsx'; +import StudioActivity from './studio-activity.jsx'; + +const StudioShell = () => { + const match = useRouteMatch(); + + return ( +
+ +
+ +
+ + + + + + + + + + + + {/* We can force /projects back to / this way */} + + + + + + +
+
+ ); +}; + +render( + + + + {/* Use variable studioPath to support /studio-playground/ or future route */} + + + + + + , + document.getElementById('app') +); diff --git a/webpack.config.js b/webpack.config.js index b1880bc1b..fea8669f9 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -14,7 +14,7 @@ const autoprefixer = require('autoprefixer'); let routes = require('./src/routes.json'); const templateConfig = require('./src/template-config.js'); // eslint-disable-line global-require -if (process.env.NODE_ENV !== 'production') { +if (process.env.NODE_ENV !== 'production' || process.env.SCRATCH_ENV === 'staging') { routes = routes.concat(require('./src/routes-dev.json')); // eslint-disable-line global-require }