├── components ├── home │ ├── schema.xml │ ├── Projects.tsx │ ├── Contact.tsx │ ├── Experience.tsx │ ├── Home.tsx │ └── Expertise.tsx ├── visual │ ├── LanguageImage.tsx │ └── AppPreview.tsx ├── notion │ └── NotionPage.tsx ├── CommonFooter.tsx ├── shared │ ├── Hero.tsx │ └── Accordion.tsx ├── projects │ └── ProjectsColumn.tsx ├── work │ └── Work.tsx └── Navigation.tsx ├── .vscode ├── settings.json └── launch.json ├── types └── requestContext.ts ├── public ├── icon.png ├── favicon.ico ├── ogImage.png ├── homeImage.png ├── icon │ ├── home.png │ ├── user.png │ └── sack-dollar.png ├── scrollDown.gif ├── work │ ├── daiday.png │ ├── metavest.png │ └── danceflavors_app.png ├── logos │ ├── website.png │ ├── github-mark.png │ └── In-White-48@2x.png ├── fonts │ ├── VisbyBold.otf │ ├── VisbyLight.otf │ ├── VisbyMedium.otf │ └── VisbyRegular.otf ├── illustrations │ └── hello_illustration.png └── lotties │ └── scrollDown.json ├── services ├── notion.ts └── config.ts ├── utils ├── case.ts ├── lang.js └── dataUtils.ts ├── next-env.d.ts ├── hooks └── device.ts ├── next.config.js ├── .github └── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── pages ├── notion-tryout.tsx ├── _app.tsx ├── [slug].tsx └── index.tsx ├── tsconfig.json ├── LICENSE ├── package.json ├── README.md ├── .gitignore ├── CODE_OF_CONDUCT.md └── styles └── globals.css /components/home/schema.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.tabSize": 2 3 | } -------------------------------------------------------------------------------- /types/requestContext.ts: -------------------------------------------------------------------------------- 1 | export type RequestContext = { 2 | isMobile: boolean 3 | } -------------------------------------------------------------------------------- /public/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/umutyesildal/yesildal.me-personal-portfolio/HEAD/public/icon.png -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/umutyesildal/yesildal.me-personal-portfolio/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /public/ogImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/umutyesildal/yesildal.me-personal-portfolio/HEAD/public/ogImage.png -------------------------------------------------------------------------------- /public/homeImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/umutyesildal/yesildal.me-personal-portfolio/HEAD/public/homeImage.png -------------------------------------------------------------------------------- /public/icon/home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/umutyesildal/yesildal.me-personal-portfolio/HEAD/public/icon/home.png -------------------------------------------------------------------------------- /public/icon/user.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/umutyesildal/yesildal.me-personal-portfolio/HEAD/public/icon/user.png -------------------------------------------------------------------------------- /public/scrollDown.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/umutyesildal/yesildal.me-personal-portfolio/HEAD/public/scrollDown.gif -------------------------------------------------------------------------------- /public/work/daiday.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/umutyesildal/yesildal.me-personal-portfolio/HEAD/public/work/daiday.png -------------------------------------------------------------------------------- /public/logos/website.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/umutyesildal/yesildal.me-personal-portfolio/HEAD/public/logos/website.png -------------------------------------------------------------------------------- /public/work/metavest.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/umutyesildal/yesildal.me-personal-portfolio/HEAD/public/work/metavest.png -------------------------------------------------------------------------------- /services/notion.ts: -------------------------------------------------------------------------------- 1 | import { NotionAPI } from 'notion-client' 2 | 3 | const notion = new NotionAPI() 4 | export default notion -------------------------------------------------------------------------------- /public/fonts/VisbyBold.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/umutyesildal/yesildal.me-personal-portfolio/HEAD/public/fonts/VisbyBold.otf -------------------------------------------------------------------------------- /public/fonts/VisbyLight.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/umutyesildal/yesildal.me-personal-portfolio/HEAD/public/fonts/VisbyLight.otf -------------------------------------------------------------------------------- /public/icon/sack-dollar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/umutyesildal/yesildal.me-personal-portfolio/HEAD/public/icon/sack-dollar.png -------------------------------------------------------------------------------- /utils/case.ts: -------------------------------------------------------------------------------- 1 | export const kebabize = (str) => str.replace(/[A-Z]+(?![a-z])|[A-Z]/g, ($, ofs) => (ofs ? "-" : "") + $.toLowerCase()) -------------------------------------------------------------------------------- /public/fonts/VisbyMedium.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/umutyesildal/yesildal.me-personal-portfolio/HEAD/public/fonts/VisbyMedium.otf -------------------------------------------------------------------------------- /public/fonts/VisbyRegular.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/umutyesildal/yesildal.me-personal-portfolio/HEAD/public/fonts/VisbyRegular.otf -------------------------------------------------------------------------------- /public/logos/github-mark.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/umutyesildal/yesildal.me-personal-portfolio/HEAD/public/logos/github-mark.png -------------------------------------------------------------------------------- /public/logos/In-White-48@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/umutyesildal/yesildal.me-personal-portfolio/HEAD/public/logos/In-White-48@2x.png -------------------------------------------------------------------------------- /public/work/danceflavors_app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/umutyesildal/yesildal.me-personal-portfolio/HEAD/public/work/danceflavors_app.png -------------------------------------------------------------------------------- /public/illustrations/hello_illustration.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/umutyesildal/yesildal.me-personal-portfolio/HEAD/public/illustrations/hello_illustration.png -------------------------------------------------------------------------------- /utils/lang.js: -------------------------------------------------------------------------------- 1 | import { useRouter } from "next/router"; 2 | 3 | export function useLanguage(){ 4 | const router = useRouter(); 5 | return router.locale ?? 'en'; 6 | } -------------------------------------------------------------------------------- /next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/basic-features/typescript for more information. 6 | -------------------------------------------------------------------------------- /services/config.ts: -------------------------------------------------------------------------------- 1 | // TODO: change this to the notion ID of the page you want to test 2 | export const rootNotionPageId = '581905d9a16f4832940af432226895d6' 3 | 4 | export const isDev = 5 | process.env.NODE_ENV === 'development' || !process.env.NODE_ENV -------------------------------------------------------------------------------- /hooks/device.ts: -------------------------------------------------------------------------------- 1 | import mobile from 'is-mobile'; 2 | import { RequestContext } from 'pages/_app'; 3 | import { useContext } from 'react'; 4 | 5 | export function useMobile(){ 6 | const ctx = useContext(RequestContext); 7 | return ctx.isMobile || mobile(); 8 | } -------------------------------------------------------------------------------- /components/visual/LanguageImage.tsx: -------------------------------------------------------------------------------- 1 | import { useLanguage } from "../../utils/lang"; 2 | 3 | 4 | export default function LanguageImage(props){ 5 | let lang = useLanguage(); 6 | const src = `/img/i18n/${lang}/${props.src}` 7 | return 8 | } -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | module.exports = { 3 | reactStrictMode: true, 4 | i18n: { 5 | locales: ["en"], 6 | defaultLocale: "en", 7 | localeDetection: false, 8 | }, 9 | async headers() { 10 | return [ 11 | { 12 | source: "/.well-known/apple-app-site-association", 13 | headers: [ 14 | { 15 | key: "Content-Type", 16 | value: "application/json", 17 | }, 18 | ], 19 | }, 20 | ]; 21 | }, 22 | }; 23 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /pages/notion-tryout.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | 3 | import { ExtendedRecordMap } from "notion-types"; 4 | 5 | import { NotionPage } from "../components/notion/NotionPage"; 6 | import { rootNotionPageId } from "../services/config"; 7 | import notion from "../services/notion"; 8 | 9 | export const getStaticProps = async () => { 10 | const pageId = rootNotionPageId; 11 | const recordMap = await notion.getPage(pageId); 12 | 13 | return { 14 | props: { 15 | recordMap, 16 | }, 17 | revalidate: 10, 18 | }; 19 | }; 20 | 21 | export default function Page({ recordMap }: { recordMap: ExtendedRecordMap }) { 22 | return ; 23 | } 24 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "ESNext", 4 | "lib": [ 5 | "dom", 6 | "dom.iterable", 7 | "esnext" 8 | ], 9 | "allowJs": true, 10 | "skipLibCheck": true, 11 | "strict": false, 12 | "forceConsistentCasingInFileNames": true, 13 | "noEmit": true, 14 | "incremental": true, 15 | "esModuleInterop": true, 16 | "module": "esnext", 17 | "moduleResolution": "node", 18 | "isolatedModules": true, 19 | "jsx": "preserve", 20 | "resolveJsonModule": true, 21 | "baseUrl": "." 22 | }, 23 | "include": [ 24 | "next-env.d.ts", 25 | "**/*.ts", 26 | "**/*.tsx" 27 | , "middleware.js" ], 28 | "exclude": [ 29 | "node_modules" 30 | ] 31 | } 32 | -------------------------------------------------------------------------------- /pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import "../styles/globals.css"; 2 | import App from "next/app"; 3 | import "react-notion-x/src/styles.css"; 4 | import { createContext, useEffect } from "react"; 5 | import { RequestContext as RequestContextType } from "types/requestContext"; 6 | export const RequestContext = createContext>({}); 7 | 8 | type AppRootProps = { 9 | Component: any; 10 | pageProps: any; 11 | }; 12 | function AppRoot(props: AppRootProps) { 13 | const Component = props.Component; 14 | const pageProps = props.pageProps; 15 | 16 | return ; 17 | } 18 | 19 | AppRoot.getInitialProps = async (ctx) => { 20 | const appProps = await App.getInitialProps(ctx); 21 | return { ...appProps }; 22 | }; 23 | 24 | export default AppRoot; 25 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "name": "Debug server-side", 6 | "type": "node-terminal", 7 | "request": "launch", 8 | "command": "yarn dev" 9 | }, 10 | { 11 | "name": "Debug client-side", 12 | "type": "pwa-chrome", 13 | "request": "launch", 14 | "url": "http://localhost:3000" 15 | }, 16 | { 17 | "name": "Debug full stack", 18 | "type": "node-terminal", 19 | "request": "launch", 20 | "command": "yarn dev", 21 | "serverReadyAction": { 22 | "pattern": "started server on .+, url: (https?://.+)", 23 | "uriFormat": "%s", 24 | "action": "debugWithChrome" 25 | } 26 | } 27 | ] 28 | } -------------------------------------------------------------------------------- /components/notion/NotionPage.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import Head from "next/head"; 3 | 4 | import { ExtendedRecordMap } from "notion-types"; 5 | import { getPageTitle } from "notion-utils"; 6 | import { NotionRenderer } from "react-notion-x"; 7 | 8 | export const NotionPage = ({ 9 | recordMap, 10 | rootPageId, 11 | }: { 12 | recordMap: ExtendedRecordMap; 13 | rootPageId?: string; 14 | }) => { 15 | if (!recordMap) { 16 | return null; 17 | } 18 | 19 | const title = getPageTitle(recordMap); 20 | console.log(title, recordMap); 21 | 22 | return ( 23 | <> 24 | 25 | 26 | 27 | {title} 28 | 29 | 30 | 36 | 37 | ); 38 | }; 39 | -------------------------------------------------------------------------------- /utils/dataUtils.ts: -------------------------------------------------------------------------------- 1 | // taken and modified from https://stackoverflow.com/a/61375162/811405 2 | function snakeToCamel(str){ 3 | if(str.indexOf('_') == -1 && str.indexOf('-') == -1){ 4 | return str; 5 | } 6 | while(str.indexOf('_') != -1){ 7 | const targetIndex = str.indexOf('_'); 8 | str = str.substring(0, targetIndex) + str.substring(targetIndex + 1, targetIndex + 2).toUpperCase() + str.substring(targetIndex + 2); 9 | } 10 | return str; 11 | } 12 | 13 | 14 | export function sanitizeData(data){ 15 | for (const key in data) { 16 | const element = data[key]; 17 | if(typeof element === 'undefined'){ 18 | data[key] = null; 19 | }else if(typeof element === 'object'){ 20 | sanitizeData(element); 21 | } 22 | } 23 | for (const key in data) { 24 | const camelKey = snakeToCamel(key); 25 | if(camelKey != key){ 26 | data[camelKey] = data[key]; 27 | delete data[key]; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /components/visual/AppPreview.tsx: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * 4 | * Image Preview component, this component is used at the very first page. Because there is only one image at the whole page, image is static, but you can always change it. 5 | * 6 | * @param {String} image - Image shown in the preview. 7 | * 8 | */ 9 | 10 | export default function ImagePreview() { 11 | return ( 12 | <> 13 |
14 | 15 |
16 | 35 | 36 | ); 37 | } 38 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 umutyesildal 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "yesildal-portfolio", 3 | "version": "0.1.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "next dev", 7 | "build": "next build", 8 | "start": "next start", 9 | "lint": "next lint" 10 | }, 11 | "dependencies": { 12 | "@emotion/react": "^11.10.5", 13 | "@emotion/styled": "^11.10.5", 14 | "@mui/icons-material": "^5.10.15", 15 | "@mui/material": "^5.10.17", 16 | "bootstrap": "^5.2.3", 17 | "cookies-next": "^2.0.4", 18 | "express-useragent": "^1.0.15", 19 | "gsap": "^3.11.3", 20 | "html-react-parser": "^3.0.7", 21 | "is-mobile": "^3.1.1", 22 | "js-cookie": "^3.0.1", 23 | "next": "^12.2.5", 24 | "node-html-parser": "^5.3.3", 25 | "notion-client": "^6.15.6", 26 | "prop-types": "^15.8.1", 27 | "react": "17.0.2", 28 | "react-device-detect": "^2.2.2", 29 | "react-dom": "17.0.2", 30 | "react-gtm-module": "^2.0.11", 31 | "react-lottie": "^1.2.3", 32 | "react-notion-x": "^6.15.7", 33 | "react-scroll": "^1.8.9", 34 | "react-useinterval": "^1.0.2", 35 | "remark": "^14.0.2", 36 | "remark-html": "^15.0.1" 37 | }, 38 | "devDependencies": { 39 | "@types/gsap": "^3.0.0", 40 | "@types/react": "^18.0.17", 41 | "@types/react-scroll": "^1.8.5", 42 | "eslint": "8.12.0", 43 | "eslint-config-next": "12.1.2", 44 | "typescript": "^4.7.4" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /pages/[slug].tsx: -------------------------------------------------------------------------------- 1 | import Head from "next/head"; 2 | import CommonFooter from "../components/CommonFooter"; 3 | import Navigation from "components/Navigation"; 4 | 5 | const page = ({ content, seoDescription, style, pageSpesificStyle }) => { 6 | return ( 7 | <> 8 | 9 | 10 | 11 | 12 | 13 | 14 | 19 |
20 |
24 |
25 | 26 | 27 | 28 | 29 | ); 30 | }; 31 | 32 | export async function getServerSideProps(context) { 33 | let found = false; 34 | let props = { 35 | name: context.params.slug, 36 | content: "Not found", 37 | seoTitle: "Not found", 38 | seoDescription: "Not found", 39 | style: "", 40 | head: "", 41 | description: "", 42 | pageSpesificHead: "", 43 | pageSpesificStyle: "", 44 | }; 45 | if (found) { 46 | return { 47 | props: props, 48 | }; 49 | } else { 50 | return { 51 | redirect: { 52 | destination: "/", 53 | permanent: false, 54 | }, 55 | }; 56 | } 57 | } 58 | 59 | export default page; 60 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Software Developer Folio 2 | 3 | ## A clean, beautiful and responsive portfolio template for Developers! 4 | 5 | ![Portfolio Website](https://repository-images.githubusercontent.com/577325623/4f220169-ebd3-4aa6-8e9b-b6b0909b5cd2) 6 | 7 | Nearly all the components are dynamic and easy to use! Feel free to use it as-is or personalize it as much as you want. 8 | 9 | If you'd like to **contribute** and make this much better for other users, please do. 10 | 11 | 12 | ## Project Covers 13 | ✔️ Homepage\ 14 | ✔️ Expertise\ 15 | ✔️ Experience\ 16 | ✔️ Work and Projects\ 17 | ✔️ Contact 18 | 19 | To view a live example, **[click here](https://yesildal.me)**. 20 | 21 | 22 | ## Getting Started 23 | 24 | These instructions will get you a copy of the project up and running on your local machine for development and testing purposes. 25 | 26 | The versions i have used in the project. 27 | 28 | ``` 29 | node@v16.16.0 30 | yarn@1.22.17 31 | git@2.37.3 32 | ``` 33 | 34 | ## How To Use 35 | 36 | From your command line and clone. 37 | 38 | ```bash 39 | # Clone this repository 40 | git clone https://github.com/umutyesildal/yesildal.me-personal-portfolio.git 41 | 42 | # Go into the repository 43 | cd yesildal.me-personal-portfolio 44 | 45 | # Install dependencies 46 | yarn 47 | 48 | # Start a local dev server 49 | yarn dev 50 | ``` 51 | 52 | ## Deployment 53 | 54 | For deployment I have used [vercel](https://vercel.app/) and I am pretty happy with it. 55 | ```bash 56 | # Build & Development Settings 57 | Framework Preset: Nextjs 58 | Build command: next build 59 | Output directory: default 60 | Install command: yarn 61 | Development command: next 62 | ``` 63 | 64 | 65 | 66 | 67 | ## Technologies Used 68 | 69 | - [React](https://reactjs.org/) 70 | - [Next](https://nextjs.org/) 71 | - [gsap](https://greensock.com/gsap/) 72 | -------------------------------------------------------------------------------- /components/CommonFooter.tsx: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | * Footer 4 | * 5 | * @param {String} text - Footer text 6 | * 7 | */ 8 | 9 | export default function CommonFooter() { 10 | return ( 11 | <> 12 |
13 |
14 |

