Skip to content

Commit

Permalink
urlDelete and profile section
Browse files Browse the repository at this point in the history
  • Loading branch information
sid86-dev committed May 1, 2022
1 parent 8abf8bf commit 7c54e65
Show file tree
Hide file tree
Showing 9 changed files with 367 additions and 29 deletions.
4 changes: 2 additions & 2 deletions components/Main.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export default function Main() {
if (data.response) {
toast.info(data.response, {
position: "top-center",
autoClose: 3000,
autoClose: 2000,
hideProgressBar: false,
closeOnClick: true,
pauseOnHover: true,
Expand All @@ -37,7 +37,7 @@ export default function Main() {

toast.success('Url saved!', {
position: "top-center",
autoClose: 3000,
autoClose: 2000,
hideProgressBar: false,
closeOnClick: true,
pauseOnHover: true,
Expand Down
3 changes: 1 addition & 2 deletions components/Result.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { useState } from 'react';
import copy from 'copy-to-clipboard';
import { ToastContainer, toast } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';

export default function Result({ data }) {

Expand Down Expand Up @@ -44,7 +43,7 @@ export default function Result({ data }) {

<ToastContainer
position="bottom-center"
autoClose={5000}
autoClose={4000}
hideProgressBar
newestOnTop={false}
closeOnClick
Expand Down
169 changes: 155 additions & 14 deletions components/user/Profile.jsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,78 @@
import axios from "axios"
import axios from "axios"
import { useRouter } from "next/router";
import { Context } from '../../context/Store'
import { useContext, useEffect, useState } from 'react';
import randomColor from 'randomcolor';
import copy from 'copy-to-clipboard';
import { ToastContainer, toast } from 'react-toastify';
import Ripples from 'react-ripples'
import LinkIcon from '@mui/icons-material/Link';
import ContentCopyIcon from '@mui/icons-material/ContentCopy';
import DeleteIcon from '@mui/icons-material/Delete';
import { getCookie, removeCookies, setCookies } from 'cookies-next';
import buildId from 'build-id'


const refreshUserData = async () => {

var url = process.env.NEXT_PUBLIC_DOMAIN_URL;

async function sendReq(token, url) {

const response = await fetch(url, {
method: 'POST',
headers: {
'authorization': `Bearer ${token}`
}
});

return response.json();
}

// get token from storage
const refresh = await getCookie('refreshToken');

// send conditional request
if (!refresh) {
removeCookies('accessToken');
return { authorization: false, expired: true, payload: null }
}

else {
const data = await sendReq(refresh, url + '/api/user/auth');
return data;

};

return data;
};


export default function Profile() {
const router = useRouter();
const [state, setState] = useContext(Context);

const user = state.user?.payload;
const sessionId = getCookie('session')

const handleLogout = async () => {
await axios.post('/api/user/revoke');
router.push('/account?tab=login')
};

const updateUserState = async () => {
const authData = await refreshUserData();
await setState(prevState => ({
...prevState,
['user']: authData,
['authorized']: true,
}));
};

useEffect(() => {
updateUserState();
console.log('refreshing')
}, [sessionId])

return (


Expand Down Expand Up @@ -61,14 +119,14 @@ export default function Profile() {

</div>
</div>
{user && user.links != undefined ? (
{user && user.links != undefined && (
<div className="filter-result">
<p className="mb-30 ff-montserrat">Total URLs : {user.links.length}</p>
{ user.links.map((id, index) =>
{user.links.length == 0 ? <NoLink /> : user.links.map((id, index) =>
<Link Id={id} key={index} />
) }
</div>
) : <NoLink />
)
}

</div>
Expand All @@ -83,18 +141,73 @@ export default function Profile() {

export function Link({ Id }) {

const router = useRouter();
const [state, setState] = useContext(Context);
const user = state.user?.payload;
const [color, setColor] = useState(randomColor());
const [url, setUrl] = useState(process.env.NEXT_PUBLIC_DOMAIN_URL);
const [res, setRes] = useState(null);

const copyUrl = async (url) => {
copy(url);
toast('📋 Url copied to clipboard', {
position: "top-center",
autoClose: 1200,
hideProgressBar: true,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
progress: undefined,
});
};


const getUrlData = async () => {
const res = await axios.post(url + '/api/getUrl/' + Id, { app: true });
await setRes(res.data);
};

const updateSession = async () => {
removeCookies('session')
const sessionId = await buildId(50)
setCookies('session', sessionId);
}

async function deleteUrl(id) {
const promise = axios.post('/api/user/app/deleteUrl', { userId: user.userId, urlId: id });
toast.promise(promise, {
pending: 'Deleting Url...',
success: 'Url deleted!',
error: 'Something went wrong'
}
).then(() => {

updateSession().then(() => {
router.push('/account')
}).catch((err) => console.log(err))

}).catch((error) => {
console.log(error);
});
}

useEffect(() => {
axios.post(url + '/api/getUrl/' + Id, { app: true }).then((res) => {
console.log(res.data)
setRes(res.data);
}).catch((err) => console.log(err))
getUrlData().catch(console.log("Cannot fetch url data"));
}, [])

return (
<>
<ToastContainer
position="top-center"
autoClose={4000}
hideProgressBar
newestOnTop={false}
closeOnClick
rtl={false}
pauseOnFocusLoss
draggable
pauseOnHover
/>
<div className="job-box d-md-flex align-items-center justify-content-between mb-30">
<div className="job-left my-1 d-md-flex align-items-center flex-wrap">
<div className="img-holder mr-md-4 mb-md-0 mb-4 mx-auto mx-md-0 d-md-none d-lg-flex" style={{ backgroundColor: color }}>
Expand All @@ -104,18 +217,46 @@ export function Link({ Id }) {
<h5 className="text-md-left" style={{ paddingLeft: "30px" }}> <small>shwt.xyz/</small>
<strong className="text-primary">{Id} </strong></h5>

<ul className=" text-start d-md-flex flex-wrap text-break ff-open-sans">
<p className="pt-1 text-muted" >{res ? (res.fullUrl).substring(0,80)+' ...' : <p className="placeholder-glow">
<ul className=" text-start d-md-flex flex-wrap text-break ff-open-sans" >
<p className="pt-1 text-muted pe-auto" ><a href={res && res.fullUrl} rel="noreferrer" className="text-muted" target="_blank">
<LinkIcon fontSize="large" /></a> <Ripples> {res ? (res.fullUrl).substring(0, 80) + ' ...' : <p className="placeholder-glow">
<span className="placeholder col-10"></span>
</p>}</p>
</p>}</Ripples> </p>
</ul>
</div>
</div>
<div className="job-right my-2 flex-shrink-0">
<a className="btn d-block w-100 d-sm-inline-block btn-light ">more</a>
<a type="button" className="btn d-block w-100 d-sm-inline-block btn-light text-muted" onClick={() => copyUrl(`${url}/${Id}`)}>
<ContentCopyIcon fontSize="small" label="Copy" />
</a>

<a type="button" className="btn d-block w-100 d-sm-inline-block btn-light mt-3 " data-bs-toggle="modal"
data-bs-target="#deleteModel"><DeleteIcon color="gray" /></a>

<div className="modal fade" id="deleteModel" data-bs-backdrop="static" data-bs-keyboard="false" tabIndex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
<div className="modal-dialog modal-dialog-centered">
<div className="modal-content rounded-4 shadow">
<div className="modal-body p-4 text-center">
<h5 className="mb-0">Delete this shwt?</h5>
<p className="mb-0">You can always change your mind.</p>
</div>
<div className="modal-footer flex-nowrap p-0">
<button type="button" className="btn btn-lg btn-link fs-6 text-decoration-none col-6 m-0 rounded-0 border-right"
onClick={() => deleteUrl(Id)}
data-bs-dismiss="modal">
<strong>Yes, delete</strong>
</button>
<button type="button" className="btn btn-lg btn-link fs-6 text-decoration-none col-6 m-0 rounded-0" data-bs-dismiss="modal">No thanks</button>
</div>
</div>
</div>
</div>


</div>
</div>

</div>
</>
)
};

Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@
"dependencies": {
"@emotion/react": "11",
"@emotion/styled": "11",
"@mui/icons-material": "^5.6.2",
"@mui/material": "^5.6.3",
"@popperjs/core": "^2.11.5",
"axios": "^0.26.1",
"bootstrap": "^5.1.3",
Expand All @@ -28,6 +30,7 @@
"randomcolor": "^0.6.2",
"react": "18.0.0",
"react-dom": "18.0.0",
"react-ripples": "^2.2.1",
"react-toastify": "^8.2.0",
"shortid": "^2.2.16"
},
Expand Down
2 changes: 1 addition & 1 deletion pages/_document.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default function Document() {
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/nprogress/0.2.0/nprogress.min.css"
integrity="sha512-42kB9yDlYiCEfx2xVwq0q7hT4uf26FUgSIZBK8uiaEnTdShXjwr8Ip1V4xGJMg3mHkUt9nNuTDxunHF0/EgxLQ=="
crossOrigin="anonymous" referrerPolicy="no-referrer" />

</Head>
<body>
<Main />
Expand Down
7 changes: 5 additions & 2 deletions pages/account.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ import { Context } from '../context/Store'
import { useContext, useEffect, useState } from 'react';
import Login from '../components/Login';
import Signup from '../components/Signup';
import { getCookie, removeCookies } from 'cookies-next';
import { getCookie, removeCookies, setCookies } from 'cookies-next';
import { useRouter } from 'next/router';
import Profile from '../components/user/Profile';
import buildId from 'build-id'

Account.getInitialProps = async (ctx) => {
const { query, res, req } = ctx;
Expand Down Expand Up @@ -64,10 +65,12 @@ Account.getInitialProps = async (ctx) => {
export default function Account({ authData }) {
const router = useRouter();
const { query } = useRouter();

const [state, setState] = useContext(Context);

useEffect(() => {
const sessionId = buildId(50)
setCookies('session', sessionId);

const tab = query.tab;

if (authData.authorization == false && tab == undefined) {
Expand Down
43 changes: 43 additions & 0 deletions pages/api/user/app/deleteUrl.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import dbConnect from '../../../../utils/dbConnect';
import userSchema from '../../../../utils/models/userSchema'

dbConnect();

export default async function handler(req, res) {

if (req.method !== 'POST') {
return res.status(500).json({ message: 'Soory this is post route' })
}

const { userId, urlId } = req.body;

const filter = { _id: userId };

const user = await userSchema.findOne(filter);

if (!user) {
return res.status(423).send({ success: false })
}

try {

if (!user.links.includes(urlId)) {
return res.status(423).send({ success: false, response: "Url does not exist" })
}

var index = user.links.indexOf(urlId);

user.links.splice(index, 1);
await user.save();

return res.status(200).send({ success: true })
}
catch (e) {
console.log(e)
return res.status(423).send({ success: false })
}

return res.status(423).send({ success: false })


}
9 changes: 5 additions & 4 deletions pages/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ import Head from 'next/head';
import Navbar from '../components/Navbar';
import Main from '../components/Main';
import { Context } from '../context/Store'
import React, { useContext, useEffect, useState } from 'react';
import React, { useContext, useEffect} from 'react';
import { getCookie, removeCookies } from 'cookies-next';
import Script from 'next/script'

export default function Home() {

Expand Down Expand Up @@ -62,7 +63,6 @@ export default function Home() {
const setAuthData = async () => {

const authData = await getUserData();
console.log(authData);
await setState(prevState => ({
...prevState,
['user']: authData,
Expand All @@ -78,8 +78,9 @@ export default function Home() {
<Head>
<title>Shwt</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
</Head>

</Head>
<Script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-ka7Sk0Gln4gmtz2MlQnikT1wXgYsOg+OMhuP+IlRH9sENBO0LRn5q+8nbTov4+1p"
crossOrigin="anonymous"></Script>
<Navbar />
<Main />
</div>
Expand Down
Loading

0 comments on commit 7c54e65

Please sign in to comment.