Skip to content

Commit

Permalink
feat: add functionality for redirect ot original url
Browse files Browse the repository at this point in the history
  • Loading branch information
sahsisunny committed Nov 9, 2023
1 parent 1be31df commit 6d6ab9c
Show file tree
Hide file tree
Showing 6 changed files with 157 additions and 1 deletion.
13 changes: 12 additions & 1 deletion next.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
/** @type {import('next').NextConfig} */
const nextConfig = {};

const nextConfig = {
async redirects() {
return [
{
source: '/:shortCode',
destination: '/redirect/:shortCode',
permanent: false,
},
];
},
};

module.exports = nextConfig;
7 changes: 7 additions & 0 deletions public/assets/icons/redirect.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const RedirectIcon = () => (
<svg xmlns="http://www.w3.org/2000/svg" height="5em" viewBox="0 0 512 512" fill="#ffff">
<path d="M227.7 11.7c15.6-15.6 40.9-15.6 56.6 0l216 216c15.6 15.6 15.6 40.9 0 56.6l-216 216c-15.6 15.6-40.9 15.6-56.6 0l-216-216c-15.6-15.6-15.6-40.9 0-56.6l216-216zm87.6 137c-4.6-4.6-11.5-5.9-17.4-3.5s-9.9 8.3-9.9 14.8v56H224c-35.3 0-64 28.7-64 64v48c0 13.3 10.7 24 24 24s24-10.7 24-24V280c0-8.8 7.2-16 16-16h64v56c0 6.5 3.9 12.3 9.9 14.8s12.9 1.1 17.4-3.5l80-80c6.2-6.2 6.2-16.4 0-22.6l-80-80z" />
</svg>
);

export default RedirectIcon;
2 changes: 2 additions & 0 deletions src/constants/url.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ export const TINY_API_URL = 'https://staging-tinysite-api.realdevsquad.com/v1';
export const TINY_API_GOOGLE_LOGIN = `${TINY_API_URL}/auth/google/login`;
export const TINY_API_LOGOUT = `${TINY_API_URL}/auth/logout`;
export const BASE_SHORT_URL = 'https://staging-tinysite.realdevsquad.com';
export const TINY_API_URL_DETAIL = `${TINY_API_URL}/urls`;
export const TINY_API_REDIRECT = `${TINY_API_URL}/tinyurl`;
101 changes: 101 additions & 0 deletions src/pages/redirect/[redirect].tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import fetchOriginalUrl from '@/utils/fetchOriginalUrl ';
import RedirectIcon from '../../../public/assets/icons/redirect';
import { useState, useEffect } from 'react';
import { useRouter } from 'next/router';
import Head from 'next/head';

const Redirect = () => {
const router = useRouter();
const { redirect: shortUrlCode } = router.query as { redirect: string };

const [originalUrl, setOriginalUrl] = useState('');
const [timer, setTimer] = useState(5);
const [isPremiumUser, setIsPremiumUser] = useState(false);
const [showTooltip, setShowTooltip] = useState(false);

useEffect(() => {
setIsPremiumUser(false);
}, []);

useEffect(() => {
if (shortUrlCode) {
fetchOriginalUrl(shortUrlCode)
.then((url) => {
if (url) {
setOriginalUrl(url);
} else {
console.log('Short URL code not found');
router.push('/');
}
})
.catch((error) => {
console.error('Error fetching original URL:', error);
});
}
}, [shortUrlCode]);

useEffect(() => {
if (timer > 0) {
const countdown = setTimeout(() => setTimer(timer - 1), 1000);
return () => clearTimeout(countdown);
} else if (timer === 0) {
router.push(originalUrl);
}
}, [timer, originalUrl]);

const handleGoButtonClick = () => {
if (isPremiumUser) {
router.push(originalUrl);
} else {
setShowTooltip(true);
}
};

return (
<>
<Head>
<title>Redirecting...</title>
<meta name="robots" content="noindex" />
</Head>
<div className="w-screen min-h-screen flex flex-col items-center justify-center bg-gray-900 text-white">
<p className="text-lg">You are being redirected to:</p>
<p className="text-blue-500 text-xl font-bold">{originalUrl}</p>
{timer < 1 ? (
<div className="mt-4 flex flex-col items-center space-y-2">
<RedirectIcon />
<p className="text-1xl">Redirecting...</p>
</div>
) : (
<>
<div className="loader border-t-4 rounded-full border-gray-500 animate-spin aspect-square w-20 flex justify-center items-center text-yellow-700 text-4xl font-bold mt-4">
{timer}
</div>
<button onClick={handleGoButtonClick} className="mt-4 p-2 bg-blue-500 text-white rounded-md">
Go
</button>
</>
)}

{showTooltip && !isPremiumUser && (
<div className="mt-2 p-2 bg-yellow-100 text-yellow-800 rounded-md">
Wait for {timer} seconds or become a premium user to skip the wait time.
</div>
)}

<div className="absolute bottom-0 right-0 p-2 text-gray-500 w-screen flex justify-center items-center">
<p className="text-sm text-white ">This short URL generated by&nbsp;</p>
<a
className="text-sm text-white font-bold cursor-pointer hover:underline"
href="https://realdevsquad.com/"
target="_blank"
rel="noopener noreferrer"
>
Real Dev Squad URL Shortener
</a>
</div>
</div>
</>
);
};

export default Redirect;
15 changes: 15 additions & 0 deletions src/types/url.types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
export interface UrlType {
Id: number;
OriginalUrl: string;
ShortUrl: string;
Comment: string;
UserId: number;
ExpiredAt: string;
CreatedAt: string;
CreatedBy: string;
}

export interface UrlResponseTypes {
message: string;
url: UrlType;
}
20 changes: 20 additions & 0 deletions src/utils/fetchOriginalUrl .ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { TINY_API_URL_DETAIL } from '@/constants/url';
import { UrlResponseTypes } from '@/types/url.types';

async function fetchOriginalUrl(shortUrlCode: string): Promise<string | null> {
try {
const response = await fetch(`${TINY_API_URL_DETAIL}/${shortUrlCode}`);

if (response.ok) {
const data = (await response.json()) as UrlResponseTypes;
return data.url.OriginalUrl;
} else {
return null; // Return null if the response is not ok
}
} catch (error) {
console.error('Error fetching original URL:', error);
return null; // Return null in case of an error
}
}

export default fetchOriginalUrl;

0 comments on commit 6d6ab9c

Please sign in to comment.