Browse Source

created GoMessage

yankevych0210 1 year ago
parent
commit
42a16944c1

+ 10 - 0
src/components/Editor/Editor.jsx

@@ -15,6 +15,8 @@ import { saveFiles } from '../../store/currentWork/actions/saveFiles';
 import { setFormatCode } from '../../store/currentWork/currentWorkSlice';
 import { askToLogin } from '../../utils/askToLogin.js';
 import { useNavigate } from 'react-router-dom';
+import { GoMessage } from '../GoMessage/GoMessage';
+import { useTimedPopup } from '../../hooks/useTimedPopup.js';
 
 const logos = {
   xml: <HtmlLogo />,
@@ -28,6 +30,8 @@ export default function Editor({ language, displayName, value, onChange }) {
   const editorRef = useRef(null);
   const { id, files } = useSelector((state) => state.currentWork);
   const { isAuth } = useSelector((state) => state.auth);
+  const saveMessage = useTimedPopup();
+
   const handleSave = () => {
     dispatch(setFormatCode());
 
@@ -42,6 +46,7 @@ export default function Editor({ language, displayName, value, onChange }) {
           js: files.js.text,
         })
       );
+      saveMessage.openPopup();
     }
   };
 
@@ -84,6 +89,11 @@ export default function Editor({ language, displayName, value, onChange }) {
           editorRef.current = editor;
         }}
       />
+      <GoMessage
+        message={'Pen saved.'}
+        close={saveMessage.closePopup}
+        isOpen={saveMessage.isOpen}
+      />
     </Section>
   );
 }

+ 38 - 0
src/components/GoMessage/GoMessage.jsx

@@ -0,0 +1,38 @@
+import style from './GoMessage.module.scss';
+import { GrClose } from 'react-icons/gr';
+import { BsCheckLg } from 'react-icons/bs';
+
+export const GoMessage = ({ children, type, message, isOpen, close }) => {
+  const getStyle = () => {
+    let top = isOpen ? '20px' : '-200px';
+    let border;
+
+    if (type === 'success') {
+      border = '2px solid #46CF73';
+    }
+    if (type === 'warning') {
+      border = '2px solid #ffdd40';
+    }
+
+    return {
+      top,
+      border,
+    };
+  };
+
+  if (children) {
+    return (
+      <div style={getStyle()} className={style.message}>
+        {children}
+      </div>
+    );
+  }
+
+  return (
+    <div style={getStyle()} className={style.message}>
+      <BsCheckLg />
+      <span>{message}</span>
+      <GrClose onClick={close} />
+    </div>
+  );
+};

+ 52 - 0
src/components/GoMessage/GoMessage.module.scss

@@ -0,0 +1,52 @@
+@import '../../scss/index.scss';
+
+.message {
+    @include flex($align: center);
+    position: absolute;
+    top: -100px;
+    left: 50%;
+    transform: translate(-50%);
+    border: 3px solid $greenGoMessage;
+    background-color: #2D313A;
+    border-radius: 6px;
+    padding: 9px 13px 9px 15px;
+    color: white;
+    transition: .5s all ease-in-out;
+    z-index: 10;
+
+
+    svg:first-of-type {
+        width:20px;
+        height: 20px;
+        margin-right: 8px;
+        background-color: $greenGoMessage;
+        border-radius: 50%;
+        padding: 2px;
+    }
+
+    svg:last-of-type {
+        width:13px;
+        height: 13px;
+        margin-left: 7px;
+        path {
+            stroke: #868DA0;
+        }
+        
+        &:hover {
+            path {
+                stroke: #aeb4c5;
+            }
+        }
+    }
+
+}
+
+.open {
+    @extend .message;
+    top: 20px;
+}
+
+.closed {
+    @extend .message;
+    top: -200px;
+}

+ 38 - 4
src/components/HeaderPen/HeaderPen.jsx

@@ -1,4 +1,4 @@
-import React from 'react';
+import React, { useEffect } from 'react';
 import { useDispatch, useSelector } from 'react-redux';
 import { ReactComponent as Logo } from '../../assets/img/logo.svg';
 import { NavLink, useNavigate } from 'react-router-dom';
@@ -6,12 +6,19 @@ import { saveFiles } from '../../store/currentWork/actions/saveFiles';
 import style from './HeaderPen.module.scss';
 import { setFormatCode } from '../../store/currentWork/currentWorkSlice';
 import { askToLogin } from '../../utils/askToLogin';
