Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UI : removed uncessary buttons and improve UI #35

Merged
merged 7 commits into from
Nov 7, 2023
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/pre-commit-checks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,4 @@ jobs:
run: yarn format:check

- name: Test check
run: yarn test -u
run: yarn test
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

# testing
/coverage
./__tests__/__snapshots__

# next.js
/.next/
Expand Down
2 changes: 0 additions & 2 deletions __tests__/components/Navbar.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@ describe('Navbar', () => {
it('should have dropdown menu', () => {
const { container } = render(<Navbar />);
expect(container.querySelector('ul')).toBeInTheDocument();
expect(container.querySelector('ul')).toContainHTML('Profile');
expect(container.querySelector('ul')).toContainHTML('Dashboard');
expect(container.querySelector('ul')).toContainHTML('Settings');
expect(container.querySelector('ul')).toContainHTML('Sign Out');
});

Expand Down
5 changes: 0 additions & 5 deletions __tests__/components/ProfileIcon.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,6 @@ import { render } from '@testing-library/react';
import ProfileIcon from '@/components/ProfileIcon/ProfileIcon';

describe('ProfileIcon', () => {
it('should render', () => {
const { container } = render(<ProfileIcon firstName="Sunny" lastName="Sahsi" size={50} />);
expect(container).toMatchSnapshot();
});

it('should have the correct initials', () => {
const { container } = render(<ProfileIcon firstName="Sunny" lastName="Sahsi" size={50} />);
expect(container).toHaveTextContent('SS');
Expand Down
25 changes: 25 additions & 0 deletions __tests__/components/Toast.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import React from 'react';
import { render, screen, waitFor } from '@testing-library/react';
import Toast from '../../src/components/Toast';

describe('Toast', () => {
const onDismiss = jest.fn();

test('should render the toast component with the message', () => {
render(<Toast message="This is a toast message" isVisible={true} timeToShow={5000} onDismiss={onDismiss} />);

expect(screen.getByText('This is a toast message')).toBeInTheDocument();
});

test('should not call onDismiss function when the timeToShow is not completed', () => {
render(<Toast message="This is a toast message" isVisible={true} timeToShow={5000} onDismiss={onDismiss} />);

expect(onDismiss).not.toHaveBeenCalled();
});

test('should call onDismiss function when the timeToShow is completed', async () => {
render(<Toast message="This is a toast message" isVisible={true} timeToShow={0} onDismiss={onDismiss} />);

await waitFor(() => expect(onDismiss).toHaveBeenCalled());
});
});
10 changes: 0 additions & 10 deletions __tests__/hello.test.tsx

This file was deleted.

26 changes: 26 additions & 0 deletions __tests__/pages/dashboard.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import Dashboard from '../../src/pages/dashboard';
import { render, screen, fireEvent } from '@testing-library/react';

describe('Dashboard Component', () => {
test('renders the Dashboard component', () => {
render(<Dashboard />);
const urlInput = screen.getByPlaceholderText('🔗 Enter the URL');
const generateButton = screen.getByText('Generate');
const copyButton = screen.getByTestId('copy-button');

expect(urlInput).toBeInTheDocument();
expect(generateButton).toBeInTheDocument();
expect(copyButton).toBeInTheDocument();
});

test('generates a short URL when clicking the Generate button', () => {
render(<Dashboard />);
const generateButton = screen.getByText('Generate');
const shortUrlInput = screen.getByPlaceholderText('Copy the URL');

fireEvent.click(generateButton);
const shortUrlValue = shortUrlInput.value;

expect(shortUrlValue).toMatch(/^https:\/\/rds\.li\/[a-zA-Z0-9]+$/);
});
});
5 changes: 0 additions & 5 deletions __tests__/pages/login.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,6 @@ import { fireEvent, render } from '@testing-library/react';
import LoginPage from '../../src/pages/login';

describe('LoginPage', () => {
it('should render without throwing an error', () => {
const { container } = render(<LoginPage />);
expect(container).toMatchSnapshot();
});

it('should render username input', () => {
const { getByLabelText } = render(<LoginPage />);
const usernameInput = getByLabelText('username') as HTMLInputElement;
Expand Down
1 change: 1 addition & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const createJestConfig = nextJest({
const customJestConfig = {
setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
testEnvironment: 'jest-environment-jsdom',
snapshotSerializers: [],
};

module.exports = createJestConfig(customJestConfig);
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"check:all": "yarn format:check && yarn lint:check",
"fix:all": "yarn format:fix && yarn lint:fix",
"prepare": "husky install",
"test": "jest --coverage -u",
"test": "jest --coverage",
"lint": "eslint .",
"lint-fix": "eslint . --fix"
},
Expand Down
10 changes: 0 additions & 10 deletions src/components/Navbar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,21 +57,11 @@ const Navbar: React.FC = () => {
)}
</li>
<ul className={`${menuOpen ? 'block' : 'hidden'} absolute top-[8vh] right-0 bg-gray-800 p-2 z-10`}>
<li>
<a href="#" className="text-white hover:bg-gray-700 block px-4 py-2">
Profile
</a>
</li>
<li>
<a href="#" className="text-white hover:bg-gray-700 block px-4 py-2">
Dashboard
</a>
</li>
<li>
<a href="#" className="text-white hover:bg-gray-700 block px-4 py-2">
Settings
</a>
</li>
<li>
<a href={TINY_API_LOGOUT} className="text-white hover:bg-gray-700 block px-4 py-2">
sahsisunny marked this conversation as resolved.
Show resolved Hide resolved
Sign Out
Expand Down
30 changes: 30 additions & 0 deletions src/components/Toast/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React, { useEffect } from 'react';

interface ToastProps {
message: string;
isVisible: boolean;
timeToShow: number;
onDismiss: () => void;
}

const Toast: React.FC<ToastProps> = ({ message, isVisible, timeToShow, onDismiss }) => {
useEffect(() => {
if (isVisible) {
const timer = setTimeout(() => {
onDismiss();
}, timeToShow);

return () => {
clearTimeout(timer);
};
}
}, [isVisible, timeToShow, onDismiss]);

return isVisible ? (
<div className="fixed bottom-10 left-1/2 transform -translate-x-1/2 bg-gray-900 text-white px-4 py-2 rounded-lg border-2 border-cyan-100">
{message}
</div>
) : null;
};

export default Toast;
76 changes: 35 additions & 41 deletions src/pages/dashboard/index.tsx
sahsisunny marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -1,84 +1,78 @@
import Button from '@/components/Button';
import InputBox from '@/components/InputBox';
import Layout from '@/components/Layout';
import Toast from '@/components/Toast';
import { randomString } from '@/utils/constants';
import { useState } from 'react';
import AddIcon from '../../../public/assets/icons/add';
import CopyIcon from '../../../public/assets/icons/copy';
import ReloadIcon from '../../../public/assets/icons/reload';

const Dashboard = () => {
const [url, getUrl] = useState<string>('');
const [shortUrl, setUrl] = useState<string>('');
const [toastMessage, setToastMessage] = useState<string>('');
const [showToast, setShowToast] = useState(false);

const handleUniqueUrl = () => {
setUrl(`https://rds.li/${randomString}`);
};

const handleCopyUrl = () => {
shortUrl ? setToastMessage('Copied to clipboard') : setToastMessage('No URL to copy');
navigator.clipboard.writeText(shortUrl);
setShowToast(true);
};

return (
<Layout title="Home | URL Shortener">
<div className="w-screen">
<div className="flex flex-col justify-center items-center m-4">
<div className="w-full lg:w-[42rem]">
<div className="w-full lg:w-[42rem] md:w-[32rem] sm:w-[22rem]">
<h1 className="text-4xl text-center text-white font-semibold">URL Shortener</h1>{' '}
<div className="flex flex-col md:flex-row justify-center items-center space-y-4 md:space-y-0 md:space-x-1 my-2">
<div className="bg-gray-200 flex flex-row justify-center items-center space-y-0 space-x-0 rounded-2xl mt-5 sm:mt-10">
<InputBox
type="text"
hideLabel={true}
className="w-full bg-gray-200 md:rounded-l-2xl p-4 md:rounded-none"
onChange={(e) => {
getUrl(e.target.value);
}}
className="bg-gray-200 w-full outline-none p-4 rounded-l-2xl"
onChange={(e) => getUrl(e.target.value)}
value={url}
placeholder="Enter the URL"
placeholder="🔗 Enter the URL"
name="URL"
/>
<Button
className="w-full md:w-auto bg-gray-200 md:rounded-r-2xl px-4 md:px-8 py-4 hover:bg-gray-300 mt-2 md:mt-0 md:rounded-none"
onClick={() => handleUniqueUrl()}
className="bg-gray-300 rounded-r-2xl p-4 hover:bg-gray-400"
onClick={handleUniqueUrl}
>
Generate
</Button>
</div>
<div className="flex flex-col md:flex-row justify-center items-center space-y-4 md:space-y-0 md:space-x-1">
<div className="bg-gray-200 flex flex-row justify-center items-center space-y-0 space-x-0 rounded-2xl mt-2">
<InputBox
type="text"
name="URL"
hideLabel={true}
className="w-full bg-gray-200 md:rounded-l-2xl p-4 md:rounded-none"
className="bg-gray-200 w-full outline-none p-4 rounded-l-2xl"
value={shortUrl}
disabled={true}
placeholder="Copy the URL"
/>
<div className="flex flex-row justify-center items-center space-x-1">
<Button
type="button"
className="w-full h-100 md:w-auto bg-gray-200 px-4 md:px-8 py-3 hover:bg-gray-300 mt-2 md:mt-0 md:rounded-none"
onClick={() => handleUniqueUrl()}
>
<ReloadIcon />
</Button>
<Button
type="button"
className="w-full md:w-auto bg-gray-200 px-4 md:px-8 py-3 hover:bg-gray-300 mt-2 md:mt-0 md:rounded-none"
onClick={() => {
setUrl('');
}}
>
<AddIcon />
</Button>
<Button
type="button"
className="w-full md:w-auto bg-gray-200 md:rounded-r-2xl px-4 md:px-8 py-3 hover:bg-gray-300 mt-2 md:mt-0 md:rounded-none"
onClick={() => {
navigator.clipboard.writeText(shortUrl);
}}
>
<CopyIcon />
</Button>
</div>
<Button
type="button"
className="bg-gray-200 rounded-r-2xl p-4 hover:bg-gray-400"
testId="copy-button"
onClick={handleCopyUrl}
>
<CopyIcon />
</Button>
</div>
</div>
</div>
{showToast && (
<Toast
message={toastMessage}
isVisible={showToast}
timeToShow={3000}
onDismiss={() => setShowToast(false)}
/>
)}
</div>
</Layout>
);
Expand Down