├── .gitignore ├── .storybook ├── main.js ├── preview.js └── webpack.config.js ├── README.md ├── package-lock.json ├── package.json ├── public ├── favicon.ico ├── index.html ├── logo192.png ├── logo512.png ├── manifest.json ├── profile_photo.jpeg └── robots.txt ├── src ├── App.test.tsx ├── App.tsx ├── ColorModeSwitcher.tsx ├── Logo.tsx ├── feature │ ├── Home │ │ ├── Components │ │ │ ├── Introduction │ │ │ │ └── Introduction.tsx │ │ │ └── Post │ │ │ │ ├── Post.tsx │ │ │ │ └── PostItem.tsx │ │ ├── Home.styles.ts │ │ └── Home.tsx │ └── Layout │ │ └── LayoutPage.tsx ├── foundation │ ├── Footer │ │ └── Footer.tsx │ ├── NavBar │ │ └── NavBar.tsx │ ├── PFAvatar │ │ └── PFAvatar.tsx │ ├── PFButton │ │ └── PFButton.tsx │ ├── PFHeading │ │ └── PFHeading.tsx │ ├── PFIconButton │ │ └── PFIconButton.tsx │ ├── PFParagraph │ │ └── PFParagraph.tsx │ ├── Work │ │ ├── Work.tsx │ │ └── WorkItem.tsx │ ├── index.ts │ └── theme │ │ └── Spacing.tsx ├── index.tsx ├── logo.svg ├── react-app-env.d.ts ├── reportWebVitals.ts ├── routes │ └── routes.ts ├── serviceWorker.ts ├── setupTests.ts ├── store │ └── store.ts ├── stories │ ├── PFButton │ │ └── PFbutton.stories.tsx │ ├── PFHeading │ │ └── PFHeading.stories.tsx │ ├── PFIconButton │ │ └── PFIconButton.stories.tsx │ ├── PFParagraph │ │ └── PFParagraph.stories.tsx │ └── assets │ │ ├── code-brackets.svg │ │ ├── colors.svg │ │ ├── comments.svg │ │ ├── direction.svg │ │ ├── flow.svg │ │ ├── plugin.svg │ │ ├── repo.svg │ │ └── stackalt.svg ├── test-utils.tsx ├── test │ ├── CardItem │ │ └── CardItem.tsx │ ├── HomePage │ │ ├── HomePage.tsx │ │ └── components │ │ │ └── HomePageBody.tsx │ └── service │ │ └── charachter.slice.ts └── theme.ts └── tsconfig.json /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /.storybook/main.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | const toPath = _path => path.join(process.cwd(), _path); 3 | 4 | module.exports = { 5 | stories: [ 6 | "../src/**/*.stories.mdx", 7 | "../src/**/*.stories.@(js|jsx|ts|tsx)", 8 | ], 9 | addons: [ 10 | "@storybook/addon-links", 11 | "@storybook/addon-essentials", 12 | "@storybook/preset-create-react-app", 13 | ], 14 | typescript: { 15 | reactDocgen: "react-docgen-typescript", 16 | reactDocgenTypescriptOptions: { 17 | compilerOptions: { 18 | allowSyntheticDefaultImports: false, 19 | esModuleInterop: false, 20 | }, 21 | }, 22 | }, 23 | webpackFinal: async config => { 24 | return { 25 | ...config, 26 | resolve: { 27 | ...config.resolve, 28 | alias: { 29 | ...config.resolve.alias, 30 | "@emotion/core": toPath("node_modules/@emotion/react"), 31 | "emotion-theming": toPath("node_modules/@emotion/react"), 32 | }, 33 | }, 34 | }; 35 | }, 36 | }; -------------------------------------------------------------------------------- /.storybook/preview.js: -------------------------------------------------------------------------------- 1 | import { ChakraProvider } from "@chakra-ui/react"; 2 | import {addDecorator} from "@storybook/react" 3 | import customTheme from "../src/theme" 4 | 5 | addDecorator(story=>( 6 | {story()} 7 | )); 8 | 9 | export const parameters = { 10 | actions: { argTypesRegex: "^on[A-Z].*" }, 11 | viewMode: "docs" 12 | } -------------------------------------------------------------------------------- /.storybook/webpack.config.js: -------------------------------------------------------------------------------- 1 | const path = require("path"); 2 | 3 | module.exports = async ({ config }) => { 4 | 5 | config.module.rules.push({ 6 | test: /\.(png|woff|woff2|eot|ttf)$/, 7 | use: [ 8 | { 9 | loader: "file-loader", 10 | query: { 11 | name: "[name].[ext]", 12 | }, 13 | }, 14 | ], 15 | include: path.resolve(__dirname, "../"), 16 | }); 17 | 18 | return config; 19 | }; -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #Readme will be added soon 2 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "portfolio", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "@chakra-ui/react": "^1.0.0", 7 | "@emotion/react": "^11.0.0", 8 | "@emotion/styled": "^11.0.0", 9 | "@reduxjs/toolkit": "^1.7.2", 10 | "@testing-library/jest-dom": "^5.9.0", 11 | "@testing-library/react": "^10.2.1", 12 | "@testing-library/user-event": "^12.0.2", 13 | "@types/jest": "^25.0.0", 14 | "@types/node": "^12.0.0", 15 | "@types/react": "^16.9.0", 16 | "@types/react-dom": "^16.9.0", 17 | "axios": "^0.25.0", 18 | "babel-loader": "8.1.0", 19 | "framer-motion": "^4.0.0", 20 | "react": "^17.0.2", 21 | "react-dom": "^17.0.2", 22 | "react-icons": "^3.0.0", 23 | "react-redux": "^7.2.6", 24 | "react-router-dom": "^6.2.1", 25 | "react-scripts": "4.0.3", 26 | "typescript": "^3.9.5", 27 | "web-vitals": "^0.2.2" 28 | }, 29 | "scripts": { 30 | "start": "react-scripts start", 31 | "build": "react-scripts build", 32 | "test": "react-scripts test", 33 | "eject": "react-scripts eject", 34 | "storybook": "start-storybook -p 6006 -s public", 35 | "build-storybook": "build-storybook -s public" 36 | }, 37 | "eslintConfig": { 38 | "extends": "react-app", 39 | "overrides": [ 40 | { 41 | "files": [ 42 | "**/*.stories.*" 43 | ], 44 | "rules": { 45 | "import/no-anonymous-default-export": "off" 46 | } 47 | } 48 | ] 49 | }, 50 | "browserslist": { 51 | "production": [ 52 | ">0.2%", 53 | "not dead", 54 | "not op_mini all" 55 | ], 56 | "development": [ 57 | "last 1 chrome version", 58 | "last 1 firefox version", 59 | "last 1 safari version" 60 | ] 61 | }, 62 | "devDependencies": { 63 | "@storybook/addon-actions": "^6.3.12", 64 | "@storybook/addon-essentials": "^6.3.12", 65 | "@storybook/addon-links": "^6.3.12", 66 | "@storybook/node-logger": "^6.3.12", 67 | "@storybook/preset-create-react-app": "^3.2.0", 68 | "@storybook/react": "^6.3.12", 69 | "babel-loader": "8.1.0" 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevStack06/React-Portfolio-ChakraUI-Typescript/9d5adae27bea63c097de2162a8e54e672d775af0/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 17 | 18 | 27 | React App 28 | 29 | 30 | 31 |
32 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevStack06/React-Portfolio-ChakraUI-Typescript/9d5adae27bea63c097de2162a8e54e672d775af0/public/logo192.png -------------------------------------------------------------------------------- /public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevStack06/React-Portfolio-ChakraUI-Typescript/9d5adae27bea63c097de2162a8e54e672d775af0/public/logo512.png -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /public/profile_photo.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DevStack06/React-Portfolio-ChakraUI-Typescript/9d5adae27bea63c097de2162a8e54e672d775af0/public/profile_photo.jpeg -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # https://www.robotstxt.org/robotstxt.html 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /src/App.test.tsx: -------------------------------------------------------------------------------- 1 | import React from "react" 2 | import { screen } from "@testing-library/react" 3 | import { render } from "./test-utils" 4 | import { App } from "./App" 5 | 6 | test("renders learn react link", () => { 7 | render() 8 | const linkElement = screen.getByText(/learn chakra/i) 9 | expect(linkElement).toBeInTheDocument() 10 | }) 11 | -------------------------------------------------------------------------------- /src/App.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import { ChakraProvider } from "@chakra-ui/react"; 3 | 4 | import { Provider } from "react-redux"; 5 | import customTheme from "./theme"; 6 | import Home from "./feature/Home/Home"; 7 | import { store } from "./store/store"; 8 | import { BrowserRouter, Route, Routes } from "react-router-dom"; 9 | import { routes } from "./routes/routes"; 10 | import LayoutPage from "./feature/Layout/LayoutPage"; 11 | 12 | export const App = () => ( 13 | 14 | 15 | 16 | 17 | 21 | {" "} 22 | 23 | } 24 | /> 25 | } /> 26 | 27 | 28 | 29 | 30 | ); 31 | -------------------------------------------------------------------------------- /src/ColorModeSwitcher.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import { 3 | useColorMode, 4 | useColorModeValue, 5 | IconButton, 6 | IconButtonProps, 7 | } from "@chakra-ui/react" 8 | import { FaMoon, FaSun } from "react-icons/fa" 9 | 10 | type ColorModeSwitcherProps = Omit 11 | 12 | export const ColorModeSwitcher: React.FC = (props) => { 13 | const { toggleColorMode } = useColorMode() 14 | const text = useColorModeValue("dark", "light") 15 | const SwitchIcon = useColorModeValue(FaMoon, FaSun) 16 | 17 | return ( 18 | } 26 | aria-label={`Switch to ${text} mode`} 27 | {...props} 28 | /> 29 | ) 30 | } 31 | -------------------------------------------------------------------------------- /src/Logo.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import { 3 | chakra, 4 | keyframes, 5 | ImageProps, 6 | forwardRef, 7 | usePrefersReducedMotion, 8 | } from "@chakra-ui/react" 9 | import logo from "./logo.svg" 10 | 11 | const spin = keyframes` 12 | from { transform: rotate(0deg); } 13 | to { transform: rotate(360deg); } 14 | ` 15 | 16 | export const Logo = forwardRef((props, ref) => { 17 | const prefersReducedMotion = usePrefersReducedMotion() 18 | 19 | const animation = prefersReducedMotion 20 | ? undefined 21 | : `${spin} infinite 20s linear` 22 | 23 | return 24 | }) 25 | -------------------------------------------------------------------------------- /src/feature/Home/Components/Introduction/Introduction.tsx: -------------------------------------------------------------------------------- 1 | import { Box, Flex, VStack } from "@chakra-ui/react"; 2 | import React from "react"; 3 | import { 4 | PFHeading, 5 | PFParagraph, 6 | PFButton, 7 | PFAvatar, 8 | } from "../../../../foundation"; 9 | 10 | import { styles } from "../../Home.styles"; 11 | 12 | export default function Introduction() { 13 | return ( 14 | 20 | 21 | 25 | 26 | 30 | 31 | Download Resume 32 | 33 | {/* */} 34 | 35 | 36 | ); 37 | } 38 | -------------------------------------------------------------------------------- /src/feature/Home/Components/Post/Post.tsx: -------------------------------------------------------------------------------- 1 | import { Box, Flex } from "@chakra-ui/react"; 2 | import React from "react"; 3 | import { PFButton, PFParagraph } from "../../../../foundation"; 4 | import { Spacing } from "../../../../foundation/theme/Spacing"; 5 | import { styles } from "../../Home.styles"; 6 | import PostItem from "./PostItem"; 7 | 8 | export default function Post() { 9 | console.log("spacing", Spacing.x3); 10 | return ( 11 | 20 | 21 | 22 | 23 | 29 | {" "} 30 | View all 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | ); 40 | } 41 | -------------------------------------------------------------------------------- /src/feature/Home/Components/Post/PostItem.tsx: -------------------------------------------------------------------------------- 1 | import { Box, Flex } from "@chakra-ui/react"; 2 | import React from "react"; 3 | import { PFHeading, PFParagraph } from "../../../../foundation"; 4 | import { Spacing } from "../../../../foundation/theme/Spacing"; 5 | 6 | export default function PostItem() { 7 | return ( 8 | 16 | 17 | 18 | 25 | 26 | 27 | 28 | 29 | 33 | 34 | 35 | ); 36 | } 37 | -------------------------------------------------------------------------------- /src/feature/Home/Home.styles.ts: -------------------------------------------------------------------------------- 1 | export const styles = { 2 | firstRowContainer: { 3 | alignSelf: "start", 4 | alignItems: "start", 5 | width: "35vw", 6 | }, 7 | containerPadding: { 8 | paddingLeft: "15vw", 9 | paddingRight: "15vw", 10 | }, 11 | containerMargin: { 12 | marginLeft: "15vw", 13 | marginRight: "15vw", 14 | }, 15 | }; 16 | -------------------------------------------------------------------------------- /src/feature/Home/Home.tsx: -------------------------------------------------------------------------------- 1 | import { Box, VStack } from "@chakra-ui/react"; 2 | import React from "react"; 3 | import { Spacing } from "../../foundation/theme/Spacing"; 4 | import Post from "./Components/Post/Post"; 5 | import Introduction from "./Components/Introduction/Introduction"; 6 | import Work from "../../foundation/Work/Work"; 7 | 8 | export default function Home() { 9 | return ( 10 | 11 | 12 | 13 | 14 | 15 | 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /src/feature/Layout/LayoutPage.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import Footer from "../../foundation/Footer/Footer"; 3 | import NavBar from "../../foundation/NavBar/NavBar"; 4 | 5 | export default function LayoutPage({ children }: { children: any }) { 6 | return ( 7 |
8 | 9 | {children} 10 |
11 |
12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /src/foundation/Footer/Footer.tsx: -------------------------------------------------------------------------------- 1 | import { Flex } from "@chakra-ui/react"; 2 | import React from "react"; 3 | import { 4 | FaFacebookSquare, 5 | FaInstagram, 6 | FaLinkedin, 7 | FaTwitter, 8 | } from "react-icons/fa"; 9 | import { PFParagraph } from ".."; 10 | import PFIconButton from "../PFIconButton/PFIconButton"; 11 | import { Spacing } from "../theme/Spacing"; 12 | 13 | export default function Footer() { 14 | return ( 15 | 21 | 22 | } 24 | ariaLabel="facebook button" 25 | onClick={() => {}} 26 | /> 27 | } ariaLabel="insta button" /> 28 | } ariaLabel="insta button" /> 29 | } ariaLabel="insta button" /> 30 | 31 | 32 | 33 | ); 34 | } 35 | -------------------------------------------------------------------------------- /src/foundation/NavBar/NavBar.tsx: -------------------------------------------------------------------------------- 1 | import { Flex } from "@chakra-ui/react"; 2 | import React from "react"; 3 | import { ColorModeSwitcher } from "../../ColorModeSwitcher"; 4 | import PFButton from "../PFButton/PFButton"; 5 | import { Spacing } from "../theme/Spacing"; 6 | 7 | export default function NavBar() { 8 | return ( 9 | 10 | Works 11 | Youtube 12 | Contact 13 | 14 | 15 | 16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /src/foundation/PFAvatar/PFAvatar.tsx: -------------------------------------------------------------------------------- 1 | import { Avatar } from "@chakra-ui/react"; 2 | import React from "react"; 3 | 4 | export default function PFAvatar({ src }: { src: string }) { 5 | return ( 6 | 14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /src/foundation/PFButton/PFButton.tsx: -------------------------------------------------------------------------------- 1 | import { Button } from "@chakra-ui/button"; 2 | import React from "react"; 3 | 4 | type PFButtonType = { 5 | variant?: "ghost" | "solid" | "navBar"; 6 | stylesProps?: Object; 7 | children: any; 8 | OnClick?: any; 9 | }; 10 | 11 | export default function PFButton({ 12 | variant = "solid", 13 | children, 14 | stylesProps = {}, 15 | OnClick, 16 | }: PFButtonType) { 17 | return ( 18 | 21 | ); 22 | } 23 | -------------------------------------------------------------------------------- /src/foundation/PFHeading/PFHeading.tsx: -------------------------------------------------------------------------------- 1 | import { Heading } from "@chakra-ui/react"; 2 | import React from "react"; 3 | 4 | type PFHeadingProps = { 5 | variant: string; 6 | text: string; 7 | }; 8 | 9 | export default function PFHeading({ variant, text }: PFHeadingProps) { 10 | return ( 11 | 12 | {text} 13 | 14 | ); 15 | } 16 | -------------------------------------------------------------------------------- /src/foundation/PFIconButton/PFIconButton.tsx: -------------------------------------------------------------------------------- 1 | import { IconButton } from "@chakra-ui/button"; 2 | import React from "react"; 3 | import { Spacing } from "../theme/Spacing"; 4 | 5 | type PFIconButtonProps = { 6 | icon: React.ReactElement; 7 | ariaLabel: string; 8 | onClick?: any; 9 | }; 10 | 11 | export default function PFIconButton({ 12 | icon, 13 | ariaLabel, 14 | onClick, 15 | }: PFIconButtonProps) { 16 | return ( 17 | 27 | ); 28 | } 29 | -------------------------------------------------------------------------------- /src/foundation/PFParagraph/PFParagraph.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import { Text } from "@chakra-ui/react"; 3 | 4 | type PFParagraphProps = { 5 | variant: string; 6 | text: string; 7 | }; 8 | export default function PFParagraph({ variant, text }: PFParagraphProps) { 9 | return {text}; 10 | } 11 | -------------------------------------------------------------------------------- /src/foundation/Work/Work.tsx: -------------------------------------------------------------------------------- 1 | import { Flex } from "@chakra-ui/react"; 2 | import React from "react"; 3 | import PFParagraph from "../PFParagraph/PFParagraph"; 4 | import WorkItem from "./WorkItem"; 5 | 6 | export default function Work() { 7 | return ( 8 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | ); 23 | } 24 | -------------------------------------------------------------------------------- /src/foundation/Work/WorkItem.tsx: -------------------------------------------------------------------------------- 1 | import { Box, Divider, Flex, Tag, Image } from "@chakra-ui/react"; 2 | import React from "react"; 3 | import { PFHeading, PFParagraph } from ".."; 4 | import { Spacing } from "../theme/Spacing"; 5 | 6 | export default function WorkItem() { 7 | return ( 8 | 14 | 19 | 28 | 29 | 30 | 31 | 32 | 39 | 45 | 2020 46 | 47 | 48 | 49 | 53 | 54 | 55 | 56 | 57 | ); 58 | } 59 | -------------------------------------------------------------------------------- /src/foundation/index.ts: -------------------------------------------------------------------------------- 1 | import PFAvatar from "./PFAvatar/PFAvatar"; 2 | import PFButton from "./PFButton/PFButton"; 3 | import PFHeading from "./PFHeading/PFHeading"; 4 | import PFIconButton from "./PFIconButton/PFIconButton"; 5 | import PFParagraph from "./PFParagraph/PFParagraph"; 6 | 7 | export { PFAvatar, PFButton, PFHeading, PFIconButton, PFParagraph }; 8 | -------------------------------------------------------------------------------- /src/foundation/theme/Spacing.tsx: -------------------------------------------------------------------------------- 1 | const baseSpacing = 8; 2 | export const Spacing = { 3 | xp25: baseSpacing * 0.25 + "px", 4 | xp5: baseSpacing * 0.5 + "px", 5 | x1: baseSpacing + "px", 6 | x1p5: baseSpacing * 1.5 + "px", 7 | x2: baseSpacing * 2 + "px", 8 | x2p5: baseSpacing * 2.5 + "px", 9 | x3: baseSpacing * 3 + "px", 10 | x5: baseSpacing * 5 + "px", 11 | x4: baseSpacing * 4 + "px", 12 | x6: baseSpacing * 6 + "px", 13 | x7: baseSpacing * 7 + "px", 14 | x8: baseSpacing * 8 + "px", 15 | x9: baseSpacing * 9 + "px", 16 | x10: baseSpacing * 10 + "px", 17 | x11: baseSpacing * 11 + "px", 18 | x12: baseSpacing * 12 + "px", 19 | x15: baseSpacing * 15 + "px", 20 | }; 21 | -------------------------------------------------------------------------------- /src/index.tsx: -------------------------------------------------------------------------------- 1 | import { ColorModeScript } from "@chakra-ui/react" 2 | import * as React from "react" 3 | import ReactDOM from "react-dom" 4 | import { App } from "./App" 5 | import reportWebVitals from "./reportWebVitals" 6 | import * as serviceWorker from "./serviceWorker" 7 | 8 | ReactDOM.render( 9 | 10 | 11 | 12 | , 13 | document.getElementById("root"), 14 | ) 15 | 16 | // If you want your app to work offline and load faster, you can change 17 | // unregister() to register() below. Note this comes with some pitfalls. 18 | // Learn more about service workers: https://cra.link/PWA 19 | serviceWorker.unregister() 20 | 21 | // If you want to start measuring performance in your app, pass a function 22 | // to log results (for example: reportWebVitals(console.log)) 23 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals 24 | reportWebVitals() 25 | -------------------------------------------------------------------------------- /src/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /src/react-app-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /src/reportWebVitals.ts: -------------------------------------------------------------------------------- 1 | import { ReportHandler } from "web-vitals" 2 | 3 | const reportWebVitals = (onPerfEntry?: ReportHandler) => { 4 | if (onPerfEntry && onPerfEntry instanceof Function) { 5 | import("web-vitals").then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => { 6 | getCLS(onPerfEntry) 7 | getFID(onPerfEntry) 8 | getFCP(onPerfEntry) 9 | getLCP(onPerfEntry) 10 | getTTFB(onPerfEntry) 11 | }) 12 | } 13 | } 14 | 15 | export default reportWebVitals 16 | -------------------------------------------------------------------------------- /src/routes/routes.ts: -------------------------------------------------------------------------------- 1 | export const routes = { 2 | home: "/home", 3 | }; 4 | -------------------------------------------------------------------------------- /src/serviceWorker.ts: -------------------------------------------------------------------------------- 1 | // This optional code is used to register a service worker. 2 | // register() is not called by default. 3 | 4 | // This lets the app load faster on subsequent visits in production, and gives 5 | // it offline capabilities. However, it also means that developers (and users) 6 | // will only see deployed updates on subsequent visits to a page, after all the 7 | // existing tabs open on the page have been closed, since previously cached 8 | // resources are updated in the background. 9 | 10 | // To learn more about the benefits of this model and instructions on how to 11 | // opt-in, read https://cra.link/PWA 12 | 13 | const isLocalhost = Boolean( 14 | window.location.hostname === "localhost" || 15 | // [::1] is the IPv6 localhost address. 16 | window.location.hostname === "[::1]" || 17 | // 127.0.0.0/8 are considered localhost for IPv4. 18 | window.location.hostname.match( 19 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/, 20 | ), 21 | ) 22 | 23 | type Config = { 24 | onSuccess?: (registration: ServiceWorkerRegistration) => void 25 | onUpdate?: (registration: ServiceWorkerRegistration) => void 26 | } 27 | 28 | export function register(config?: Config) { 29 | if (process.env.NODE_ENV === "production" && "serviceWorker" in navigator) { 30 | // The URL constructor is available in all browsers that support SW. 31 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href) 32 | if (publicUrl.origin !== window.location.origin) { 33 | // Our service worker won't work if PUBLIC_URL is on a different origin 34 | // from what our page is served on. This might happen if a CDN is used to 35 | // serve assets; see https://github.com/facebook/create-react-app/issues/2374 36 | return 37 | } 38 | 39 | window.addEventListener("load", () => { 40 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js` 41 | 42 | if (isLocalhost) { 43 | // This is running on localhost. Let's check if a service worker still exists or not. 44 | checkValidServiceWorker(swUrl, config) 45 | 46 | // Add some additional logging to localhost, pointing developers to the 47 | // service worker/PWA documentation. 48 | navigator.serviceWorker.ready.then(() => { 49 | console.log( 50 | "This web app is being served cache-first by a service " + 51 | "worker. To learn more, visit https://cra.link/PWA", 52 | ) 53 | }) 54 | } else { 55 | // Is not localhost. Just register service worker 56 | registerValidSW(swUrl, config) 57 | } 58 | }) 59 | } 60 | } 61 | 62 | function registerValidSW(swUrl: string, config?: Config) { 63 | navigator.serviceWorker 64 | .register(swUrl) 65 | .then((registration) => { 66 | registration.onupdatefound = () => { 67 | const installingWorker = registration.installing 68 | if (installingWorker == null) { 69 | return 70 | } 71 | installingWorker.onstatechange = () => { 72 | if (installingWorker.state === "installed") { 73 | if (navigator.serviceWorker.controller) { 74 | // At this point, the updated precached content has been fetched, 75 | // but the previous service worker will still serve the older 76 | // content until all client tabs are closed. 77 | console.log( 78 | "New content is available and will be used when all " + 79 | "tabs for this page are closed. See https://cra.link/PWA.", 80 | ) 81 | 82 | // Execute callback 83 | if (config && config.onUpdate) { 84 | config.onUpdate(registration) 85 | } 86 | } else { 87 | // At this point, everything has been precached. 88 | // It is the perfect time to display a 89 | // "Content is cached for offline use." message. 90 | console.log("Content is cached for offline use.") 91 | 92 | // Execute callback 93 | if (config && config.onSuccess) { 94 | config.onSuccess(registration) 95 | } 96 | } 97 | } 98 | } 99 | } 100 | }) 101 | .catch((error) => { 102 | console.error("Error during service worker registration:", error) 103 | }) 104 | } 105 | 106 | function checkValidServiceWorker(swUrl: string, config?: Config) { 107 | // Check if the service worker can be found. If it can't reload the page. 108 | fetch(swUrl, { 109 | headers: { "Service-Worker": "script" }, 110 | }) 111 | .then((response) => { 112 | // Ensure service worker exists, and that we really are getting a JS file. 113 | const contentType = response.headers.get("content-type") 114 | if ( 115 | response.status === 404 || 116 | (contentType != null && contentType.indexOf("javascript") === -1) 117 | ) { 118 | // No service worker found. Probably a different app. Reload the page. 119 | navigator.serviceWorker.ready.then((registration) => { 120 | registration.unregister().then(() => { 121 | window.location.reload() 122 | }) 123 | }) 124 | } else { 125 | // Service worker found. Proceed as normal. 126 | registerValidSW(swUrl, config) 127 | } 128 | }) 129 | .catch(() => { 130 | console.log( 131 | "No internet connection found. App is running in offline mode.", 132 | ) 133 | }) 134 | } 135 | 136 | export function unregister() { 137 | if ("serviceWorker" in navigator) { 138 | navigator.serviceWorker.ready 139 | .then((registration) => { 140 | registration.unregister() 141 | }) 142 | .catch((error) => { 143 | console.error(error.message) 144 | }) 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /src/setupTests.ts: -------------------------------------------------------------------------------- 1 | // jest-dom adds custom jest matchers for asserting on DOM nodes. 2 | // allows you to do things like: 3 | // expect(element).toHaveTextContent(/react/i) 4 | // learn more: https://github.com/testing-library/jest-dom 5 | import "@testing-library/jest-dom" 6 | -------------------------------------------------------------------------------- /src/store/store.ts: -------------------------------------------------------------------------------- 1 | import { configureStore } from "@reduxjs/toolkit"; 2 | import avatarReducer from "../test/service/charachter.slice"; 3 | 4 | export const store = configureStore({ 5 | reducer: { 6 | counter: avatarReducer, 7 | }, 8 | }); 9 | 10 | // Infer the `RootState` and `AppDispatch` types from the store itself 11 | export type RootState = ReturnType; 12 | // Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState} 13 | export type AppDispatch = typeof store.dispatch; 14 | -------------------------------------------------------------------------------- /src/stories/PFButton/PFbutton.stories.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import PFButton from "../../foundation/PFButton/PFButton"; 3 | 4 | export default { 5 | title: "Foundation/PFButton", 6 | component: PFButton, 7 | }; 8 | 9 | export const Default = () => { 10 | return ( 11 | {}} 19 | > 20 | Download Resume 21 | 22 | ); 23 | }; 24 | 25 | export const GhostButton = () => { 26 | return ( 27 | 34 | View All 35 | 36 | ); 37 | }; 38 | -------------------------------------------------------------------------------- /src/stories/PFHeading/PFHeading.stories.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import PFHeading from "../../foundation/PFHeading/PFHeading"; 3 | 4 | export default { 5 | title: "Foundation/PFHeading", 6 | component: PFHeading, 7 | }; 8 | 9 | export const Default = () => { 10 | return ; 11 | }; 12 | export const Heading2 = () => { 13 | return ; 14 | }; 15 | 16 | export const Heading3 = () => { 17 | return ; 18 | }; 19 | 20 | export const Heading4 = () => { 21 | return ; 22 | }; 23 | -------------------------------------------------------------------------------- /src/stories/PFIconButton/PFIconButton.stories.tsx: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | import PFIconButton from "../../foundation/PFIconButton/PFIconButton"; 3 | import { 4 | FaFacebookSquare, 5 | FaInstagram, 6 | FaLinkedin, 7 | FaTwitter, 8 | } from "react-icons/fa"; 9 | 10 | export default { 11 | title: "Foundation/PFIconButton", 12 | component: PFIconButton, 13 | }; 14 | 15 | export const Default = () => { 16 | return ( 17 | } 19 | ariaLabel="facebook button" 20 | onClick={() => {}} 21 | /> 22 | ); 23 | }; 24 | 25 | export const InstaIconButton = () => { 26 | return } ariaLabel="insta button" />; 27 | }; 28 | 29 | export const TwitterIconButton = () => { 30 | return } ariaLabel="insta button" />; 31 | }; 32 | 33 | export const LinkedInIconButton = () => { 34 | return } ariaLabel="insta button" />; 35 | }; 36 | -------------------------------------------------------------------------------- /src/stories/PFParagraph/PFParagraph.stories.tsx: -------------------------------------------------------------------------------- 1 | import PFParagraph from "../../foundation/PFParagraph/PFParagraph"; 2 | import React from "react"; 3 | 4 | export default { 5 | title: "Foundation/PFParagraph", 6 | component: PFParagraph, 7 | }; 8 | 9 | export const Default = () => { 10 | return ; 11 | }; 12 | 13 | export const Paragraph2 = () => { 14 | return ; 15 | }; 16 | export const Paragraph3 = () => { 17 | return ; 18 | }; 19 | 20 | export const Paragraph4 = () => { 21 | return ; 22 | }; 23 | 24 | export const Paragraph5 = () => { 25 | return ; 26 | }; 27 | export const Paragraph6 = () => { 28 | return ; 29 | }; 30 | -------------------------------------------------------------------------------- /src/stories/assets/code-brackets.svg: -------------------------------------------------------------------------------- 1 | illustration/code-brackets -------------------------------------------------------------------------------- /src/stories/assets/colors.svg: -------------------------------------------------------------------------------- 1 | illustration/colors -------------------------------------------------------------------------------- /src/stories/assets/comments.svg: -------------------------------------------------------------------------------- 1 | illustration/comments -------------------------------------------------------------------------------- /src/stories/assets/direction.svg: -------------------------------------------------------------------------------- 1 | illustration/direction -------------------------------------------------------------------------------- /src/stories/assets/flow.svg: -------------------------------------------------------------------------------- 1 | illustration/flow -------------------------------------------------------------------------------- /src/stories/assets/plugin.svg: -------------------------------------------------------------------------------- 1 | illustration/plugin -------------------------------------------------------------------------------- /src/stories/assets/repo.svg: -------------------------------------------------------------------------------- 1 | illustration/repo -------------------------------------------------------------------------------- /src/stories/assets/stackalt.svg: -------------------------------------------------------------------------------- 1 | illustration/stackalt -------------------------------------------------------------------------------- /src/test-utils.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react" 2 | import { render, RenderOptions } from "@testing-library/react" 3 | import { ChakraProvider, theme } from "@chakra-ui/react" 4 | 5 | const AllProviders = ({ children }: { children?: React.ReactNode }) => ( 6 | {children} 7 | ) 8 | 9 | const customRender = (ui: React.ReactElement, options?: RenderOptions) => 10 | render(ui, { wrapper: AllProviders, ...options }) 11 | 12 | export { customRender as render } 13 | -------------------------------------------------------------------------------- /src/test/CardItem/CardItem.tsx: -------------------------------------------------------------------------------- 1 | import { Badge, Box, Image } from "@chakra-ui/react"; 2 | import React from "react"; 3 | 4 | export default function CardItem({ ele }) { 5 | const property = { 6 | imageUrl: "https://bit.ly/2Z4KKcF", 7 | imageAlt: "Rear view of modern home with pool", 8 | beds: 3, 9 | baths: 2, 10 | title: "Modern home in city center in the heart of historic Los Angeles", 11 | formattedPrice: "$1,900.00", 12 | reviewCount: 34, 13 | rating: 4, 14 | }; 15 | 16 | return ( 17 | 18 | {property.imageAlt} 19 | 20 | 21 | 22 | 23 | New 24 | 25 | 26 | 27 | 34 | {ele.name} 35 | 36 | 37 | {ele.status} 38 | {ele.gender} 39 | 40 | 41 | ); 42 | } 43 | -------------------------------------------------------------------------------- /src/test/HomePage/HomePage.tsx: -------------------------------------------------------------------------------- 1 | import { VStack } from "@chakra-ui/react"; 2 | import React from "react"; 3 | import NavBar from "../../foundation/NavBar/NavBar"; 4 | import HomePageBody from "./components/HomePageBody"; 5 | 6 | export default function HomePage() { 7 | return ( 8 | 9 | 10 | 11 | 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /src/test/HomePage/components/HomePageBody.tsx: -------------------------------------------------------------------------------- 1 | import { Box, Button, HStack, VStack } from "@chakra-ui/react"; 2 | import React, { useEffect, useState } from "react"; 3 | import { useDispatch, useSelector } from "react-redux"; 4 | import { RootState } from "../../../store/store"; 5 | import CardItem from "../../CardItem/CardItem"; 6 | import { fetchAvatar } from "../../service/charachter.slice"; 7 | 8 | export default function HomePageBody() { 9 | const count = useSelector((state: RootState) => state.counter.avatar); 10 | const { results } = count; 11 | const dispachEvent = useDispatch(); 12 | const [filterValeu, setFilter] = useState([]); 13 | 14 | useEffect(() => { 15 | dispachEvent(fetchAvatar()); 16 | }, []); 17 | console.log("here", count); 18 | 19 | const filter = (filterType: string) => { 20 | let filterData = []; 21 | if ((filterType = "Male")) { 22 | filterData = results.filter((ele) => ele.gender == filterType); 23 | setFilter(filterData); 24 | } else { 25 | filterData = results.filter((ele) => ele.gender == filterType); 26 | setFilter(filterData); 27 | } 28 | }; 29 | 30 | const renderData = (records) => { 31 | return records?.map((ele) => { 32 | return ; 33 | }); 34 | }; 35 | 36 | return ( 37 | 38 | 39 | {/* */} 40 | 41 | 42 | {/* */} 43 | 44 | 45 | {renderData(filterValeu.length > 0 ? filterValeu : results)} 46 | 47 | 48 | ); 49 | } 50 | -------------------------------------------------------------------------------- /src/test/service/charachter.slice.ts: -------------------------------------------------------------------------------- 1 | import { createAsyncThunk, createSlice } from "@reduxjs/toolkit"; 2 | import axios from "axios"; 3 | 4 | export interface CounterState { 5 | avatar: Array; 6 | filterData: Array; 7 | } 8 | 9 | const initialState: CounterState = { 10 | avatar: [], 11 | filterData: [], 12 | }; 13 | 14 | export const fetchAvatar = createAsyncThunk( 15 | "avatar", 16 | async (pageNum, thunkAPI) => { 17 | const response = await axios.get( 18 | "https://rickandmortyapi.com/api/character?page=2" 19 | ); 20 | console.log("here is the d", response.data); 21 | thunkAPI.dispatch(setData(response.data)); 22 | return response.data; 23 | } 24 | ); 25 | 26 | export const avatarSlice = createSlice({ 27 | name: "avatar", 28 | initialState, 29 | reducers: { 30 | setData: (state, action) => { 31 | state.avatar = action.payload; 32 | }, 33 | filter: (state, action) => { 34 | state.avatar = action.payload; 35 | }, 36 | }, 37 | }); 38 | 39 | // Action creators are generated for each case reducer function 40 | export const { setData } = avatarSlice.actions; 41 | 42 | export default avatarSlice.reducer; 43 | -------------------------------------------------------------------------------- /src/theme.ts: -------------------------------------------------------------------------------- 1 | import { extendTheme } from "@chakra-ui/react"; 2 | 3 | const customTheme = extendTheme({ 4 | colors: { 5 | primary: "#FF6464", 6 | secondary: "#00A8CC", 7 | darkColor: "#21243D", 8 | lightColor: "#8695A4", 9 | whiteColor: " #FFFFFF", 10 | backgroundColor: "#E5E5E5", 11 | backgroundColor2: "#EDF7FA", 12 | tagColor: "#142850", 13 | }, 14 | components: { 15 | Button: { 16 | variants: { 17 | solid: { 18 | backgroundColor: "primary", 19 | color: "whiteColor", 20 | }, 21 | ghost: { 22 | color: "secondary", 23 | }, 24 | navBar: { 25 | color: "darkColor", 26 | fontSize: "18px", 27 | lineHeight: "29px", 28 | }, 29 | }, 30 | }, 31 | Heading: { 32 | variants: { 33 | "1": { 34 | fontSize: "44px", 35 | lineHeight: "60px", 36 | }, 37 | "2": { 38 | fontSize: "34px", 39 | lineHeight: "50px", 40 | }, 41 | "3": { 42 | fontSize: "30px", 43 | lineHeight: "44px", 44 | }, 45 | "4": { 46 | fontSize: "26px", 47 | lineHeight: "38px", 48 | }, 49 | }, 50 | }, 51 | Text: { 52 | variants: { 53 | "1": { 54 | fontSize: "16px", 55 | lineHeight: "23px", 56 | color: "darkColor", 57 | }, 58 | "2": { 59 | fontSize: "22px", 60 | lineHeight: "60px", 61 | color: "darkColor", 62 | }, 63 | "3": { 64 | fontSize: "18px", 65 | lineHeight: "26px", 66 | color: "darkColor", 67 | }, 68 | "4": { 69 | fontSize: "20px", 70 | lineHeight: "29.3px", 71 | color: "lightColor", 72 | }, 73 | "5": { 74 | fontSize: "14px", 75 | lineHeight: "20.5px", 76 | color: "darkColor", 77 | }, 78 | "6": { 79 | fontSize: "20px", 80 | lineHeight: "29.38px", 81 | color: "darkColor", 82 | }, 83 | "7": { 84 | fontSize: "16px", 85 | fontWeight: 400, 86 | lineHeight: "23.5px", 87 | color: "darkColor", 88 | }, 89 | }, 90 | }, 91 | }, 92 | }); 93 | 94 | export default customTheme; 95 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": [ 5 | "dom", 6 | "dom.iterable", 7 | "esnext" 8 | ], 9 | "allowJs": true, 10 | "skipLibCheck": true, 11 | "esModuleInterop": true, 12 | "allowSyntheticDefaultImports": true, 13 | "strict": true, 14 | "forceConsistentCasingInFileNames": true, 15 | "noFallthroughCasesInSwitch": true, 16 | "module": "esnext", 17 | "moduleResolution": "node", 18 | "resolveJsonModule": true, 19 | "isolatedModules": true, 20 | "noEmit": true, 21 | "jsx": "react" 22 | }, 23 | "include": [ 24 | "src" 25 | ] 26 | } 27 | --------------------------------------------------------------------------------