From d8dfd515dd4075804e571befbbd751c3036b6e99 Mon Sep 17 00:00:00 2001 From: GauravSingh75 <55052983+GauravSingh9356@users.noreply.github.com> Date: Mon, 28 Feb 2022 23:58:21 +0530 Subject: [PATCH] modal feature added after custom URL is generated --- frontend/package-lock.json | 81 ++++++++++ frontend/package.json | 1 + frontend/src/App.scss | 314 +++++++++++++++++++------------------ frontend/src/App.tsx | 208 +++++++++++++----------- 4 files changed, 355 insertions(+), 249 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index ff29aa8..8d7122a 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -25,6 +25,7 @@ "node-sass": "^7.0.0", "react": "^17.0.2", "react-dom": "^17.0.2", + "react-responsive-modal": "^6.2.0", "react-scripts": "5.0.0", "react-simple-code-editor": "^0.11.0", "react-syntax-highlighter": "^15.4.5", @@ -1851,6 +1852,25 @@ "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==" }, + "node_modules/@bedrock-layout/use-forwarded-ref": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@bedrock-layout/use-forwarded-ref/-/use-forwarded-ref-1.1.12.tgz", + "integrity": "sha512-FIQlXhgwB+hh3fUm0TkFjL3SFLqm0VHYhEOZhoFGhYn3n0ZOz/zSsxFH/m67GX+Q3/A5D3ox/1Y+phAMUw2L7g==", + "dependencies": { + "@bedrock-layout/use-stateful-ref": "^1.2.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17" + } + }, + "node_modules/@bedrock-layout/use-stateful-ref": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@bedrock-layout/use-stateful-ref/-/use-stateful-ref-1.2.0.tgz", + "integrity": "sha512-bAL7tZbd1nuriRi2i0IdTqAZuXndVVbTkOJb5/BMKOj6seOix97QnlNmE5GIkXVr8jebEHJ2KOj8HAjhK5p8Ig==", + "peerDependencies": { + "react": "^16.8 || ^17" + } + }, "node_modules/@csstools/normalize.css": { "version": "12.0.0", "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-12.0.0.tgz", @@ -5061,6 +5081,11 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, + "node_modules/body-scroll-lock": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/body-scroll-lock/-/body-scroll-lock-3.1.5.tgz", + "integrity": "sha512-Yi1Xaml0EvNA0OYWxXiYNqY24AfWkbA6w5vxE7GWxtKfzIbZM+Qw+aSmkgsbWzbHiy/RCSkUZBplVxTA+E4jJg==" + }, "node_modules/bonjour": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", @@ -5567,6 +5592,11 @@ "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==" }, + "node_modules/classnames": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz", + "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==" + }, "node_modules/clean-css": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.2.2.tgz", @@ -16529,6 +16559,23 @@ "node": ">=0.10.0" } }, + "node_modules/react-responsive-modal": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/react-responsive-modal/-/react-responsive-modal-6.2.0.tgz", + "integrity": "sha512-i3Or4ixdDnLOeZbOQltgayOj69zg6Pbd8IF+RMi6gG1hyZvXHL39QvMvXBuG7poEaBMHspXNDtCzbTBJpOmdfw==", + "dependencies": { + "@bedrock-layout/use-forwarded-ref": "^1.1.4", + "body-scroll-lock": "^3.1.5", + "classnames": "^2.2.6" + }, + "funding": { + "url": "https://github.com/sponsors/pradel" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17", + "react-dom": "^16.8.0 || ^17" + } + }, "node_modules/react-scripts": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.0.tgz", @@ -21821,6 +21868,20 @@ "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==" }, + "@bedrock-layout/use-forwarded-ref": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/@bedrock-layout/use-forwarded-ref/-/use-forwarded-ref-1.1.12.tgz", + "integrity": "sha512-FIQlXhgwB+hh3fUm0TkFjL3SFLqm0VHYhEOZhoFGhYn3n0ZOz/zSsxFH/m67GX+Q3/A5D3ox/1Y+phAMUw2L7g==", + "requires": { + "@bedrock-layout/use-stateful-ref": "^1.2.0" + } + }, + "@bedrock-layout/use-stateful-ref": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@bedrock-layout/use-stateful-ref/-/use-stateful-ref-1.2.0.tgz", + "integrity": "sha512-bAL7tZbd1nuriRi2i0IdTqAZuXndVVbTkOJb5/BMKOj6seOix97QnlNmE5GIkXVr8jebEHJ2KOj8HAjhK5p8Ig==", + "requires": {} + }, "@csstools/normalize.css": { "version": "12.0.0", "resolved": "https://registry.npmjs.org/@csstools/normalize.css/-/normalize.css-12.0.0.tgz", @@ -24225,6 +24286,11 @@ } } }, + "body-scroll-lock": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/body-scroll-lock/-/body-scroll-lock-3.1.5.tgz", + "integrity": "sha512-Yi1Xaml0EvNA0OYWxXiYNqY24AfWkbA6w5vxE7GWxtKfzIbZM+Qw+aSmkgsbWzbHiy/RCSkUZBplVxTA+E4jJg==" + }, "bonjour": { "version": "3.5.0", "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", @@ -24595,6 +24661,11 @@ "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==" }, + "classnames": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz", + "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==" + }, "clean-css": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.2.2.tgz", @@ -32470,6 +32541,16 @@ "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.11.0.tgz", "integrity": "sha512-F27qZr8uUqwhWZboondsPx8tnC3Ct3SxZA3V5WyEvujRyyNv0VYPhoBg1gZ8/MV5tubQp76Trw8lTv9hzRBa+A==" }, + "react-responsive-modal": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/react-responsive-modal/-/react-responsive-modal-6.2.0.tgz", + "integrity": "sha512-i3Or4ixdDnLOeZbOQltgayOj69zg6Pbd8IF+RMi6gG1hyZvXHL39QvMvXBuG7poEaBMHspXNDtCzbTBJpOmdfw==", + "requires": { + "@bedrock-layout/use-forwarded-ref": "^1.1.4", + "body-scroll-lock": "^3.1.5", + "classnames": "^2.2.6" + } + }, "react-scripts": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/react-scripts/-/react-scripts-5.0.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index 756b18c..4ee3c3a 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -20,6 +20,7 @@ "node-sass": "^7.0.0", "react": "^17.0.2", "react-dom": "^17.0.2", + "react-responsive-modal": "^6.2.0", "react-scripts": "5.0.0", "react-simple-code-editor": "^0.11.0", "react-syntax-highlighter": "^15.4.5", diff --git a/frontend/src/App.scss b/frontend/src/App.scss index 22aa601..0baa9af 100644 --- a/frontend/src/App.scss +++ b/frontend/src/App.scss @@ -1,4 +1,4 @@ -@import url("https://fonts.googleapis.com/css2?family=KoHo:wght@200;300;400;500;600;700&display=swap"); +@import url('https://fonts.googleapis.com/css2?family=KoHo:wght@200;300;400;500;600;700&display=swap'); $header-color: #37474f; $footer-color: #37474f; @@ -8,171 +8,175 @@ $footer-height: 1.5rem; $editor-height: calc(100vh - 5rem); .App { - height: 100vh; - font-family: koho; + height: 100vh; + font-family: koho; } .header, .footer { - z-index: 2; - position: fixed; - background-color: $header-color; - display: flex; - flex-direction: row; - align-items: center; - justify-content: space-between; - font-size: calc(10px + 2vmin); - color: white; - width: 100%; - box-sizing: border-box; - padding: 0 12px; + z-index: 2; + position: fixed; + background-color: $header-color; + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + font-size: calc(10px + 2vmin); + color: white; + width: 100%; + box-sizing: border-box; + padding: 0 12px; } .header { - height: $header-height; - top: 0; - box-shadow: 0 3px 3px rgba(0, 0, 0, 0.16), 0 3px 3px rgba(0, 0, 0, 0.23); - - .site-name { - font-size: 2rem; - font-weight: 500; - color: #f9bfd3; - cursor: pointer; - } - - .custom-url { - width: 320px; - background: transparent; - border: none; - font-size: 1em; - color: whitesmoke; - font-family: cascadia code; - border-bottom: #717273 2px solid; - outline: none; - - &.active { - border-bottom: whitesmoke 2px solid; - } - &.error { - border-bottom: rgba(253, 0, 0, 0.96) 2px solid; - } - } - - .btn-wrapper { - display: inline-flex; - align-items: center; - - .btn { - width: 2.6rem; - font-size: 1.6rem; - cursor: pointer; - color: #c8cdd1; - - &:hover { - color: white; - } - - &.save { - &.failure { - color: #f1c902; - } - &.success { - color: #74e84d; - } - } - - &.timer { - padding: 1.2rem 0; - } - } - } - - .btn.timer:hover ~ .expiry-menu { - display: block; - } - - .expiry-menu { - display: none; - z-index: 5; - position: fixed; - top: 3.5rem; - right: 0; - box-sizing: border-box; - margin: 4px 8px; - padding: 4px 4px; - background-color: $header-color; - border-radius: 4px; - box-shadow: 0 3px 3px rgba(0, 0, 0, 0.16), 0 3px 3px rgba(0, 0, 0, 0.23); - font-size: 1.4rem; - text-align: center; - - &:hover{ - display: block; - } - - span { - text-decoration: underline; - text-underline-offset: 3px; - text-decoration-thickness: 1px; - } - ul { - padding: 0; - margin: 8px; - text-align: left; - - li { - list-style-type: none; - text-indent: 0; - font-size: 1.2rem; - padding: 4px 16px; - transition: 0.36s ease-out; - border-radius: 4px; - cursor: pointer; - - &:hover { - background-color: #4b616dd8; - transition: 0.24s ease-out; - } - } - } - } + height: $header-height; + top: 0; + box-shadow: 0 3px 3px rgba(0, 0, 0, 0.16), 0 3px 3px rgba(0, 0, 0, 0.23); + + .site-name { + font-size: 2rem; + font-weight: 500; + color: #f9bfd3; + cursor: pointer; + } + + .custom-url { + width: 320px; + background: transparent; + border: none; + font-size: 1em; + color: whitesmoke; + font-family: cascadia code; + border-bottom: #717273 2px solid; + outline: none; + + &.active { + border-bottom: whitesmoke 2px solid; + } + &.error { + border-bottom: rgba(253, 0, 0, 0.96) 2px solid; + } + } + + .btn-wrapper { + display: inline-flex; + align-items: center; + + .btn { + width: 2.6rem; + font-size: 1.6rem; + cursor: pointer; + color: #c8cdd1; + + &:hover { + color: white; + } + + &.save { + &.failure { + color: #f1c902; + } + &.success { + color: #74e84d; + } + } + + &.timer { + padding: 1.2rem 0; + } + } + } + + .btn.timer:hover ~ .expiry-menu { + display: block; + } + + .expiry-menu { + display: none; + z-index: 5; + position: fixed; + top: 3.5rem; + right: 0; + box-sizing: border-box; + margin: 4px 8px; + padding: 4px 4px; + background-color: $header-color; + border-radius: 4px; + box-shadow: 0 3px 3px rgba(0, 0, 0, 0.16), 0 3px 3px rgba(0, 0, 0, 0.23); + font-size: 1.4rem; + text-align: center; + + &:hover { + display: block; + } + + span { + text-decoration: underline; + text-underline-offset: 3px; + text-decoration-thickness: 1px; + } + ul { + padding: 0; + margin: 8px; + text-align: left; + + li { + list-style-type: none; + text-indent: 0; + font-size: 1.2rem; + padding: 4px 16px; + transition: 0.36s ease-out; + border-radius: 4px; + cursor: pointer; + + &:hover { + background-color: #4b616dd8; + transition: 0.24s ease-out; + } + } + } + } } .footer { - height: $footer-height; - bottom: 0; - box-shadow: 0 -3px 3px rgba(0, 0, 0, 0.16), 0 -3px 3px rgba(0, 0, 0, 0.23); - justify-content: flex-end; - - .credits { - font-size: 0.8rem; - .copyleft { - display: inline-block; - transform: rotate(180deg); - padding: 0 4px 2px; - } - } + height: $footer-height; + bottom: 0; + box-shadow: 0 -3px 3px rgba(0, 0, 0, 0.16), 0 -3px 3px rgba(0, 0, 0, 0.23); + justify-content: flex-end; + + .credits { + font-size: 0.8rem; + .copyleft { + display: inline-block; + transform: rotate(180deg); + padding: 0 4px 2px; + } + } } .main { - position: fixed; - top: $header-height; - background-color: $editor-color; - min-width: 100%; - min-height: $editor-height; - font-size: calc(10px + 2vmin); - color: white; - - .editor { - border-style: none; - border-color: Transparent; - outline: none; - resize: none; - background: none; - min-height: $editor-height; - width: 100%; - font-size: 20px; - color: white; - font-family: "Courier New", Courier, monospace; - } + position: fixed; + top: $header-height; + background-color: $editor-color; + min-width: 100%; + min-height: $editor-height; + font-size: calc(10px + 2vmin); + color: white; + + .editor { + border-style: none; + border-color: Transparent; + outline: none; + resize: none; + background: none; + min-height: $editor-height; + width: 100%; + font-size: 20px; + color: white; + font-family: 'Courier New', Courier, monospace; + } +} + +.url-style:hover { + color: #32b904; } diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 13d9788..671315b 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -1,156 +1,176 @@ import { useEffect, useState } from 'react'; -import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import { faSave, faPlus, faClock } from "@fortawesome/free-solid-svg-icons"; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { faSave, faPlus, faClock } from '@fortawesome/free-solid-svg-icons'; +import 'react-responsive-modal/styles.css'; +import { Modal } from 'react-responsive-modal'; import './App.scss'; -import { getBin } from "./logic/getBin"; -import { saveBin } from "./logic/saveBin"; -import { SaveStates, Bin, SaveIcons } from "./logic/constants"; -import { CustomUrlInput } from "./components/CustomUrlInput"; -import { ExpiryMenu } from "./components/ExpiryMenu"; -import { Footer } from "./components/Footer"; -import { Main } from "./components/Main"; +import { getBin } from './logic/getBin'; +import { saveBin } from './logic/saveBin'; +import { SaveStates, Bin, SaveIcons } from './logic/constants'; +import { CustomUrlInput } from './components/CustomUrlInput'; +import { ExpiryMenu } from './components/ExpiryMenu'; +import { Footer } from './components/Footer'; +import { Main } from './components/Main'; +function App() { + const [customUrl, setCustomUrl] = useState(''); + const [customUrlError, setCustomUrlError] = useState(false); -function App () -{ - const [ customUrl, setCustomUrl ] = useState( "" ); - const [ customUrlError, setCustomUrlError ] = useState( false ); + const [binData, setBinData] = useState(''); + const [language, setLanguage] = useState('js'); + const [expiryDate, setExpiryDate] = useState('Never'); - const [ binData, setBinData ] = useState( "" ); - const [ language, setLanguage ] = useState( "js" ); - const [ expiryDate, setExpiryDate ] = useState( "Never" ); + const [saveIcon, setSaveIcon] = useState(faSave); + const [saveState, setSaveState] = useState(SaveStates.neutral); - const [ saveIcon, setSaveIcon ] = useState( faSave ); - const [ saveState, setSaveState ] = useState( SaveStates.neutral ); + const [newBinIcon, setNewBinIcon] = useState(faPlus); + const [expiryIcon, setExpiryIcon] = useState(faClock); - const [ newBinIcon, setNewBinIcon ] = useState( faPlus ); - const [ expiryIcon, setExpiryIcon ] = useState( faClock ); + // modal hooks + const [open, setOpen] = useState(false); + const onOpenModal = () => setOpen(true); + const onCloseModal = () => setOpen(false); - function displayBin ( bin: Bin ) - { - setCustomUrl( bin.customUrl ); - setBinData( bin.code ); + //styles for modal + const styles = {}; + + function displayBin(bin: Bin) { + setCustomUrl(bin.customUrl); + setBinData(bin.code); } - function newBin () - { + function newBin() { window.location.pathname = '/'; - setCustomUrl( "" ); - setBinData( "" ); + setCustomUrl(''); + setBinData(''); } - async function onSaveClick () - { - const status = await saveBin( { + async function onSaveClick() { + const status = await saveBin({ language: language, customUrl: customUrl, code: binData, expiryDate: expiryDate, - } ); + }); - console.log( status ); + console.log(status); - switch ( status ) - { + switch (status) { case 201: - setSaveIcon( SaveIcons.saveSuccessIcon ); - setSaveState( SaveStates.success ); + setSaveIcon(SaveIcons.saveSuccessIcon); + setSaveState(SaveStates.success); window.location.pathname = customUrl; - break; + break; case 401: case 404: - setSaveIcon( SaveIcons.saveFailureIcon ); - setSaveState( SaveStates.failure ); - setCustomUrlError( true ); + setSaveIcon(SaveIcons.saveFailureIcon); + setSaveState(SaveStates.failure); + setCustomUrlError(true); break; default: break; } - console.log( saveState, customUrlError ); + console.log(saveState, customUrlError); - setTimeout( () => - { - setSaveIcon( SaveIcons.saveNeutralIcon ); - setSaveState( SaveStates.neutral ); - }, 1200 ); + setTimeout(() => { + setSaveIcon(SaveIcons.saveNeutralIcon); + setSaveState(SaveStates.neutral); + }, 1200); } - useEffect( () => - { + useEffect(() => { const binUrl = window.location.pathname; - async function checkBinUrl () - { - if ( binUrl != '/' ) - { - let bin: Bin = await getBin( binUrl ); - displayBin( bin ); - } - - else - { + async function checkBinUrl() { + if (binUrl != '/') { + let bin: Bin = await getBin(binUrl); + displayBin(bin); + } else { return null; } - }; + } checkBinUrl(); - }, [] ); - + }, []); return ( -
window.open(customUrl)}>{customUrl}
+