├── .eslintrc.json ├── .gitignore ├── README.md ├── components ├── Button.jsx ├── Container.jsx ├── FooterLink.jsx ├── FooterTitle.jsx ├── HeroFeature.jsx ├── IconList.jsx ├── IllustrationCard.jsx ├── IntroCard.jsx ├── LangCard.jsx ├── Link.jsx ├── Navbar.jsx ├── PricingCard.jsx ├── SectionBadge.jsx ├── SectionDescription.jsx ├── SectionTitle.jsx ├── SocialLink.jsx ├── SquareList.jsx ├── TestimonialCard.jsx └── index.js ├── jsconfig.json ├── package-lock.json ├── package.json ├── pages ├── _app.js ├── _document.jsx └── index.jsx ├── postcss.config.js ├── public ├── favicon.ico ├── github.svg ├── hotjar.svg ├── illustration-1.png ├── illustration-2.png ├── illustration-3.png ├── illustration-4.png ├── javascript.svg ├── jquery.svg ├── logo.png ├── nodejs.svg ├── react.svg ├── redux.svg ├── sass.svg ├── tailwindcss.svg └── vercel.svg ├── styles ├── Home.module.css └── globals.css ├── tailwind.config.js └── yarn.lock /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": true, 4 | "es2021": true, 5 | "node": true 6 | }, 7 | "extends": [ 8 | "eslint:recommended", 9 | "plugin:react/recommended", "plugin:jsx-a11y/recommended", 10 | "plugin:prettier/recommended" 11 | ], 12 | "parserOptions": { 13 | "ecmaFeatures": { 14 | "jsx": true 15 | }, 16 | "ecmaVersion": 12, 17 | "sourceType": "module" 18 | }, 19 | "plugins": [ 20 | "react", 21 | "jsx-a11y", 22 | "simple-import-sort", 23 | "import" 24 | ], 25 | "rules": { 26 | "simple-import-sort/imports": "error", 27 | "simple-import-sort/exports": "error", 28 | "indent": [ 29 | "error", 30 | 2 31 | ], 32 | "linebreak-style": [ 33 | "error", 34 | "unix" 35 | ], 36 | "quotes": [ 37 | "error", 38 | "single" 39 | ], 40 | "semi": [ 41 | "error", 42 | "always" 43 | ], 44 | "react/react-in-jsx-scope": "off", 45 | "react/jsx-filename-extension": [ 46 | 1, 47 | { 48 | "extensions": [".js", ".jsx"] 49 | } 50 | ], 51 | "react/display-name": 1, 52 | "react/jsx-props-no-spreading": "off", 53 | "react/self-closing-comp": ["error", { 54 | "component": true, 55 | "html": true 56 | }], 57 | "jsx-a11y/anchor-is-valid": [ 58 | "error", 59 | { 60 | "components": ["Link"], 61 | "specialLink": ["hrefLeft", "hrefRight"], 62 | "aspects": ["invalidHref", "preferButton"] 63 | } 64 | ], 65 | "import/prefer-default-export": "off", 66 | "import/newline-after-import": "error", 67 | "import/no-unresolved": ["error", { "ignore": ["@"] } ] 68 | }, 69 | "settings": { 70 | "import/resolver": { 71 | "node": { 72 | "extensions": [".js", ".jsx", ".ts", ".tsx"] 73 | } 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /.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 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | # local env files 28 | .env.local 29 | .env.development.local 30 | .env.test.local 31 | .env.production.local 32 | 33 | # vercel 34 | .vercel 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). 2 | 3 | ## Getting Started 4 | 5 | First, run the development server: 6 | 7 | ```bash 8 | npm run dev 9 | # or 10 | yarn dev 11 | ``` 12 | 13 | Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. 14 | 15 | You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file. 16 | 17 | [API routes](https://nextjs.org/docs/api-routes/introduction) can be accessed on [http://localhost:3000/api/hello](http://localhost:3000/api/hello). This endpoint can be edited in `pages/api/hello.js`. 18 | 19 | The `pages/api` directory is mapped to `/api/*`. Files in this directory are treated as [API routes](https://nextjs.org/docs/api-routes/introduction) instead of React pages. 20 | 21 | ## Learn More 22 | 23 | To learn more about Next.js, take a look at the following resources: 24 | 25 | - [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. 26 | - [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. 27 | 28 | You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! 29 | 30 | ## Deploy on Vercel 31 | 32 | The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. 33 | 34 | Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. 35 | -------------------------------------------------------------------------------- /components/Button.jsx: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | 3 | import Link from './Link'; 4 | 5 | function Button({ 6 | tagName, 7 | href, 8 | children, 9 | size, 10 | wide, 11 | variant, 12 | className: addClassName, 13 | external, 14 | ...props 15 | }) { 16 | const baseClass = ` 17 | inline-flex 18 | font-bold 19 | border-2 20 | rounded-lg 21 | transition-all 22 | `; 23 | 24 | const sizes = { 25 | small: 'py-2 px-5', 26 | normal: 'px-6 py-3', 27 | }; 28 | 29 | const variants = { 30 | solidBlue: 'text-white bg-blue-500 hover:bg-blue-600 border-transparent', 31 | solidYellow: 32 | 'text-white bg-yellow-500 hover:bg-yellow-600 border-transparent', 33 | lightBlue: 'text-blue-500 bg-blue-100 hover:bg-blue-200 border-transparent', 34 | outlineBlue: 35 | 'text-blue-500 hover:text-white bg-transparent border-blue-500 hover:border-transparent hover:bg-blue-500', 36 | lightOpacity: 37 | 'text-white bg-blue-400/30 hover:bg-blue-400/50 border-transparent', 38 | }; 39 | 40 | const wideClassName = 'flex w-full justify-center items-center'; 41 | 42 | const className = `${baseClass} ${sizes[size]} ${variants[variant]} ${ 43 | wide ? wideClassName : '' 44 | } ${addClassName}`; 45 | 46 | return ( 47 | <> 48 | {external ? ( 49 | 55 | {children} 56 | 57 | ) : tagName === 'a' || href ? ( 58 | 59 | {children} 60 | 61 | ) : ( 62 | 65 | )} 66 | 67 | ); 68 | } 69 | 70 | Button.defaultProps = { 71 | size: 'normal', 72 | className: '', 73 | tagName: 'button', 74 | wide: false, 75 | variant: 'solid', 76 | }; 77 | 78 | Button.propTypes = { 79 | size: PropTypes.oneOf(['small', 'normal']), 80 | href: PropTypes.string, 81 | tagName: PropTypes.oneOf(['link', 'button']), 82 | wide: PropTypes.bool, 83 | variant: PropTypes.string, 84 | children: PropTypes.node, 85 | className: PropTypes.string, 86 | external: PropTypes.bool, 87 | }; 88 | 89 | export default Button; 90 | -------------------------------------------------------------------------------- /components/Container.jsx: -------------------------------------------------------------------------------- 1 | import clsx from 'clsx'; 2 | import PropTypes from 'prop-types'; 3 | 4 | function Container({ className, children, ...props }) { 5 | return ( 6 |
12 | {children} 13 |
14 | ); 15 | } 16 | 17 | Container.propTypes = { 18 | className: PropTypes.string, 19 | children: PropTypes.node, 20 | }; 21 | 22 | export default Container; 23 | -------------------------------------------------------------------------------- /components/FooterLink.jsx: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | 3 | function FooterLink({ children, href }) { 4 | return ( 5 | 8 | {children} 9 | 10 | ); 11 | } 12 | 13 | FooterLink.propTypes = { 14 | href: PropTypes.string, 15 | children: PropTypes.node, 16 | }; 17 | 18 | export default FooterLink; 19 | -------------------------------------------------------------------------------- /components/FooterTitle.jsx: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | 3 | function FooterTitle() { 4 | return ( 5 |

6 | External 7 |

8 | ); 9 | } 10 | 11 | FooterTitle.propTypes = { 12 | children: PropTypes.node, 13 | }; 14 | 15 | export default FooterTitle; 16 | -------------------------------------------------------------------------------- /components/HeroFeature.jsx: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | 3 | function HeroFeature({ title, description, icon: Icon }) { 4 | return ( 5 |
6 | 7 |
8 |

{title}

9 |

10 | {description} 11 |

12 |
13 |
14 | ); 15 | } 16 | 17 | HeroFeature.propTypes = { 18 | title: PropTypes.string, 19 | description: PropTypes.node, 20 | icon: PropTypes.func, 21 | }; 22 | 23 | export default HeroFeature; 24 | -------------------------------------------------------------------------------- /components/IconList.jsx: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | 3 | function IconListItem({ title, description, icon: Icon }) { 4 | return ( 5 |
  • 6 |
    7 | 8 |
    9 |
    10 |

    {title}

    11 |

    {description}

    12 |
    13 |
  • 14 | ); 15 | } 16 | 17 | IconListItem.propTypes = { 18 | title: PropTypes.string, 19 | description: PropTypes.string, 20 | icon: PropTypes.func, 21 | }; 22 | 23 | export { IconListItem }; 24 | 25 | function IconList({ children }) { 26 | return ; 27 | } 28 | 29 | IconList.propTypes = { 30 | children: PropTypes.node, 31 | }; 32 | 33 | export default IconList; 34 | -------------------------------------------------------------------------------- /components/IllustrationCard.jsx: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | 3 | function IllustrationCard({ title, description, image }) { 4 | return ( 5 |
    6 | {title} 7 |

    {title}

    8 |

    {description}

    9 |
    10 | ); 11 | } 12 | 13 | IllustrationCard.propTypes = { 14 | title: PropTypes.string, 15 | description: PropTypes.string, 16 | image: PropTypes.string, 17 | }; 18 | 19 | export default IllustrationCard; 20 | -------------------------------------------------------------------------------- /components/IntroCard.jsx: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | 3 | function IntroCard({ icon: Icon, title, content, list }) { 4 | return ( 5 |
    6 | 7 |
    8 |

    {title}

    9 |

    {content}

    10 |
    11 | {list.map(({ title, description }) => ( 12 |
    13 |
    14 |
    15 |
    16 | {title} 17 |
    18 |
    {description}
    19 |
    20 |
    21 | ))} 22 |
    23 |
    24 |
    25 | ); 26 | } 27 | 28 | IntroCard.defaultProps = { 29 | list: [], 30 | }; 31 | 32 | IntroCard.propTypes = { 33 | title: PropTypes.string, 34 | content: PropTypes.node, 35 | icon: PropTypes.func, 36 | list: PropTypes.array, 37 | }; 38 | 39 | export default IntroCard; 40 | -------------------------------------------------------------------------------- /components/LangCard.jsx: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | 3 | function LangCard({ logo, name }) { 4 | return ( 5 |
    6 | {name} 7 |
    8 | ); 9 | } 10 | 11 | LangCard.propTypes = { 12 | logo: PropTypes.string, 13 | name: PropTypes.string, 14 | }; 15 | 16 | export default LangCard; 17 | -------------------------------------------------------------------------------- /components/Link.jsx: -------------------------------------------------------------------------------- 1 | // import { Link } from 'react-router-dom'; 2 | import Link from 'next/link'; 3 | import PropTypes from 'prop-types'; 4 | 5 | function LinkElement({ href, className, children, ...props }) { 6 | return ( 7 | 8 | 9 | {children} 10 | 11 | 12 | ); 13 | } 14 | 15 | LinkElement.defaultProps = { 16 | href: '/', 17 | }; 18 | 19 | LinkElement.propTypes = { 20 | /** Page path */ 21 | href: PropTypes.string, 22 | className: PropTypes.string, 23 | children: PropTypes.node, 24 | }; 25 | 26 | export default LinkElement; 27 | -------------------------------------------------------------------------------- /components/Navbar.jsx: -------------------------------------------------------------------------------- 1 | import { Button, Container, Link } from '@components'; 2 | import clsx from 'clsx'; 3 | import PropTypes from 'prop-types'; 4 | import React, { useEffect, useState } from 'react'; 5 | 6 | function Navbar({ items, logo, rightButtonHref, className, rightButton }) { 7 | const [collapse, setCollpase] = useState(false); 8 | 9 | useEffect(() => { 10 | function responsiveNavbar() { 11 | const vw = window.outerWidth; 12 | const threshold = 768; 13 | 14 | if (vw <= threshold) setCollpase(true); 15 | 16 | if (vw > threshold) setCollpase(false); 17 | } 18 | 19 | responsiveNavbar(); 20 | 21 | window.addEventListener('resize', responsiveNavbar); 22 | }, []); 23 | 24 | return ( 25 | 113 | ); 114 | } 115 | 116 | Navbar.defaultProps = { 117 | logo: 'Nauval Ganteng', 118 | items: [], 119 | rightButtonChildren: 'Sign Up', 120 | rightButtonHref: '/', 121 | rightButtonColor: 'blue', 122 | className: '', 123 | rightButton: {}, 124 | }; 125 | 126 | Navbar.propTypes = { 127 | scheme: PropTypes.oneOf(['light', 'dark']), 128 | items: PropTypes.array, 129 | rightButtonChildren: PropTypes.string, 130 | rightButtonHref: PropTypes.string, 131 | rightButtonColor: PropTypes.string, 132 | className: PropTypes.string, 133 | rightButton: PropTypes.oneOfType([PropTypes.object, PropTypes.bool]), 134 | logo: PropTypes.node, 135 | }; 136 | 137 | export default Navbar; 138 | -------------------------------------------------------------------------------- /components/PricingCard.jsx: -------------------------------------------------------------------------------- 1 | import { Button, SectionBadge } from '@components'; 2 | import clsx from 'clsx'; 3 | import PropTypes from 'prop-types'; 4 | import { HiCheck } from 'react-icons/hi'; 5 | 6 | function PricingCard({ price, name, description, features, highlight }) { 7 | return ( 8 |
    13 | {name} 14 |

    19 | IDR{price} 20 |

    21 |

    26 | {description} 27 |

    28 |
    29 | {features.map((f) => ( 30 |
    36 |
    41 | 42 |
    43 | {f} 44 |
    45 | ))} 46 |
    47 | 48 | 54 |
    55 | ); 56 | } 57 | 58 | PricingCard.propTypes = { 59 | price: PropTypes.string, 60 | description: PropTypes.string, 61 | name: PropTypes.string, 62 | features: PropTypes.array, 63 | highlight: PropTypes.bool, 64 | }; 65 | 66 | export default PricingCard; 67 | -------------------------------------------------------------------------------- /components/SectionBadge.jsx: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | 3 | function SectionBadge({ children }) { 4 | return ( 5 |
    6 | {children} 7 |
    8 | ); 9 | } 10 | 11 | SectionBadge.propTypes = { 12 | children: PropTypes.node, 13 | }; 14 | 15 | export default SectionBadge; 16 | -------------------------------------------------------------------------------- /components/SectionDescription.jsx: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | 3 | function SectionDescription({ children }) { 4 | return ( 5 |

    {children}

    6 | ); 7 | } 8 | 9 | SectionDescription.propTypes = { 10 | children: PropTypes.node, 11 | }; 12 | 13 | export default SectionDescription; 14 | -------------------------------------------------------------------------------- /components/SectionTitle.jsx: -------------------------------------------------------------------------------- 1 | import clsx from 'clsx'; 2 | import PropTypes from 'prop-types'; 3 | 4 | function SectionTitle({ children, className }) { 5 | return ( 6 |

    11 | {children} 12 |

    13 | ); 14 | } 15 | 16 | SectionTitle.propTypes = { 17 | children: PropTypes.node, 18 | className: PropTypes.string, 19 | }; 20 | 21 | export default SectionTitle; 22 | -------------------------------------------------------------------------------- /components/SocialLink.jsx: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | 3 | function SocialLink({ icon: Icon, name, href }) { 4 | return ( 5 | 9 | 10 | 11 | ); 12 | } 13 | 14 | SocialLink.propTypes = { 15 | href: PropTypes.string, 16 | icon: PropTypes.func, 17 | name: PropTypes.string, 18 | }; 19 | 20 | export default SocialLink; 21 | -------------------------------------------------------------------------------- /components/SquareList.jsx: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | 3 | function SquareListItem({ point, children }) { 4 | return ( 5 |
  • 6 |
    7 | 8 | {point} {children} 9 | 10 |
  • 11 | ); 12 | } 13 | 14 | SquareListItem.propTypes = { 15 | point: PropTypes.string, 16 | children: PropTypes.node, 17 | }; 18 | 19 | export { SquareListItem }; 20 | 21 | function SquareList({ children }) { 22 | return ; 23 | } 24 | 25 | SquareList.propTypes = { 26 | children: PropTypes.node, 27 | }; 28 | 29 | export default SquareList; 30 | -------------------------------------------------------------------------------- /components/TestimonialCard.jsx: -------------------------------------------------------------------------------- 1 | import PropTypes from 'prop-types'; 2 | 3 | function TestimonialCard({ testimoni, name, avatar, job }) { 4 | return ( 5 |
    6 |
    7 |

    {testimoni}

    8 |
    9 | orang 14 |
    15 |

    {name}

    16 |

    {job}

    17 |
    18 |
    19 |
    20 |
    21 | ); 22 | } 23 | 24 | TestimonialCard.propTypes = { 25 | testimoni: PropTypes.string, 26 | name: PropTypes.string, 27 | avatar: PropTypes.string, 28 | job: PropTypes.string, 29 | }; 30 | 31 | export default TestimonialCard; 32 | -------------------------------------------------------------------------------- /components/index.js: -------------------------------------------------------------------------------- 1 | export { default as Button } from './Button'; 2 | export { default as Container } from './Container'; 3 | export { default as FooterLink } from './FooterLink'; 4 | export { default as FooterTitle } from './FooterTitle'; 5 | export { default as HeroFeature } from './HeroFeature'; 6 | export { default as IconList, IconListItem } from './IconList'; 7 | export { default as IllustrationCard } from './IllustrationCard'; 8 | export { default as IntroCard } from './IntroCard'; 9 | export { default as LangCard } from './LangCard'; 10 | export { default as Link } from './Link'; 11 | export { default as Navbar } from './Navbar'; 12 | export { default as PricingCard } from './PricingCard'; 13 | export { default as SectionBadge } from './SectionBadge'; 14 | export { default as SectionDescription } from './SectionDescription'; 15 | export { default as SectionTitle } from './SectionTitle'; 16 | export { default as SocialLink } from './SocialLink'; 17 | export { default as SquareList, SquareListItem } from './SquareList'; 18 | export { default as TestimonialCard } from './TestimonialCard'; 19 | -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "paths": { 5 | "@components": ["components/index.js"] 6 | } 7 | } 8 | } 9 | 10 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "collosal", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "eslint ./pages/** -c .eslintrc.json --ext js,jsx", 10 | "fix": "eslint --fix" 11 | }, 12 | "dependencies": { 13 | "autoprefixer": "^10.2.6", 14 | "clsx": "^1.1.1", 15 | "next": "10.2.0", 16 | "postcss": "^8.3.0", 17 | "prop-types": "^15.7.2", 18 | "react": "17.0.2", 19 | "react-dom": "17.0.2", 20 | "react-icons": "^4.2.0", 21 | "react-slick": "^0.28.1", 22 | "slick-carousel": "^1.8.1", 23 | "tailwindcss": "canary" 24 | }, 25 | "devDependencies": { 26 | "eslint": "^7.26.0", 27 | "eslint-config-prettier": "^8.3.0", 28 | "eslint-config-recommended": "^4.1.0", 29 | "eslint-plugin-import": "^2.22.1", 30 | "eslint-plugin-jsx-a11y": "^6.4.1", 31 | "eslint-plugin-prettier": "^3.4.0", 32 | "eslint-plugin-react": "^7.23.2", 33 | "eslint-plugin-simple-import-sort": "^7.0.0", 34 | "prettier": "^2.3.0" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /pages/_app.js: -------------------------------------------------------------------------------- 1 | import '../styles/globals.css'; 2 | 3 | import Head from 'next/head'; 4 | import PropTypes from 'prop-types'; 5 | 6 | function MyApp({ Component, pageProps }) { 7 | return ( 8 | <> 9 | 10 | 11 | 15 | 19 | 20 | 21 | 22 | 23 | ); 24 | } 25 | 26 | MyApp.propTypes = { 27 | Component: PropTypes.elementType.isRequired, 28 | pageProps: PropTypes.shape({}).isRequired, 29 | }; 30 | 31 | export default MyApp; 32 | -------------------------------------------------------------------------------- /pages/_document.jsx: -------------------------------------------------------------------------------- 1 | import Document, { Head, Html, Main, NextScript } from 'next/document'; 2 | 3 | class MyDocument extends Document { 4 | static async getInitialProps(ctx) { 5 | const initialProps = await Document.getInitialProps(ctx); 6 | return { ...initialProps }; 7 | } 8 | 9 | render() { 10 | return ( 11 | 12 | 13 | 14 |
    15 | 16 | 17 | 18 | ); 19 | } 20 | } 21 | 22 | export default MyDocument; 23 | -------------------------------------------------------------------------------- /pages/index.jsx: -------------------------------------------------------------------------------- 1 | import { 2 | Button, 3 | Container, 4 | FooterLink, 5 | FooterTitle, 6 | HeroFeature, 7 | IconList, 8 | IconListItem, 9 | IllustrationCard, 10 | IntroCard, 11 | LangCard, 12 | Navbar, 13 | PricingCard, 14 | SectionBadge, 15 | SectionDescription, 16 | SectionTitle, 17 | SocialLink, 18 | SquareList, 19 | SquareListItem, 20 | TestimonialCard, 21 | } from '@components'; 22 | import Head from 'next/head'; 23 | import { 24 | FaFacebookF, 25 | FaGithub, 26 | FaLinkedinIn, 27 | FaTwitter, 28 | FaYoutube, 29 | } from 'react-icons/fa'; 30 | import { 31 | HiOutlineAcademicCap, 32 | HiOutlineAnnotation, 33 | HiOutlineHeart, 34 | HiOutlineLightningBolt, 35 | HiOutlinePlay, 36 | HiOutlineShoppingCart, 37 | HiOutlineTemplate, 38 | HiOutlineTerminal, 39 | HiOutlineViewGrid, 40 | } from 'react-icons/hi'; 41 | import Slider from 'react-slick'; 42 | 43 | export default function Index() { 44 | const settings = { 45 | dots: true, 46 | infinite: true, 47 | speed: 500, 48 | slidesToShow: 3, 49 | slidesToScroll: 1, 50 | initialSlide: 0, 51 | responsive: [ 52 | { 53 | breakpoint: 1280, 54 | settings: { 55 | slidesToShow: 2, 56 | slidesToScroll: 1, 57 | }, 58 | }, 59 | { 60 | breakpoint: 600, 61 | settings: { 62 | slidesToShow: 2, 63 | slidesToScroll: 2, 64 | initialSlide: 2, 65 | }, 66 | }, 67 | { 68 | breakpoint: 480, 69 | settings: { 70 | slidesToShow: 1, 71 | slidesToScroll: 1, 72 | }, 73 | }, 74 | ], 75 | }; 76 | 77 | return ( 78 | <> 79 | 80 | 81 | 85 | 86 | 87 | 88 | 89 | 90 | 94 | 95 | 96 | 97 | 98 | 102 | 103 | 104 | KKTBSYS — Tailwind & Next Mentorship Template 105 | 106 | 107 | 108 | 111 | Logo 118 | KKTBSYS 119 |
    120 | } 121 | className="bg-gradient-to-br from-blue-400 to-blue-700 xl:bg-none" 122 | items={[ 123 | { text: 'Kodinger', href: 'https://kodinger.com' }, 124 | { text: 'Array ID', href: 'https://array.id' }, 125 | { text: 'Stisla', href: 'https://getstisla.com' }, 126 | { text: 'Nauval', href: 'https://nauv.al' }, 127 | ]} 128 | rightButton={{ 129 | variant: 'lightBlue', 130 | children: 'Daftar Sekarang', 131 | href: '/', 132 | }} 133 | /> 134 | 135 |
    136 |
    137 | 138 |
    139 |
    140 |

    141 | Menjadi{' '} 142 | Front-end Developer Yang{' '} 143 | Modern Ellitist 144 |

    145 |

    146 | Saya ini engineer yang bekerja di big company dan sudah pernah 147 | implement microservice. Jadi, saya sangat cocok jadi mentor 148 | kamu! 149 |

    150 | 151 |
    152 | 157 | 164 |
    165 |
    166 |
    167 | mentor 172 |
    173 | Photo by{' '} 174 | 175 | NEXT Academy 176 | {' '} 177 | on{' '} 178 | 179 | Unsplash 180 | 181 |
    182 |
    183 |
    184 |
    185 |
    186 | 191 |
    192 |
    193 | 198 |
    199 |
    200 | 205 |
    206 |
    207 |
    208 |
    209 | 210 |
    211 | 212 |
    213 |
    214 |
    215 |
    216 |
    217 | gw 222 |

    223 | Photo by{' '} 224 | 225 | Madison Yocum 226 | {' '} 227 | on{' '} 228 | 229 | Unsplash 230 | 231 |

    232 |
    233 |
    234 |
    235 | Introduction 236 | 237 | Siapa sih gw ini sebenernya?{' '} 238 | Berkenalan dulu sama 239 | mentornya! 240 | 241 | 254 | 259 | 264 |
    265 |
    266 | 267 |
    268 | 269 |
    270 | Pokoknya yang modern-modern 271 | 272 | Apa sih yang{' '} 273 | bakal gw ajarin di sini? 274 | Wah banyak banget! 275 | 276 |
    277 | 278 |
    279 |
    280 | 285 |
    286 |
    287 | 292 |
    293 |
    294 | 299 |
    300 |
    301 | 306 |
    307 |
    308 | 313 |
    314 |
    315 | 320 |
    321 |
    322 | 327 |
    328 |
    329 | 334 |
    335 |
    336 | 337 |
    338 | 339 |
    340 |
    341 |
    342 |
    343 |
    344 |
    345 |
    346 | 347 |
    348 | Wah Ada Banyak Ya 349 | 350 | Semua Ini Teknologi Yang{' '} 351 | Bakal Lo Pelajarin, Cuy! 352 | 353 |
    354 |
    355 |
    356 | 357 |
    358 |
    359 | 360 | 361 |
    362 |
    363 | 364 | 365 | 366 |
    367 |
    368 | 369 | 370 |
    371 |
    372 | 373 |
    374 |
    375 |
    376 | 377 | Puluhan teknologi ini yang akan bikin hidup lo jadi berubah, dari 378 | puluhan teknologi ini ada 2 yang mantep banget, 2 teknologi itu 379 | ... baca selengkapnya. 380 | 381 |
    382 |
    383 |
    384 | 385 |
    386 | 387 |
    388 |
    389 | Di mana aja 390 | 391 | Belajar bisa di mana aja, di starbaks contohnya, walaupun nggak 392 | fokus, gapapa{' '} 393 | 394 | 👌 395 | 396 | 397 | 398 | Banyak hal yang bakal lo pelajari, termasuk dari hidup lo 399 | sendiri. Lo mungkin aja seorang yang kuat, tapi kalo liat orang 400 | yang pake jQuery lo mending lari. 401 | 402 | 403 | 404 | 405 | belajarnya lewat Zoom, nanti lo di-invite ke sebuah Zoom 406 | meeting yang di dalemnya banyak pelajar lainnya. 407 | 408 | 409 | kalo lo nggak banyak nanya nantinya cuma tau sedikit, mending 410 | banyak nanya aja sampe mentor lo capek. 411 | 412 | 413 | nggak semua hal lo bisa kontrol, lo cuma bisa kontrol diri lo 414 | sendiri, fokus aja sama yang bisa lo kontrol, orang lain 415 | terserah mereka sendiri. 416 | 417 | 418 |
    419 |
    420 | Preview 425 |

    426 | Photo by{' '} 427 | 428 | Irvan Smith 429 | {' '} 430 | on{' '} 431 | 432 | Unsplash 433 | 434 |

    435 |
    436 |
    437 | 438 |
    439 | 440 |
    441 |
    442 | Preview 447 |

    448 | Photo by{' '} 449 | 450 | Leon 451 | {' '} 452 | on{' '} 453 | 454 | Unsplash 455 | 456 |

    457 |
    458 |
    459 | Tugas Akhir 460 | 461 | Nanti ada tugas akhir dan lo harus mempresentasikan apa yang lo 462 | udah bikin itu{' '} 463 | 464 | 🤘 465 | 466 | 467 | 468 | Seperti yang gw bilang di awal, di sini tuh nggak ada 469 | sertifikat, nanti lo bisa bikin produk sendiri yang dijamin akan 470 | membuat paul graham tercengang dan ingin invest hehe. 471 | 472 | 473 | 474 | 479 | 484 | 485 |
    486 |
    487 |
    488 |
    489 | 490 |
    491 | 492 |
    493 |
    494 | Harganya Bos 495 | 496 | Harganya udah paling sesuai dengan{' '} 497 | kantong mahasiswa Harvard 498 | 499 |
    500 |
    501 |
    502 | 515 |
    516 |
    517 | 534 |
    535 |
    536 |
    537 | 538 | Harga di atas belom termasuk PPN ya, kalo lo ga bayar pajak 539 | nanti pejabat korupsi apa dong? 540 | 541 |
    542 |
    543 |
    544 |
    545 | 546 |
    547 | 548 |
    549 |
    550 | Testimonial 551 | 552 | Apa kata orang-orang yang pernah{' '} 553 | ikut mentorship ini? 554 | 555 |
    556 |
    557 | 558 | Kalo lo belum yakin sama mentorship ini, baca aja dulu 559 | testimonial di sini, siapa tau lo jadi yakin dan mau ikut 560 | mentorship ini untuk merubah hidup lo yang sekarang sebenernya 561 | udah baik sih. Tapi ya biar lebih baik lagi aja lo ikutan 562 | mentorship ini hehehe. 563 | 564 |
    565 |
    566 | 567 | 575 | 583 | 591 | 599 | 600 |
    601 |
    602 | 603 | 735 | 736 | ); 737 | } 738 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | }; 7 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nauvalazhar/kktbsys/efa61138e9feb3c601cae59a9a3cc84e45151432/public/favicon.ico -------------------------------------------------------------------------------- /public/github.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /public/hotjar.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /public/illustration-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nauvalazhar/kktbsys/efa61138e9feb3c601cae59a9a3cc84e45151432/public/illustration-1.png -------------------------------------------------------------------------------- /public/illustration-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nauvalazhar/kktbsys/efa61138e9feb3c601cae59a9a3cc84e45151432/public/illustration-2.png -------------------------------------------------------------------------------- /public/illustration-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nauvalazhar/kktbsys/efa61138e9feb3c601cae59a9a3cc84e45151432/public/illustration-3.png -------------------------------------------------------------------------------- /public/illustration-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nauvalazhar/kktbsys/efa61138e9feb3c601cae59a9a3cc84e45151432/public/illustration-4.png -------------------------------------------------------------------------------- /public/javascript.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /public/jquery.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /public/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nauvalazhar/kktbsys/efa61138e9feb3c601cae59a9a3cc84e45151432/public/logo.png -------------------------------------------------------------------------------- /public/nodejs.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /public/react.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /public/redux.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /public/sass.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /public/tailwindcss.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /public/vercel.svg: -------------------------------------------------------------------------------- 1 | 3 | 4 | -------------------------------------------------------------------------------- /styles/Home.module.css: -------------------------------------------------------------------------------- 1 | .container { 2 | min-height: 100vh; 3 | padding: 0 0.5rem; 4 | display: flex; 5 | flex-direction: column; 6 | justify-content: center; 7 | align-items: center; 8 | height: 100vh; 9 | } 10 | 11 | .main { 12 | padding: 5rem 0; 13 | flex: 1; 14 | display: flex; 15 | flex-direction: column; 16 | justify-content: center; 17 | align-items: center; 18 | } 19 | 20 | .footer { 21 | width: 100%; 22 | height: 100px; 23 | border-top: 1px solid #eaeaea; 24 | display: flex; 25 | justify-content: center; 26 | align-items: center; 27 | } 28 | 29 | .footer a { 30 | display: flex; 31 | justify-content: center; 32 | align-items: center; 33 | flex-grow: 1; 34 | } 35 | 36 | .title a { 37 | color: #0070f3; 38 | text-decoration: none; 39 | } 40 | 41 | .title a:hover, 42 | .title a:focus, 43 | .title a:active { 44 | text-decoration: underline; 45 | } 46 | 47 | .title { 48 | margin: 0; 49 | line-height: 1.15; 50 | font-size: 4rem; 51 | } 52 | 53 | .title, 54 | .description { 55 | text-align: center; 56 | } 57 | 58 | .description { 59 | line-height: 1.5; 60 | font-size: 1.5rem; 61 | } 62 | 63 | .code { 64 | background: #fafafa; 65 | border-radius: 5px; 66 | padding: 0.75rem; 67 | font-size: 1.1rem; 68 | font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, 69 | Bitstream Vera Sans Mono, Courier New, monospace; 70 | } 71 | 72 | .grid { 73 | display: flex; 74 | align-items: center; 75 | justify-content: center; 76 | flex-wrap: wrap; 77 | max-width: 800px; 78 | margin-top: 3rem; 79 | } 80 | 81 | .card { 82 | margin: 1rem; 83 | padding: 1.5rem; 84 | text-align: left; 85 | color: inherit; 86 | text-decoration: none; 87 | border: 1px solid #eaeaea; 88 | border-radius: 10px; 89 | transition: color 0.15s ease, border-color 0.15s ease; 90 | width: 45%; 91 | } 92 | 93 | .card:hover, 94 | .card:focus, 95 | .card:active { 96 | color: #0070f3; 97 | border-color: #0070f3; 98 | } 99 | 100 | .card h2 { 101 | margin: 0 0 1rem 0; 102 | font-size: 1.5rem; 103 | } 104 | 105 | .card p { 106 | margin: 0; 107 | font-size: 1.25rem; 108 | line-height: 1.5; 109 | } 110 | 111 | .logo { 112 | height: 1em; 113 | margin-left: 0.5rem; 114 | } 115 | 116 | @media (max-width: 600px) { 117 | .grid { 118 | width: 100%; 119 | flex-direction: column; 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /styles/globals.css: -------------------------------------------------------------------------------- 1 | @import 'tailwindcss/tailwind.css'; 2 | @import 'slick-carousel/slick/slick.css'; 3 | @import 'slick-carousel/slick/slick-theme.css'; 4 | 5 | .slick-list { 6 | @apply -mx-6; 7 | } 8 | 9 | .slick-slide > div { 10 | @apply px-6; 11 | } 12 | 13 | .slick-dots { 14 | @apply static mt-12; 15 | } 16 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | const defaultTheme = require('tailwindcss/defaultTheme'); 2 | 3 | module.exports = { 4 | purge: ['./pages/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}'], 5 | mode: 'jit', 6 | darkMode: false, // or 'media' or 'class' 7 | theme: { 8 | extend: { 9 | fontFamily: { 10 | sans: ['DM Sans', ...defaultTheme.fontFamily.sans], 11 | mono: ['IBM Plex Mono', ...defaultTheme.fontFamily.mono], 12 | }, 13 | colors: { 14 | primary: { 15 | 50: '#f7f9fb', 16 | 100: '#e4f0fd', 17 | 200: '#c6d8fa', 18 | 300: '#9eb5f3', 19 | 400: '#7b8dea', 20 | 500: '#6567e7', 21 | 600: '#524cd6', 22 | 700: '#3f39b6', 23 | 800: '#2c2788', 24 | 900: '#181856', 25 | }, 26 | }, 27 | }, 28 | }, 29 | variants: { 30 | extend: {}, 31 | }, 32 | plugins: [], 33 | }; 34 | --------------------------------------------------------------------------------