Built by yesildal.

15 |
16 | 53 | 66 | 67 | ); 68 | } 69 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .next 3 | **/.DS_Store 4 | .vscode 5 | 6 | ### NextJS ### 7 | # Next build dir 8 | .next/ 9 | 10 | ### PhpStorm ### 11 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider 12 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 13 | 14 | # User-specific stuff 15 | .idea 16 | 17 | # CMake 18 | cmake-build-*/ 19 | # File-based project format 20 | *.iws 21 | 22 | # IntelliJ 23 | out/ 24 | 25 | # mpeltonen/sbt-idea plugin 26 | .idea_modules/ 27 | 28 | # JIRA plugin 29 | atlassian-ide-plugin.xml 30 | 31 | # Cursive Clojure plugin 32 | .idea/replstate.xml 33 | 34 | # SonarLint plugin 35 | .idea/sonarlint/ 36 | 37 | # Crashlytics plugin (for Android Studio and IntelliJ) 38 | com_crashlytics_export_strings.xml 39 | crashlytics.properties 40 | crashlytics-build.properties 41 | fabric.properties 42 | 43 | # Editor-based Rest Client 44 | .idea/httpRequests 45 | 46 | # Android studio 3.1+ serialized cache file 47 | .idea/caches/build_file_checksums.ser 48 | 49 | ### PhpStorm Patch ### 50 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 51 | 52 | # *.iml 53 | # modules.xml 54 | # .idea/misc.xml 55 | # *.ipr 56 | 57 | # Sonarlint plugin 58 | # https://plugins.jetbrains.com/plugin/7973-sonarlint 59 | .idea/**/sonarlint/ 60 | 61 | # SonarQube Plugin 62 | # https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin 63 | .idea/**/sonarIssues.xml 64 | 65 | # Markdown Navigator plugin 66 | # https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced 67 | .idea/**/markdown-navigator.xml 68 | .idea/**/markdown-navigator-enh.xml 69 | .idea/**/markdown-navigator/ 70 | 71 | # Cache file creation bug 72 | # See https://youtrack.jetbrains.com/issue/JBR-2257 73 | .idea/$CACHE_FILE$ 74 | 75 | # CodeStream plugin 76 | # https://plugins.jetbrains.com/plugin/12206-codestream 77 | .idea/codestream.xml 78 | 79 | # Azure Toolkit for IntelliJ plugin 80 | # https://plugins.jetbrains.com/plugin/8053-azure-toolkit-for-intellij 81 | .idea/**/azureSettings.xml 82 | 83 | ### react ### 84 | .DS_* 85 | *.log 86 | logs 87 | **/*.backup.* 88 | **/*.back.* 89 | 90 | node_modules 91 | bower_components 92 | 93 | *.sublime* 94 | 95 | psd 96 | thumb 97 | sketch 98 | .vercel 99 | -------------------------------------------------------------------------------- /components/home/Projects.tsx: -------------------------------------------------------------------------------- 1 | import ProjectsColumn from "components/projects/ProjectsColumn"; 2 | import { useState } from "react"; 3 | 4 | 5 | /** 6 | * 7 | * Projects section, only for mobile 8 | * 9 | * @param {String} title - Title of the component. 10 | * @param {String} subtitle - Subtitle of the component. 11 | * 12 | */ 13 | 14 | 15 | export default function Projects() { 16 | const [texts] = useState({ 17 | title: `Work, my previous projects.`, 18 | subtitle: "Here are the projects that I have worked on before.", 19 | }); 20 | 21 | return ( 22 | <> 23 |
24 |
25 |

