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

🚧 Working on About Section #13

Merged
merged 4 commits into from
Dec 28, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
3 changes: 2 additions & 1 deletion frontend/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Madhurendra's Tech Odyssey</title>
<link rel="shortcut icon" href="public/gif/Logo.gif" type="image/x-icon">
<title>👋 | Madhurendra's Tech Odyssey</title>
</head>
<body>
<div id="root"></div>
Expand Down
Binary file added frontend/public/jpeg/About-Image.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 4 additions & 1 deletion frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import HomeSection from './pages/Home';
import './App.css';
import { DarkModeProvider } from './services/context/DarkMode';
import { useDarkMode } from './services/customhook/useDarkMode';
import About from './pages/About';

function App() {
return (
Expand All @@ -18,13 +19,15 @@ const AppContent: React.FC = () => {
const { isDark } = useDarkMode();

const AppContainer = styled('div')({
color:isDark ? '#fff' : 'inherit',
color: isDark ? '#fff' : '#000',
backgroundColor: isDark ? "#1f1d27" : "inherit"
});

return (
<AppContainer>
<Navbar />
<HomeSection />
<About />
</AppContainer>
);
};
Expand Down
35 changes: 35 additions & 0 deletions frontend/src/components/atoms/Chip/index.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from 'react';
import { render, screen } from '@testing-library/react';
import MyChip from '.';
import "@testing-library/jest-dom"
import { IChipProp } from '../../../interfaces/types';

const mockProps: IChipProp = {
size: 'small',
label: 'Test Label',
variant: 'outlined',
onClick: jest.fn(),
color: 'primary',
style: {},
};


describe('MyChip Component', () => {
it('renders MyChip component with given props', () => {
render(<MyChip {...mockProps} />);

const chipElement = screen.getByTestId('mui-chip');
expect(chipElement).toBeInTheDocument();
expect(chipElement).toHaveTextContent('Test Label');
expect(chipElement).toHaveClass('MuiChip-outlined');
expect(chipElement).toHaveClass('MuiChip-sizeSmall');
});

it('calls onClick when chip is clicked', () => {
const mockFunction = jest.fn()
render(<MyChip {...mockProps} onClick={mockFunction} />);
const chipElement = screen.getByTestId('mui-chip');
chipElement.click()
expect(mockFunction).toHaveBeenCalledTimes(1);
});
});
20 changes: 20 additions & 0 deletions frontend/src/components/atoms/Chip/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react';
import { Chip } from '@mui/material';
import { MUI_CHIP } from '../../../utils/constants';
import { IChipProp } from '../../../interfaces/types';
import { getRandomLightColor } from '../../../services/functions/functions';



const MyChip = (props: IChipProp) =>
<Chip
size={props.size}
label={props.label}
variant={props.variant}
onClick={props.onClick}
color={props.color}
style={{ ...props.style, backgroundColor: getRandomLightColor() }}
data-testid={MUI_CHIP}
/>

export default MyChip;
16 changes: 16 additions & 0 deletions frontend/src/components/molecules/AnimatedName/index.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import React from 'react';
import { render } from '@testing-library/react';
import AnimatedName from '.';
import "@testing-library/jest-dom"
import { NAME_ANIMATION } from '../../../utils/constants';

test('renders the AnimatedName component', () => {
const { getByText, getAllByTestId } = render(<AnimatedName />);

const imText = getByText("I'm");
expect(imText).toBeInTheDocument();

const nameLetters = getAllByTestId(NAME_ANIMATION);
expect(nameLetters.length).toBeGreaterThan(0);

});
30 changes: 30 additions & 0 deletions frontend/src/components/molecules/AnimatedName/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from 'react'
import { myname } from '../../../services/mocks/mocks'
import { FlexDiv } from '../../../utils/styled'
import { NAME_ANIMATION } from '../../../utils/constants'
import './style.css'


const AnimatedName = () => {
return (
<FlexDiv>
<div>I'm</div>
<div className='name'>
&lt;
{myname.split('').map((ch, index) =>
<span
className={`name-${index}`}
data-testid={NAME_ANIMATION}
key={index}
>
{ch}
</span>
)}
{'/'}
&gt;
</div>
</FlexDiv>
)
}

export default AnimatedName
152 changes: 152 additions & 0 deletions frontend/src/components/molecules/AnimatedName/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
@keyframes gelatine {
from, to { transform: scale(1, 1); }
25% { transform: scale(0.9, 1.1); }
50% { transform: scale(1.1, 0.9); }
75% { transform: scale(0.95, 1.05); }
}

@keyframes bounce {
0%, 20%, 50%, 80%, 100% {transform: translateY(0);}
40% {transform: translateY(-20px);}
60% {transform: translateY(-15px);}
}
@keyframes flip {
0% {
transform: perspective(400px) rotateY(0);
animation-timing-function: ease-out;
}
40% {
transform: perspective(400px) translateZ(150px) rotateY(170deg);
animation-timing-function: ease-out;
}
50% {
transform: perspective(400px) translateZ(150px) rotateY(190deg) scale(1);
animation-timing-function: ease-in;
}
80% {
transform: perspective(400px) rotateY(360deg) scale(.95);
animation-timing-function: ease-in;
}
100% {
transform: perspective(400px) scale(1);
animation-timing-function: ease-in;
}
}

@keyframes swing {
20% { transform: rotate(15deg); }
40% { transform: rotate(-10deg); }
60% { transform: rotate(5deg); }
80% { transform: rotate(-5deg); }
100% { transform: rotate(0deg); }
}

@keyframes wobble {
0% { transform: translateX(0%); }
15% { transform: translateX(-25%) rotate(-5deg); }
30% { transform: translateX(20%) rotate(3deg); }
45% { transform: translateX(-15%) rotate(-3deg); }
60% { transform: translateX(10%) rotate(2deg); }
75% { transform: translateX(-5%) rotate(-1deg); }
100% { transform: translateX(0%); }
}

@keyframes bounce-in-right {
0% {
opacity: 0;
transform: translateX(2000px);
}
60% {
opacity: 1;
transform: translateX(-30px);
}
80% { transform: translateX(10px); }
100% { transform: translateX(0); }
}

@keyframes hinge {
0% { transform: rotate(0); transform-origin: top left; animation-timing-function: ease-in-out; }
20%, 60% { transform: rotate(80deg); transform-origin: top left; animation-timing-function: ease-in-out; }
40% { transform: rotate(60deg); transform-origin: top left; animation-timing-function: ease-in-out; }
80% { transform: rotate(60deg) translateY(0); opacity: 1; transform-origin: top left; animation-timing-function: ease-in-out; }
100% { transform: translateY(700px); opacity: 0; }
}

@keyframes rotate-in-up-left {
0% {
transform-origin: left bottom;
transform: rotate(90deg);
opacity: 0;
}
100% {
transform-origin: left bottom;
transform: rotate(0);
opacity: 1;
}
}

@keyframes rotate-in-down-left {
0% {
transform-origin: left bottom;
transform: rotate(-90deg);
opacity: 0;
}
100% {
transform-origin: left bottom;
transform: rotate(0);
opacity: 1;
}
}

@keyframes hithere {
30% { transform: scale(1.2); }
40%, 60% { transform: rotate(-20deg) scale(1.2); }
50% { transform: rotate(20deg) scale(1.2); }
70% { transform: rotate(0deg) scale(1.2); }
100% { transform: scale(1); }
}

.name {
color: #f4b039;
}

.name-0 {
display: inline-block;
animation: hinge 1.5s infinite 0.1s;
}
.name-1 {
display: inline-block;
animation: bounce 1.5s infinite 0.1s;
}
.name-2, .name-10 {
display: inline-block;
animation: flip 1.5s infinite 0.1s;
}

.name-3 {
display: inline-block;
animation: swing 1.5s infinite 0.1s;
}

.name-4, .name-8 {
display: inline-block;
animation: wobble 1.5s infinite 0.1s;
}
.name-5 {
display: inline-block;
animation: gelatine 1.5s infinite 0.1s;
}
.name-9 {
display: inline-block;
animation: rotate-in-up-left 1.5s infinite 0.1s;
}

.name-7 {
display: inline-block;
animation: rotate-in-down-left 1.5s infinite 0.1s;
}

.name-6 {
display: inline-block;
animation: hithere 1.5s infinite 0.1s;
}
7 changes: 3 additions & 4 deletions frontend/src/components/molecules/IconList/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import React from 'react';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faBriefcase, faCode, faEnvelope, faHouse, faLaptopCode, faRightToBracket, faUserGraduate } from '@fortawesome/free-solid-svg-icons';
import { faBriefcase, faCode, faEnvelope, faHouse, faInfo, faLaptopCode, faRightToBracket, faUserGraduate } from '@fortawesome/free-solid-svg-icons';
import DarkModeToggle from '../../atoms/Toggle';
import { IconContainer, LeftDiv, MiddleDiv, RightDiv, StyledAboutIcon, StyledNavIcon } from '../../../utils/styled';
import { IconContainer, LeftDiv, MiddleDiv, RightDiv, StyledNavIcon } from '../../../utils/styled';
import Icon from '../../atoms/Icon';
import LogoGif from '../../../../public/gif/Logo.gif';
import About from '../../../../public/svg/About.svg';
import { useDarkMode } from '../../../services/customhook/useDarkMode';
import { ICON_COMPONENT_HOME } from '../../../utils/constants';

Expand All @@ -19,7 +18,7 @@ const HomeIconsList = () => {
</LeftDiv>
<MiddleDiv>
<FontAwesomeIcon icon={faHouse} />
<Icon src={About} sx={StyledAboutIcon} />
<FontAwesomeIcon icon={faInfo} />
<FontAwesomeIcon icon={faUserGraduate} />
<FontAwesomeIcon icon={faCode} />
<FontAwesomeIcon icon={faLaptopCode} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ const SocialMediaIcons = () => {
<IconDiv data-testid = {SOCIAL_MEDIA_COMPONENT}>
{socialMediaData.map(({ platform, icon, color, link }) => (
<a key={platform} href={link} target="_blank" rel="noopener noreferrer">
<FontAwesomeIcon icon={icon} style={{ color }} />
<FontAwesomeIcon icon={icon} style={{ color }} className='wave' />
</a>
))}
</IconDiv>
Expand Down
13 changes: 12 additions & 1 deletion frontend/src/interfaces/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { ButtonProps, TypographyProps } from "@mui/material";
import { CSSProperties } from "react";
import { CSSProperties, ReactElement } from "react";

export interface IButtonProps extends ButtonProps {}
export interface ITypgraphyProps extends TypographyProps {
Expand All @@ -21,4 +21,15 @@ export interface IDarkModeToggle {
export interface DarkModeContextProps {
isDark: boolean;
toggleMode: () => void;
}
export interface IChipProp {
label?: string
variant?: 'filled' | 'outlined',
size?: 'medium' | 'small',
color?: 'primary'| 'secondary'| 'warning'| 'error'| 'info'| 'default'| 'success',
text?: string
src?: string
avatar?: ReactElement
onClick?:() => void
style?:React.CSSProperties;
}
43 changes: 43 additions & 0 deletions frontend/src/pages/About/index.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React from 'react';
import About from '.';
import { render, screen, cleanup } from '@testing-library/react';
import "@testing-library/jest-dom"
import { ABOUT_COMPONENT, ABOUT_DESC, ABOUT_SUB_DESC, ABOUT_SUB_FOOTER_DESC, ICON_ABOUT_ALT } from '../../utils/constants';

describe('About Component', () => {
beforeEach(() => {
render(<About />);
});

afterEach(cleanup);

it('renders the About component', () => {
const aboutElement = screen.getByTestId(ABOUT_COMPONENT);
expect(aboutElement).toBeInTheDocument();
});

it('renders the image', () => {
const imageElement = screen.getByAltText(ICON_ABOUT_ALT);
expect(imageElement).toBeInTheDocument();
});

it('renders the chip with label Software Engineer', () => {
const chipElement = screen.getByText('<Software Engineer />');
expect(chipElement).toBeInTheDocument();
});

it('renders the description', () => {
const descriptionElement = screen.getByText(ABOUT_DESC);
expect(descriptionElement).toBeInTheDocument();
});

it('renders the sub-description', () => {
const subDescriptionElement = screen.getByText(ABOUT_SUB_DESC);
expect(subDescriptionElement).toBeInTheDocument();
});

it('renders the skills', () => {
const skillElement = screen.getByText('🌐 Frontend Development');
expect(skillElement).toBeInTheDocument();
});
});
Loading