+import { BsFillCloudFill } from 'react-icons/bs';
+import { FaPen } from 'react-icons/fa/index';
+import { GoMessage } from '../GoMessage/GoMessage';
+import { useTimedPopup } from '../../hooks/useTimedPopup';
+import { usePopup } from '../../hooks/usePopup';
 
 export const HeaderPen = () => {
   const dispatch = useDispatch();
   const navigate = useNavigate();
   const { isAuth } = useSelector((state) => state.auth);
   const { id, title, owner, files } = useSelector((state) => state.currentWork);
+  const saveMessage = useTimedPopup();
+  const askToLoginPopup = usePopup();
 
   const logout = () => {
     localStorage.removeItem('authToken');
@@ -22,7 +29,8 @@ export const HeaderPen = () => {
     dispatch(setFormatCode());
 
     if (!isAuth) {
-      if (askToLogin()) navigate('/login');
+      askToLoginPopup.open();
+      // if (askToLogin()) navigate('/login');
     } else {
       dispatch(
         saveFiles({
@@ -32,6 +40,7 @@ export const HeaderPen = () => {
           js: files.js.text,
         })
       );
+      saveMessage.openPopup();
     }
   };
 
@@ -47,12 +56,37 @@ export const HeaderPen = () => {
         </div>
       </div>
 
+      <GoMessage type="warning" isOpen={askToLoginPopup.isPopupVisible}>
+        <div className={style.loginPopup}>
+          <span>
+            You’ll have to Log In or Sign Up to save your Pen. Don’t worry! All
+            your work will be saved to your account.
+          </span>
+          <div>
+            <button onClick={askToLoginPopup.close}>close</button>
+            <NavLink to={'/login'}>OK</NavLink>
+          </div>
+        </div>
+      </GoMessage>
+
+      <GoMessage
+        type="success"
+        message={'Pen saved.'}
+        close={saveMessage.closePopup}
+        isOpen={saveMessage.isOpen}
+      />
+
       <nav>
-        <button onClick={handleSaveFiles}>Save</button>
+        <button onClick={handleSaveFiles}>
+          <BsFillCloudFill />
+          Save
+        </button>
 
         {isAuth ? (
           <>
-            <NavLink to="/your-works">Your works</NavLink>
+            <NavLink to="/your-works">
+              <FaPen /> Your works
+            </NavLink>
             <NavLink
               style={{ backgroundColor: '#dc143c' }}
               onClick={logout}

+ 48 - 2
src/components/HeaderPen/HeaderPen.module.scss

@@ -4,7 +4,6 @@
   @include container($width: 98vw);
   @include flex($justify: space-between, $align: center);
   height: 65px;
-
   margin-bottom: 1px;
 
   &::before {
@@ -61,17 +60,31 @@
   }
 
   nav {
+    display: flex;
     z-index: 0;
+
     button:first-of-type {
       @extend %buttonGrey;
       font-size: 16.5px;
       padding: 13px 16px;
+      display: flex;
+      align-items: center;
+      width: 100px; 
+
+      svg {
+        margin-right: 10px;
+      }
     }
 
     a:first-of-type {
       @extend %buttonGrey;
-      padding: 13px 16px;
+      padding: 13px 14px;
       margin: 0 10px;
+      svg {
+        width: 14px;
+        height: 14px;
+        margin-right: 4px;
+      }
     }
 
     a:last-child {
@@ -80,4 +93,37 @@
       padding: 13px 16px;
     }
   }
+
+  .loginPopup {
+    @include flex($direction: column);
+    width: 400px;
+   height: 150px;
+   padding: 10px;
+    
+    span {
+      margin-bottom: auto;
+      font-weight: 400;
+      font-size: 18px;
+    }
+
+    div {
+      display: flex;
+      justify-content: flex-end;
+
+      button {
+        margin-left: 20px;
+        padding: 7px 20px;
+        @extend %buttonGrey;
+        font-size: 17px;
+      }
+
+      a {
+        margin-left: 20px;
+        padding: 7px 20px;
+        @extend %buttonGrey;
+      }
+    }
+
+
+  }
 }

+ 5 - 1
src/components/ImageUploader/ImageUploader.jsx

@@ -2,6 +2,7 @@ import style from './ImageUploader.module.scss';
 import { usePopup } from '../../hooks/usePopup';
 import { DragAndDropPopup } from '../DragAndDropPopup/DragAndDropPopup';
 import { useSelector } from 'react-redux';
+import { MdUploadFile } from 'react-icons/md';
 
 export const ImageUploader = () => {
   const dndPopup = usePopup();
@@ -13,7 +14,10 @@ export const ImageUploader = () => {
         <img src={avatar} alt="userImage" />
         <div className={style.info}>
           <span>Upload a New Profile Image</span>
-          <button onClick={dndPopup.open}>Choose File</button>
+          <button onClick={dndPopup.open}>
+            <MdUploadFile />
+            Choose File
+          </button>
           <span>or drag and drop an image here</span>
           <span>Ideal dimensions are 500px x 500px.</span>
           <span>Maximum file size is 5mb.</span>

+ 7 - 0
src/components/ImageUploader/ImageUploader.module.scss

@@ -26,11 +26,18 @@
         }
 
         button {
+            @include flex($align: center);
             @extend %buttonGrey;
             font-size: 16px;
             font-weight: 600;
             width: fit-content;
             margin: 20px 0;
+
+            svg {
+                width:20px;
+                height: 20px;
+                margin-right: 5px;
+            }
         }
 
         span:nth-child(3),

+ 6 - 1
src/components/UpdatePassword/UpdatePassword.jsx

@@ -38,7 +38,12 @@ export const UpdatePassword = () => {
         title="New Password"
         type="password"
       />
-      <button type="submit">Update</button>
+      <button
+        disabled={!currentPassword.value || !newPassword.value}
+        type="submit"
+      >
+        Update
+      </button>
     </form>
   );
 };

+ 11 - 2
src/components/WorkCardPopup/WorkCardPopup.jsx

@@ -2,6 +2,9 @@ import { useDispatch } from 'react-redux';
 import { deleteWork } from '../../store/works/actions/deleteWork';
 import { updateWorkInfo } from '../../store/works/actions/updateWorkInfo';
 import style from './WorkCardPopup.module.scss';
+import { MdDriveFileRenameOutline } from 'react-icons/md/index';
+import { MdOutlineDescription } from 'react-icons/md/index';
+import { BiTrash } from 'react-icons/bi/index';
 
 export const WorkCardPopup = ({ menuRef, isVisible, work }) => {
   const dispatch = useDispatch();
@@ -49,9 +52,15 @@ export const WorkCardPopup = ({ menuRef, isVisible, work }) => {
   if (isVisible)
     return (
       <ul ref={menuRef} className={style.menuPopup}>
-        <li onClick={renameWork}>Rename work</li>
-        <li onClick={changeDescription}>Change Description</li>
+        <li onClick={renameWork}>
+          <MdDriveFileRenameOutline className={style.rename} /> Rename work
+        </li>
+        <li onClick={changeDescription}>
+          <MdOutlineDescription className={style.changeDesc} />
+          Change Description
+        </li>
         <li className={style.delete} onClick={handleDelete}>
+          <BiTrash />
           Delete work
         </li>
       </ul>

+ 14 - 4
src/components/WorkCardPopup/WorkCardPopup.module.scss

@@ -4,22 +4,29 @@
   position: absolute;
   bottom: 89px;
   right: 5%;
-  width: 180px;
-  height: 98px;
+  
   background-color: #2c303a;
-  padding: 5px;
+  padding: 8px;
   filter: drop-shadow(0px 0px 3px rgba(0, 0, 0, 1));
   border-top-right-radius: 5px;
   border-top-left-radius: 5px;
   border-bottom-left-radius: 5px;
-
   z-index: 1;
 
   li {
+    font-size: 17px;
+    font-weight: 600;
     border-radius: 3px;
     padding: 5px 7px;
     list-style: none;
     text-decoration: none;
+    @include flex($align: center);
+
+    svg {
+      width: 20px;
+    height: 20px;
+    margin-right: 5px;
+    }
   }
 
   li:hover {
@@ -30,3 +37,6 @@
     background-color: $redMain;
   }
 }
+
+
+

+ 33 - 0
src/hooks/useTimedPopup.js

@@ -0,0 +1,33 @@
+import { useState, useEffect } from 'react';
+
+const useTimedPopup = (initialIsOpen = false, timeout = 4000) => {
+  const [isOpen, setIsOpen] = useState(initialIsOpen);
+
+  useEffect(() => {
+    let timeoutId;
+
+    if (isOpen) {
+      timeoutId = setTimeout(() => {
+        setIsOpen(false);
+      }, timeout);
+    }
+
+    return () => clearTimeout(timeoutId);
+  }, [isOpen, timeout]);
+
+  const openPopup = () => {
+    setIsOpen(true);
+  };
+
+  const closePopup = () => {
+    setIsOpen(false);
+  };
+
+  return {
+    isOpen,
+    openPopup,
+    closePopup,
+  };
+};
+
+export { useTimedPopup };

+ 1 - 0
src/pages/PenPage/PenPage.jsx

@@ -16,6 +16,7 @@ export const PenPage = () => {
   const dispatch = useDispatch();
   const { id } = useParams();
   const console = usePopup();
+
   const { isLoading, error, files } = useSelector((state) => state.currentWork);
   const [isSizeChanged, setIsSizeChanged] = useState(false);
   const { html, css, js } = files;

+ 3 - 0
src/scss/_variables.scss

@@ -15,6 +15,9 @@ $redMain: #ff3b41;
 $redMain-hover: #f22b31;
 $redMain-active: #ee141b;
 
+// goMessageColors
+$greenGoMessage: #46CF73;
+
 // container
 $containerWidth: 90vw;
 $maxContainerWidth: 1450px;

+ 6 - 0
src/scss/templates/_buttons.scss

@@ -23,6 +23,12 @@
   &:active {
     background-color: $greyMain-active;
   }
+
+
+  &[disabled] {
+    opacity: .5!important;
+    cursor: not-allowed;
+  }
 }
 
 %buttonGreen {