26 |

27 |
28 |
29 | 30 |
31 |
32 | 90 | 91 | ); 92 | } 93 | -------------------------------------------------------------------------------- /public/lotties/scrollDown.json: -------------------------------------------------------------------------------- 1 | {"v":"5.5.2","fr":30,"ip":0,"op":90,"w":500,"h":500,"nm":"Comp 1","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"Ball","sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":5,"s":[100]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":60,"s":[100]},{"t":70,"s":[0]}],"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"s":true,"x":{"a":0,"k":250,"ix":3},"y":{"a":1,"k":[{"i":{"x":[0.689],"y":[1]},"o":{"x":[0.213],"y":[1.081]},"t":10,"s":[255]},{"i":{"x":[0.284],"y":[1]},"o":{"x":[0.918],"y":[0]},"t":24,"s":[242.838]},{"i":{"x":[0.348],"y":[1]},"o":{"x":[0.589],"y":[-0.009]},"t":50,"s":[426.703]},{"t":60,"s":[409.703]}],"ix":4}},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[114,114,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[28.594,28.594],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0.297,-72.703],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":90,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"Mouse","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"s":true,"x":{"a":0,"k":250,"ix":3},"y":{"a":0,"k":250,"ix":4}},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"hasMask":true,"masksProperties":[{"inv":false,"mode":"f","pt":{"a":0,"k":{"i":[[0,0],[0,0],[0,-58.818],[0,0],[-58.818,0],[0,0],[0,58.818],[0,0],[58.818,0]],"o":[[0,0],[-58.818,0],[0,0],[0,58.818],[0,0],[58.818,0],[0,0],[0,-58.818],[0,0]],"v":[[0.5,-186.5],[0.5,-186.5],[-106,-80],[-106,81],[0.5,187.5],[0.5,187.5],[107,81],[107,-80],[0.5,-186.5]],"c":true},"ix":1},"o":{"a":0,"k":100,"ix":3},"x":{"a":0,"k":0,"ix":4},"nm":"Mask 1"}],"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-47.696,0],[0,-47.696],[0,0],[47.696,0],[0,47.696],[0,0]],"o":[[47.696,0],[0,0],[0,47.696],[-47.696,0],[0,0],[0,-47.696]],"v":[[0,-167],[86.5,-80.5],[86.5,80.5],[0,167],[-86.5,80.5],[-86.5,-80.5]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":18,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Shape 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":90,"st":0,"bm":0}],"markers":[]} -------------------------------------------------------------------------------- /components/shared/Hero.tsx: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * 4 | * Shared Hero Component of the website 5 | * 6 | * @param {String} title - Title of the hero component. 7 | * @param {String} subtitle - Subtitle of the hero component. 8 | * @param {String} background - Background image of the hero component. 9 | * @param {String} backgroundStyle - The style of Background of the hero component. 10 | * 11 | */ 12 | 13 | export default function Hero(props) { 14 | const title = props.title; 15 | const subtitle = props.subtitle; 16 | const background = props.background; 17 | const backgroundStyle = props.backgroundStyle; 18 | return ( 19 | <> 20 |
21 | {background && ( 22 |
23 | 24 |
25 | )} 26 |

{title}

27 | {subtitle &&
{subtitle}
} 28 |
29 | 30 | 109 | 110 | ); 111 | } 112 | -------------------------------------------------------------------------------- /components/shared/Accordion.tsx: -------------------------------------------------------------------------------- 1 | import * as React from "react"; 2 | import Accordion from "@mui/material/Accordion"; 3 | import AccordionSummary from "@mui/material/AccordionSummary"; 4 | import AccordionDetails from "@mui/material/AccordionDetails"; 5 | import Typography from "@mui/material/Typography"; 6 | import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; 7 | import { useState } from "react"; 8 | 9 | /** 10 | * 11 | * A simple accordion component used at FAQ page, created by using Material UI package. 12 | * 13 | * @param {Array} questions - Array of questions, data comes from strapi. questionTitle is the title, questionDescription is the description. 14 | * 15 | */ 16 | 17 | export default function SimpleAccordion() { 18 | const [questions] = useState({ 19 | questions: [ 20 | { 21 | questionTitle: "Entrepreneur İTÜ Çekirdek Jan2020-June2020", 22 | questionDescription: 23 | 'Learned the fundamentals of entrepreneurship. Taken various seminars from İTÜ Çekirdek Mentors and found the opportunity to do meetings with these Mentors. Worked at a time management project called "Crillo" and earned 10.000$ worth of credit from İTÜ Çekirdek.', 24 | }, 25 | { 26 | questionTitle: "Intern Vendrops Technologies Sep2020-Mar2021", 27 | questionDescription: 28 | "I learned the fundamental parts of the backend web programming using Node.js, Express.js, Gatsby.js. I created a Documentation page of the product using Gatsby.js.I learned the fundamentals of Testing. I learned and used Whitebox Testing, Blackbox Testing, Monkey Testing, Unit Testing and used them when testing the project. I helped the team in the creation of Facilera Tasks App by flutter development, bug fixing and testing.Learned the real life usage of Agile Methodology and SCRUM.", 29 | }, 30 | { 31 | questionTitle: "Flutter Developer Platri IT GmbH Feb2021-Jan2022", 32 | questionDescription: 33 | "Worked at some projects called “DanceFlavors”,”Signalficant”, ”Nimag” at Platri GmbH. Working with BLoC, state management and Null Safety since the start of the project. Using the package system and creating my own packages in order to have cleaner code and making the packages continually usable for other projects. Using multiple local databases for different needs so that each database has their own usage. For Key-Value Pair i used Hive and for SQL database i used SQFLite.", 34 | }, 35 | { 36 | questionTitle: "Software Developer Metavest Mar2022-Still", 37 | questionDescription: 38 | "Currently working at Metavest as a software developer, mostly focused on creating front-end pages using react and javascript and creating micro-packages for various purposes with python and javascript.", 39 | }, 40 | ], 41 | }); 42 | 43 | return ( 44 | <> 45 |
46 | {questions.questions.map((i) => { 47 | return ( 48 | 56 | } 58 | aria-controls="panel1a-content" 59 | id="panel1a-header" 60 | > 61 | 70 | {i.questionTitle} 71 | 72 | 73 | 74 | 82 | {i.questionDescription} 83 | 84 | 85 | 86 | ); 87 | })} 88 |
89 | 96 | 97 | ); 98 | } 99 | -------------------------------------------------------------------------------- /components/home/Contact.tsx: -------------------------------------------------------------------------------- 1 | import { useState } from "react"; 2 | 3 | 4 | /** 5 | * 6 | * Contact component. Here you can explain your Contact status. 7 | * 8 | * @param {String} title - Title of the component. 9 | * @param {String} subtitle - Subtitle of the component. 10 | * 11 | */ 12 | 13 | export default function Contact() { 14 | const [texts] = useState({ 15 | title: `Get in touch with me.`, 16 | subtitle: `Whether you have a question or simply want to say hello, I will do my best to respond to you asap.

"You miss 100% of the shots you don't take. - Wayne Gretzky" by Michael Scott 17 | `, 18 | }); 19 | 20 | return ( 21 | <> 22 |
23 |
24 |

25 |

26 |
27 |
28 | 35 |
36 |
37 | 38 | 149 | 150 | ); 151 | } 152 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | We as members, contributors, and leaders pledge to make participation in our 6 | community a harassment-free experience for everyone, regardless of age, body 7 | size, visible or invisible disability, ethnicity, sex characteristics, gender 8 | identity and expression, level of experience, education, socio-economic status, 9 | nationality, personal appearance, race, religion, or sexual identity 10 | and orientation. 11 | 12 | We pledge to act and interact in ways that contribute to an open, welcoming, 13 | diverse, inclusive, and healthy community. 14 | 15 | ## Our Standards 16 | 17 | Examples of behavior that contributes to a positive environment for our 18 | community include: 19 | 20 | * Demonstrating empathy and kindness toward other people 21 | * Being respectful of differing opinions, viewpoints, and experiences 22 | * Giving and gracefully accepting constructive feedback 23 | * Accepting responsibility and apologizing to those affected by our mistakes, 24 | and learning from the experience 25 | * Focusing on what is best not just for us as individuals, but for the 26 | overall community 27 | 28 | Examples of unacceptable behavior include: 29 | 30 | * The use of sexualized language or imagery, and sexual attention or 31 | advances of any kind 32 | * Trolling, insulting or derogatory comments, and personal or political attacks 33 | * Public or private harassment 34 | * Publishing others' private information, such as a physical or email 35 | address, without their explicit permission 36 | * Other conduct which could reasonably be considered inappropriate in a 37 | professional setting 38 | 39 | ## Enforcement Responsibilities 40 | 41 | Community leaders are responsible for clarifying and enforcing our standards of 42 | acceptable behavior and will take appropriate and fair corrective action in 43 | response to any behavior that they deem inappropriate, threatening, offensive, 44 | or harmful. 45 | 46 | Community leaders have the right and responsibility to remove, edit, or reject 47 | comments, commits, code, wiki edits, issues, and other contributions that are 48 | not aligned to this Code of Conduct, and will communicate reasons for moderation 49 | decisions when appropriate. 50 | 51 | ## Scope 52 | 53 | This Code of Conduct applies within all community spaces, and also applies when 54 | an individual is officially representing the community in public spaces. 55 | Examples of representing our community include using an official e-mail address, 56 | posting via an official social media account, or acting as an appointed 57 | representative at an online or offline event. 58 | 59 | ## Enforcement 60 | 61 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 62 | reported to the community leaders responsible for enforcement at 63 | . 64 | All complaints will be reviewed and investigated promptly and fairly. 65 | 66 | All community leaders are obligated to respect the privacy and security of the 67 | reporter of any incident. 68 | 69 | ## Enforcement Guidelines 70 | 71 | Community leaders will follow these Community Impact Guidelines in determining 72 | the consequences for any action they deem in violation of this Code of Conduct: 73 | 74 | ### 1. Correction 75 | 76 | **Community Impact**: Use of inappropriate language or other behavior deemed 77 | unprofessional or unwelcome in the community. 78 | 79 | **Consequence**: A private, written warning from community leaders, providing 80 | clarity around the nature of the violation and an explanation of why the 81 | behavior was inappropriate. A public apology may be requested. 82 | 83 | ### 2. Warning 84 | 85 | **Community Impact**: A violation through a single incident or series 86 | of actions. 87 | 88 | **Consequence**: A warning with consequences for continued behavior. No 89 | interaction with the people involved, including unsolicited interaction with 90 | those enforcing the Code of Conduct, for a specified period of time. This 91 | includes avoiding interactions in community spaces as well as external channels 92 | like social media. Violating these terms may lead to a temporary or 93 | permanent ban. 94 | 95 | ### 3. Temporary Ban 96 | 97 | **Community Impact**: A serious violation of community standards, including 98 | sustained inappropriate behavior. 99 | 100 | **Consequence**: A temporary ban from any sort of interaction or public 101 | communication with the community for a specified period of time. No public or 102 | private interaction with the people involved, including unsolicited interaction 103 | with those enforcing the Code of Conduct, is allowed during this period. 104 | Violating these terms may lead to a permanent ban. 105 | 106 | ### 4. Permanent Ban 107 | 108 | **Community Impact**: Demonstrating a pattern of violation of community 109 | standards, including sustained inappropriate behavior, harassment of an 110 | individual, or aggression toward or disparagement of classes of individuals. 111 | 112 | **Consequence**: A permanent ban from any sort of public interaction within 113 | the community. 114 | 115 | ## Attribution 116 | 117 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], 118 | version 2.0, available at 119 | https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. 120 | 121 | Community Impact Guidelines were inspired by [Mozilla's code of conduct 122 | enforcement ladder](https://github.com/mozilla/diversity). 123 | 124 | [homepage]: https://www.contributor-covenant.org 125 | 126 | For answers to common questions about this code of conduct, see the FAQ at 127 | https://www.contributor-covenant.org/faq. Translations are available at 128 | https://www.contributor-covenant.org/translations. 129 | -------------------------------------------------------------------------------- /pages/index.tsx: -------------------------------------------------------------------------------- 1 | import CommonFooter from "../components/CommonFooter"; 2 | import { useEffect, useState } from "react"; 3 | import Home from "components/home/Home"; 4 | import Expertise from "components/home/Expertise"; 5 | import Navigation from "components/Navigation"; 6 | import Experience from "components/home/Experience"; 7 | import Contact from "components/home/Contact"; 8 | import Work from "components/work/Work"; 9 | import { BrowserView, MobileView } from "react-device-detect"; 10 | import Projects from "components/home/Projects"; 11 | import Head from "next/head"; 12 | import parse from "html-react-parser"; 13 | 14 | export default function Index() { 15 | const [texts] = useState({ 16 | title: `Umut Yeşildal`, 17 | description: ``, 18 | head: ` 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | `, 82 | }); 83 | 84 | /// To use the animation for expertise section. 85 | useEffect(() => { 86 | const observer = new IntersectionObserver((entries) => { 87 | entries.forEach((entry) => { 88 | if (entry.isIntersecting) { 89 | entry.target.classList.add("fade-in"); 90 | } else { 91 | entry.target.classList.remove("fade-in"); 92 | } 93 | }); 94 | }); 95 | observer.observe(document.querySelector("#section2")); 96 | setTimeout(function () { 97 | document.querySelector(".vl-leaderboard") && 98 | (document.querySelector(".vl-leaderboard").style.display = 99 | "none"); 100 | }, 50); 101 | }); 102 | 103 | const parseHead = parse(texts.head); 104 | return ( 105 | <> 106 | 107 | 108 | 109 | 110 | 111 | {texts.title} 112 | 113 | 114 | {parseHead} 115 | 116 | 117 |
118 |
119 |
120 |
121 | 122 |
123 |
124 | 125 |
126 |
127 | 128 | 129 | 130 | 131 | 132 | 133 |
134 |
135 | 136 |
137 |
138 | 139 |
140 |
141 |
142 |
143 | 144 | 149 | 150 | ); 151 | } 152 | -------------------------------------------------------------------------------- /components/projects/ProjectsColumn.tsx: -------------------------------------------------------------------------------- 1 | import React, { useState } from "react"; 2 | 3 | /** 4 | * 5 | * Projects Column from the Work section. Only for mobile 6 | * 7 | * @param {Array} projects - All the projects person has done. It has 6 attributes: backgroundColor for background color of the bubble. Type for type of the projects. Title and subtitle of the project. Techs the technologies projects has used. Links is a json with 2 attributes github and website. 8 | * 9 | * 10 | */ 11 | function ProjectsColumn() { 12 | const [texts] = useState({ 13 | projects: [ 14 | { 15 | backgroundColor: `#dfe6e940`, 16 | type: `Mobile App`, 17 | title: `Danceflavors`, 18 | subtitle: 19 | "Worked on Danceflavors app for a year, created frontend for the app, took a part in designing and implementing the architecture of the backend. Mainly used Flutter and Dart programming language, Hive and SQFLite for database, BLoC for state management.", 20 | techs: "Flutter SQL NoSQL BloC", 21 | links: { 22 | github: "", 23 | website: "https://www.danceflavors.com/", 24 | }, 25 | }, 26 | { 27 | backgroundColor: `#E4FAFE`, 28 | type: `Website`, 29 | title: `Metavest`, 30 | subtitle: 31 | "Worked on metavest.app website, created bunch of pages and components with the care of responsive design. Mainly used Reactjs and Nextjs along with CSS and HTML, used Strapi for CMS and localization.", 32 | techs: "Reactjs Nextjs Strapi CSS HTML", 33 | links: { 34 | github: "", 35 | website: "https://metavest.app/", 36 | }, 37 | }, 38 | { 39 | backgroundColor: `#CCFAED`, 40 | type: `Mobile App`, 41 | title: `DaiDay`, 42 | subtitle: 43 | "Created my first solo Mobile app and published it on Google Play Store, even though it is not perfect i am proud of my work and that i learned it all by myself during University. Mainly used Flutter and Dart programming language, Hive and SQFLite for database, BLoC for state management.", 44 | techs: "Flutter SQL NoSQL BloC", 45 | links: { 46 | github: "https://github.com/umutyesildal/daiday", 47 | website: 48 | "https://play.google.com/store/apps/details?id=com.greendal.daiday", 49 | }, 50 | }, 51 | { 52 | backgroundColor: `#D5EAFF`, 53 | type: `Mobile App`, 54 | title: `Mercedes Assistify`, 55 | subtitle: 56 | "At the last year of my Bachelor, University arranged a joint lecture with Mercedes Turkey. I had the chance to meet with executives of Mercedes Turkey and find a solution to a problem Mercedes is having. Assistify is focused on solving Mercedes car users problems via Mobile App. Mainly used Flutter and Dart programming language, Hive and SQFLite for database, BLoC for state management.", 57 | techs: "Flutter SQL NoSQL BloC", 58 | links: { 59 | github: "https://github.com/umutyesildal/mercedes-assistify", 60 | website: "", 61 | }, 62 | }, 63 | ], 64 | }); 65 | 66 | /// Returns the items from the projects array. 67 | return ( 68 | <> 69 |
70 | {texts.projects.map((item, i) => { 71 | return ( 72 |
76 |

81 |

86 |

91 | 96 |
97 | {item.links.github != "" ? ( 98 | 99 | 100 | 101 | ) : null} 102 | {item.links.website != "" ? ( 103 | 104 | 105 | 106 | ) : null} 107 |
108 |
109 | ); 110 | })} 111 |
112 | 166 | 167 | ); 168 | } 169 | 170 | export default ProjectsColumn; 171 | -------------------------------------------------------------------------------- /components/home/Experience.tsx: -------------------------------------------------------------------------------- 1 | import SimpleAccordion from "components/shared/Accordion"; 2 | import { useState } from "react"; 3 | 4 | /** 5 | * 6 | * Expertise component. Here you can explain your Experiences. 7 | * 8 | * @param {String} title - Title of the component. 9 | * @param {String} subtitle - Subtitle of the component. 10 | * 11 | */ 12 | 13 | export default function Experience() { 14 | const [texts] = useState({ 15 | title: `Experience, where I worked before`, 16 | subtitle: `What i have done before, where I worked before and which position i was before`, 17 | }); 18 | 19 | return ( 20 | <> 21 |
22 |
23 |

24 |

25 |
26 | 27 |
28 |
29 |
30 | 228 | 233 | 234 | ); 235 | } 236 | -------------------------------------------------------------------------------- /components/home/Home.tsx: -------------------------------------------------------------------------------- 1 | import ImagePreview from "components/visual/AppPreview"; 2 | import { useState, useEffect, useRef } from "react"; 3 | 4 | /** 5 | * 6 | * Home of the app. First page you see 7 | * 8 | * @param {String} title - Title of the component. 9 | * @param {String} subtitle - Subtitle of the component. 10 | * 11 | */ 12 | 13 | export default function Home() { 14 | const [texts] = useState({ 15 | title: "Umut Yunus Yeşildal", 16 | subtitle: 17 | "I am a Software Developer focused on drifting with the wind of newly developed tech.

Jack of all trades, master of none, but oftentimes better than a master of one.", 18 | }); 19 | return ( 20 | <> 21 |
22 |
23 |

{texts.title}

24 |

28 |
29 |
30 |
31 | 32 |
33 |
34 |
35 | 36 | 200 | 230 | 231 | ); 232 | } 233 | -------------------------------------------------------------------------------- /styles/globals.css: -------------------------------------------------------------------------------- 1 | @font-face { 2 | font-family: 'Visby'; 3 | src: url(/fonts/VisbyLight.otf) format('opentype'); 4 | font-weight: 300; 5 | font-style: normal; 6 | font-display: swap; 7 | } 8 | 9 | @font-face { 10 | font-family: 'Visby'; 11 | src: url(/fonts/VisbyRegular.otf) format('opentype'); 12 | font-weight: 400; 13 | font-style: normal; 14 | font-display: swap; 15 | } 16 | 17 | @font-face { 18 | font-family: 'Visby'; 19 | src: url(/fonts/VisbyMedium.otf) format('opentype'); 20 | font-weight: 500; 21 | font-style: normal; 22 | font-display: swap; 23 | } 24 | 25 | @font-face { 26 | font-family: 'Visby'; 27 | src: url(/fonts/VisbyBold.otf) format('opentype'); 28 | font-weight: 700; 29 | font-style: normal; 30 | font-display: swap; 31 | } 32 | 33 | * { 34 | margin: 0; 35 | padding: 0; 36 | box-sizing: border-box; 37 | } 38 | 39 | :root{ 40 | --theme-color: #2d3436; 41 | --light-background-color: #ECF6F8; 42 | --title-color: rgb(254 105 111); 43 | --light-alternate-color: #FFF4F2; 44 | } 45 | 46 | /* wide-gamut P3 support */ 47 | @supports (color: color(display-p3 1 1 1)) { 48 | :root { 49 | --title-color: color(display-p3 0.996 0.411 0.425); 50 | --theme-color: color(display-p3 0.137 0.301 0.388); 51 | } 52 | } 53 | 54 | @keyframes fadeIn { 55 | from { 56 | transform: scale(0.95) translateY(-5%); 57 | opacity: 0; 58 | } 59 | 60 | to { 61 | transform: scale(1) translateY(0); 62 | opacity: 1; 63 | } 64 | } 65 | 66 | @keyframes slideUpFadeIn { 67 | from { 68 | transform: translateY(1.32275vw); 69 | opacity: 0.2; 70 | } 71 | 72 | to { 73 | transform: translateY(0); 74 | opacity: 1; 75 | } 76 | } 77 | 78 | @keyframes scaleInFadeIn { 79 | from { 80 | transform: scale(1.3); 81 | opacity: 0; 82 | } 83 | 84 | to { 85 | transform: scale(1); 86 | opacity: 1; 87 | } 88 | } 89 | 90 | @keyframes onlyfadeIn { 91 | from { 92 | opacity: 0; 93 | } 94 | 95 | to { 96 | opacity: 1; 97 | } 98 | } 99 | 100 | 101 | @keyframes intro { 102 | from { 103 | height: 100vh; 104 | border-radius: 0 0 0 0; 105 | } 106 | 107 | to { 108 | border-radius: 0px 0px 52px 394px; 109 | height: 95vh; 110 | } 111 | } 112 | 113 | html { 114 | scroll-behavior: smooth; 115 | font-family: Visby, -apple-system, BlinkMacSystemFont, "Segoe UI", 116 | Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; 117 | font-style: normal; 118 | font-weight: normal; 119 | overflow-y: overlay; 120 | overflow-x: hidden; 121 | /* scroll-snap-type: y proximity; DO NOT ENABLE THIS, IT MESSES UP CHROME. having it on body is OK though. */ 122 | } 123 | 124 | body { 125 | font-family: sans-serif; 126 | font-family: Visby, -apple-system, BlinkMacSystemFont, "Segoe UI", 127 | Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; 128 | font-style: normal; 129 | font-weight: normal; 130 | scroll-snap-type: y proximity; 131 | } 132 | 133 | .scroll-snap-y { 134 | scroll-snap-type: y mandatory; 135 | } 136 | 137 | 138 | ul, 139 | li { 140 | list-style: none; 141 | padding: 0; 142 | margin: 0; 143 | } 144 | 145 | a{ 146 | cursor: pointer; 147 | color: var(--theme-color); 148 | font-weight: 400; 149 | text-decoration: none; 150 | } 151 | 152 | .mobile { 153 | display: none; 154 | } 155 | 156 | 157 | .primary-button { 158 | background: #0abde3; 159 | background: color(display-p3 0.549 0.929 0.996); 160 | box-shadow: 0px 0.26455vw 0.26455vw rgba(140, 237, 254, 0.25); 161 | border: none; 162 | border-radius: 2.24867vw; 163 | display: flex; 164 | flex-direction: row; 165 | align-items: flex-start; 166 | padding: 0 1.05820vw; 167 | font-family: Visby, -apple-system, BlinkMacSystemFont, "Segoe UI", 168 | Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji"; 169 | font-style: normal; 170 | font-weight: 400; 171 | font-size: 1.32275vw; 172 | line-height: 1.71195vw; 173 | display: flex; 174 | align-items: center; 175 | height: 2.77777vw; 176 | color: var(--theme-color); 177 | text-decoration: none; 178 | transition: 0.3s ease-out all; 179 | cursor: pointer; 180 | } 181 | 182 | .primary-button:hover { 183 | background: hsl(189deg 100% 55%); 184 | box-shadow: 0px 0.06613vw 0.52910vw rgb(140 237 254 / 45%); 185 | } 186 | 187 | .fade-in .animation-element { 188 | animation: fadeIn 0.8s cubic-bezier(0.65, 0, 0.35, 1) forwards; 189 | } 190 | 191 | .vlns .vl-modal{ 192 | background: #293a45a8; 193 | } 194 | 195 | 196 | 197 | @media screen and (max-width: 1200px) { 198 | html, 199 | body { 200 | width: 100%; 201 | } 202 | .primary-button { 203 | min-height: 34px; 204 | border-radius: 18.8637px; 205 | /* font-size: 11.5682px; */ 206 | line-height: 21px; 207 | } 208 | 209 | .mobile { 210 | display: flex; 211 | } 212 | 213 | nav { 214 | padding: 21px 23px; 215 | margin-bottom: -70px; 216 | } 217 | 218 | nav.sticky { 219 | padding: 21px 23px; 220 | -webkit-backdrop-filter: none; 221 | backdrop-filter: none; 222 | } 223 | 224 | nav.sticky.dim { 225 | padding: 21px 23px; 226 | -webkit-backdrop-filter: none; 227 | backdrop-filter: none; 228 | } 229 | 230 | nav.sticky .mobile-menu { 231 | transition: 0.3s all cubic-bezier(0.075, 0.82, 0.165, 1); 232 | } 233 | 234 | 235 | nav > img { 236 | width: 196px; 237 | position: relative; 238 | z-index: 2; 239 | } 240 | 241 | nav > img, nav.sticky > img, nav.sticky.dim > img.colored { 242 | display: flex; 243 | } 244 | 245 | nav > img.colored, nav.sticky > img.colored, nav.sticky.dim > img { 246 | display: none; 247 | } 248 | 249 | nav .menu { 250 | display: none; 251 | } 252 | 253 | nav .mobile-menu { 254 | display: flex; 255 | position: absolute; 256 | width: 100%; 257 | padding-top: 70px; 258 | left: 0; 259 | top: 0; 260 | -webkit-backdrop-filter: blur(1rem); 261 | backdrop-filter: blur(1rem); 262 | transition: 0.3s all cubic-bezier(0.075, 0.82, 0.165, 1); 263 | } 264 | 265 | nav .mobile-menu.opened { 266 | padding: 107px 0 86px 0; 267 | background: hsl(0deg 0% 100% / 15%); 268 | } 269 | 270 | nav .mobile-menu button { 271 | display: flex; 272 | height: 32px; 273 | width: 32px; 274 | min-height: 32px; 275 | min-width: 32px; 276 | right: 16px; 277 | top: 16px; 278 | position: absolute; 279 | border: none; 280 | background: transparent; 281 | background-repeat: no-repeat; 282 | background-position: center center; 283 | transition: 0.3s all cubic-bezier(0.075, 0.82, 0.165, 1); 284 | transform: rotate(0deg); 285 | } 286 | 287 | nav .mobile-menu.closed button { 288 | background-size: 24px 16px; 289 | background-image: url("/menu_icon.png"); 290 | animation: cubic-bezier(0.075, 0.82, 0.165, 1) 0.3s rotateLeft; 291 | } 292 | 293 | nav.sticky.dim .mobile-menu.closed button { 294 | background-image: url("/menu_icon_dim.png"); 295 | } 296 | 297 | nav .mobile-menu ul { 298 | opacity: 0; 299 | position: absolute; 300 | pointer-events: none; 301 | transition: 0.3s all cubic-bezier(0.075, 0.82, 0.165, 1); 302 | display: flex; 303 | flex-direction: column; 304 | align-items: center; 305 | width: 100%; 306 | } 307 | 308 | nav .mobile-menu.opened ul { 309 | opacity: 1; 310 | position: relative; 311 | pointer-events: all; 312 | } 313 | 314 | nav .mobile-menu ul li.secondary { 315 | margin-right: 0; 316 | margin-bottom: 20px; 317 | border: 2px solid #b4b4be; 318 | font-size: 16px; 319 | line-height: 20px; 320 | border-radius: 16px; 321 | padding: 7px 2px; 322 | width: 205px; 323 | text-align: center; 324 | } 325 | 326 | 327 | } 328 | 329 | .arrow-button::after { 330 | content: '→'; 331 | margin-left: 0.4vw; 332 | } 333 | 334 | 335 | @media screen AND (min-width: 1921px) { 336 | .primary-button { 337 | font-size: 1vw; 338 | height: 2.213vw; 339 | } 340 | } 341 | -------------------------------------------------------------------------------- /components/home/Expertise.tsx: -------------------------------------------------------------------------------- 1 | import { useState } from "react"; 2 | 3 | /** 4 | * 5 | * Expertise component. Here you can explain your expertises. 6 | * 7 | * @param {String} title - Title of the component. 8 | * @param {String} subtitle - Subtitle of the component. 9 | * @param {String} itemTitle - The title of the item. 10 | * @param {String} item - Content of the item. 11 | * 12 | */ 13 | 14 | export default function Expertise() { 15 | const [texts] = useState({ 16 | title: `Expertise, what I worked on before.`, 17 | subtitle: `I have worked on bunch of projects and technologies but these are the topics i am most skilled at.`, 18 | item1Title: `Mobile Development`, 19 | item2Title: `Front-End Development`, 20 | item3Title: `Smart Contract Newbie`, 21 | item1: `Worked on mobile development with Flutter framework and dart programming language.`, 22 | item2: `Created beautiful UI for both mobile and web, mostly used React framework along with HTML-CSS.`, 23 | item3: `Even though this is an expertise page, i am passionate about the blockchain and smart contracts. Hopefully i will be deleting the Newbie tag from the title soon.`, 24 | }); 25 | 26 | return ( 27 | <> 28 |
29 |
30 |

34 |

38 | 39 |
    40 |
  • 41 | 42 |

    {texts.item1Title}

    43 | {texts.item1} 44 |
  • 45 |
  • 46 | 47 |

    {texts.item2Title}

    48 | {texts.item2} 49 |
  • 50 |
  • 51 | 52 |

    {texts.item3Title}

    53 | {texts.item3} 54 |
  • 55 |
56 |
57 |
58 | 269 | 274 | 275 | ); 276 | } 277 | -------------------------------------------------------------------------------- /components/work/Work.tsx: -------------------------------------------------------------------------------- 1 | import gsap from "gsap"; 2 | import { ScrollTrigger } from "gsap/dist/ScrollTrigger"; 3 | import React, { useRef, useEffect, useState } from "react"; 4 | gsap.registerPlugin(ScrollTrigger); 5 | 6 | /** 7 | * 8 | * Work page only for desktop. In this page i used gsap, scrolltrigger and it is not really optimal to use gsap and react. It is 5 different pages with static texts. 9 | * 10 | * @param {String} title - Title of the component. 11 | * @param {String} subtitle - Subtitle of component. 12 | * @param {String} itemTitle - Title of the item. 13 | * @param {String} itemSubtitle - Subtitle of the item. 14 | * @param {String} itemLink - A link for the item. 15 | * 16 | */ 17 | 18 | export default function WorkDesktop() { 19 | const [texts] = useState({ 20 | title: `Work, my previous projects.`, 21 | subtitle: "Here are the projects that i have worked on before.", 22 | }); 23 | const panels = useRef([]); 24 | const panelsContainer = useRef(); 25 | 26 | const createPanelsRefs = (panel, index) => { 27 | panels.current[index] = panel; 28 | }; 29 | 30 | useEffect(() => { 31 | const totalPanels = panels.current.length; 32 | 33 | gsap.to(panels.current, { 34 | xPercent: -100 * (totalPanels - 1), 35 | ease: "none", 36 | scrollTrigger: { 37 | trigger: panelsContainer.current, 38 | pin: true, 39 | scrub: 1, 40 | snap: 1 / (totalPanels - 1), 41 | // base vertical scrolling on how wide the container is so it feels more natural. 42 | end: () => "+=" + 1080 * panels.current.length, 43 | }, 44 | }); 45 | }, []); 46 | 47 | return ( 48 | <> 49 | <> 50 |
51 |
createPanelsRefs(e, 0)} 54 | > 55 |
56 |

57 |

{texts.subtitle}

58 |
59 | Scroll down
60 |
61 |
62 |
63 |
createPanelsRefs(e, 1)}> 64 |
65 |

Danceflavors Mobile App`, 72 | }} 73 | >

74 |

80 | Worked on Danceflavors app for a year, created frontend for the 81 | app, took a part in designing and implementing the architecture 82 | of the backend. Mainly used Flutter and Dart programming 83 | language, Hive and SQFLite for database, BLoC for state 84 | management. 85 |

86 | 94 |
95 | DanceFlavors App 96 |
97 |
createPanelsRefs(e, 2)}> 98 |
99 |

Metavest Website`, 106 | }} 107 | >

108 |

114 | Worked on metavest.app website, created bunch of pages and 115 | components with the care of responsive design. Mainly used 116 | Reactjs and Nextjs along with CSS and HTML, used Strapi for CMS 117 | and localization. 118 |

119 | 128 |
129 | Metavest App 130 |
131 |
createPanelsRefs(e, 3)}> 132 |
133 |

DaiDay Mobile App`, 140 | }} 141 | >

142 |

148 | Created my first solo Mobile app and published it on Google Play 149 | Store, even though it is not perfect i am proud of my work and 150 | that i learned it all by myself during University. Mainly used 151 | Flutter and Dart programming language, Hive and SQFLite for 152 | database, BLoC for state management. 153 |

154 | 163 |
164 | DanceFlavors App 165 |
166 |
createPanelsRefs(e, 4)}> 167 |
168 |

Mercedes Assist App`, 176 | }} 177 | >

178 |

185 | During joint lecture between TAU and Mercedes Turkey, I had the 186 | chance to meet with executives and find a solution to a problem 187 | Mercedes is having. Assistify is focused on solving Mercedes car 188 | users problems via Mobile App. 189 |

190 | 198 |
199 |
203 |

Sharify Mobile App`, 211 | }} 212 | >

213 |

220 | Sharify is focused on preventing the product and food waste by 221 | connecting people in need. Just join and create a card 222 | describing the item or food you are willing to give away or 223 | check out cards to find anything you need! 224 |

225 | 232 |
233 |
234 |
createPanelsRefs(e, 5)}> 235 |
236 |

More, checkout more at links below`, 240 | }} 241 | >

242 | 259 |
260 |
261 |
262 | 263 | 608 | 609 | ); 610 | } 611 | -------------------------------------------------------------------------------- /components/Navigation.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState, useRef } from "react"; 2 | import { useRouter } from "next/router"; 3 | import { Link } from "react-scroll"; 4 | 5 | 6 | /** 7 | * 8 | * Navigation for Desktop. It is static. Every component requires a string and a section id. 9 | * 10 | */ 11 | 12 | export default function Navigation({ 13 | isSticky = false, 14 | isDimmed = false, 15 | isActionable = true, 16 | isDark = false, 17 | currentPage = {}, 18 | }) { 19 | const security = "Security"; 20 | const [state, setState] = useState({ 21 | isActive: false, 22 | isSticky: isSticky, 23 | isDimmed: isDimmed, 24 | isActionable: isActionable, 25 | }); 26 | const router = useRouter(); 27 | const { pathname, asPath } = router; 28 | const [language, setLanguage] = useState({ 29 | state: false, 30 | 31 | currentPage: currentPage, 32 | }); 33 | 34 | let offsetHeight = 0; 35 | 36 | const toggleMenu = () => { 37 | setState((state) => ({ ...state, isActive: !state.isActive })); 38 | }; 39 | 40 | function handleNavigationBackground() { 41 | if (typeof window !== "undefined") { 42 | if (isActionable) { 43 | if (window.pageYOffset > 0) { 44 | setState((state) => ({ ...state, isSticky: true })); 45 | if (window.pageYOffset + 50 > offsetHeight) { 46 | setState((state) => ({ ...state, isDimmed: true })); 47 | } else { 48 | setState((state) => ({ ...state, isDimmed: false })); 49 | } 50 | } else { 51 | setState((state) => ({ ...state, isSticky: false, isDimmed: false })); 52 | } 53 | } 54 | } 55 | } 56 | 57 | if (typeof window !== "undefined") { 58 | if (isActionable) { 59 | window.onscroll = function () { 60 | const introElem = document.querySelector(".intro"); 61 | if (introElem) { 62 | offsetHeight = 63 | document.querySelector(".intro")?.offsetHeight; 64 | } 65 | handleNavigationBackground(); 66 | setState((state) => ({ ...state, isActive: false })); 67 | setLanguage((state) => ({ ...state, state: false })); 68 | }; 69 | } 70 | } 71 | return ( 72 | <> 73 | 149 | 649 | 650 | 662 | 663 | ); 664 | } 665 | --------------------------------------------------------------------------------