├── .dockerignore ├── .env ├── .gitignore ├── Dockerfile ├── README.md ├── docker-compose.yaml ├── package-lock.json ├── package.json ├── public ├── favicon.ico ├── favicon.png ├── index.html ├── logo192.png ├── logo512.png ├── manifest.json └── pages │ ├── docs.md │ ├── education.md │ ├── experience.md │ ├── languages.md │ ├── overview.md │ ├── projects.md │ └── skills.md ├── src ├── app │ ├── components │ │ ├── MDContainer.tsx │ │ └── globals.d.ts │ ├── hooks │ │ └── usePageTracking.tsx │ ├── layout │ │ ├── App.tsx │ │ ├── AppButtons.tsx │ │ ├── AppTree.tsx │ │ ├── Footer.tsx │ │ └── Sidebar.tsx │ └── pages │ │ ├── Home.tsx │ │ ├── links.tsx │ │ └── pages.ts ├── index.tsx ├── logo.svg ├── react-app-env.d.ts ├── reportWebVitals.ts ├── setupTests.ts └── static │ ├── favicon.png │ └── logo.svg └── tsconfig.json /.dockerignore: -------------------------------------------------------------------------------- 1 | node_modules -------------------------------------------------------------------------------- /.env: -------------------------------------------------------------------------------- 1 | REACT_APP_NAME=Emre Dokuyucu 2 | REACT_APP_MEASUREMENT_ID=q1w2e3 -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # production 12 | /build 13 | 14 | # misc 15 | .DS_Store 16 | .env.local 17 | .env.development.local 18 | .env.test.local 19 | .env.production.local 20 | 21 | npm-debug.log* 22 | yarn-debug.log* 23 | yarn-error.log* 24 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM node:17-alpine 2 | 3 | WORKDIR /app 4 | 5 | COPY package.json . 6 | 7 | RUN npm install 8 | 9 | COPY . . 10 | 11 | EXPOSE 3000 12 | 13 | CMD ["npm", "start"] -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Personal portfolio website. -------------------------------------------------------------------------------- /docker-compose.yaml: -------------------------------------------------------------------------------- 1 | version: "3.8" 2 | services: 3 | app: 4 | build: . 5 | container_name: myapp 6 | ports: 7 | - '3000:3000' 8 | stdin_open: true 9 | tty: true 10 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react_portfolio", 3 | "version": "0.1.0", 4 | "homepage": "https://emredkyc.github.io", 5 | "private": true, 6 | "dependencies": { 7 | "@emotion/react": "^11.9.0", 8 | "@emotion/styled": "^11.8.1", 9 | "@mui/icons-material": "^5.8.3", 10 | "@mui/lab": "^5.0.0-alpha.85", 11 | "@mui/material": "^5.8.3", 12 | "@testing-library/jest-dom": "^5.16.4", 13 | "@testing-library/react": "^13.3.0", 14 | "@testing-library/user-event": "^13.5.0", 15 | "@types/jest": "^27.5.2", 16 | "@types/node": "^16.11.39", 17 | "@types/react-dom": "^18.0.5", 18 | "@types/react-syntax-highlighter": "^15.5.7", 19 | "react": "^18.1.0", 20 | "react-device-detect": "^2.2.2", 21 | "react-dom": "^18.1.0", 22 | "react-ga4": "^1.4.1", 23 | "react-icons": "^4.4.0", 24 | "react-markdown": "^8.0.3", 25 | "react-router-dom": "^6.3.0", 26 | "react-scripts": "5.0.1", 27 | "react-syntax-highlighter": "^15.5.0", 28 | "rehype-raw": "^6.1.1", 29 | "remark-breaks": "^3.0.3", 30 | "remark-gfm": "^1.0.0", 31 | "typescript": "^4.7.3", 32 | "web-vitals": "^2.1.4" 33 | }, 34 | "scripts": { 35 | "predeploy": "npm run build", 36 | "deploy": "gh-pages -b gh-pages -d build", 37 | "start": "react-scripts start", 38 | "build": "react-scripts build", 39 | "test": "react-scripts test", 40 | "eject": "react-scripts eject" 41 | }, 42 | "eslintConfig": { 43 | "extends": [ 44 | "react-app", 45 | "react-app/jest" 46 | ] 47 | }, 48 | "browserslist": { 49 | "production": [ 50 | ">0.2%", 51 | "not dead", 52 | "not op_mini all" 53 | ], 54 | "development": [ 55 | "last 1 chrome version", 56 | "last 1 firefox version", 57 | "last 1 safari version" 58 | ] 59 | }, 60 | "browser": { 61 | "fs": false, 62 | "path": false, 63 | "os": false 64 | }, 65 | "devDependencies": { 66 | "@types/react": "^18.2.48", 67 | "@types/webpack-env": "^1.17.0", 68 | "gh-pages": "^4.0.0" 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emredkyc/react_vscode_portfolio/db4982db9e8bde25b14a450e12be2067deca76ac/public/favicon.ico -------------------------------------------------------------------------------- /public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emredkyc/react_vscode_portfolio/db4982db9e8bde25b14a450e12be2067deca76ac/public/favicon.png -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | %REACT_APP_NAME% 19 | 20 | 21 | 22 |
23 | 24 | 25 | -------------------------------------------------------------------------------- /public/logo192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emredkyc/react_vscode_portfolio/db4982db9e8bde25b14a450e12be2067deca76ac/public/logo192.png -------------------------------------------------------------------------------- /public/logo512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/emredkyc/react_vscode_portfolio/db4982db9e8bde25b14a450e12be2067deca76ac/public/logo512.png -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | }, 10 | { 11 | "src": "logo192.png", 12 | "type": "image/png", 13 | "sizes": "192x192" 14 | }, 15 | { 16 | "src": "logo512.png", 17 | "type": "image/png", 18 | "sizes": "512x512" 19 | } 20 | ], 21 | "start_url": ".", 22 | "display": "standalone", 23 | "theme_color": "#000000", 24 | "background_color": "#ffffff" 25 | } 26 | -------------------------------------------------------------------------------- /public/pages/docs.md: -------------------------------------------------------------------------------- 1 | ::: info 2 | Following content is adapted from https://markdown-it.github.io/ 3 | ::: 4 | 5 | # h1 Heading 6 | ## h2 Heading 7 | ### h3 Heading 8 | #### h4 Heading 9 | ##### h5 Heading 10 | ###### h6 Heading 11 | 12 | ## Horizontal Rules 13 | 14 | --- 15 | 16 | ## Emphasis 17 | 18 | **This is bold text** 19 | 20 | __This is bold text__ 21 | 22 | *This is italic text* 23 | 24 | _This is italic text_ 25 | 26 | ~~Strikethrough~~ 27 | 28 | ## Blockquotes 29 | 30 | 31 | > Blockquotes can also be nested... 32 | >> ...by using additional greater-than signs right next to each other... 33 | > > > ...or with spaces between arrows. 34 | 35 | ## Lists 36 | 37 | Unordered 38 | 39 | + Create a list by starting a line with `+`, `-`, or `*` 40 | + Sub-lists are made by indenting 2 spaces: 41 | - Marker character change forces new list start: 42 | * Ac tristique libero volutpat at 43 | + Facilisis in pretium nisl aliquet 44 | - Nulla volutpat aliquam velit 45 | + Very easy! 46 | 47 | Ordered 48 | 49 | 1. Lorem ipsum dolor sit amet 50 | 2. Consectetur adipiscing elit 51 | 3. Integer molestie lorem at massa 52 | 53 | ## Code 54 | 55 | Inline `code` 56 | 57 | Indented code 58 | 59 | // Some comments 60 | line 1 of code 61 | line 2 of code 62 | line 3 of code 63 | 64 | Block code "fences" 65 | 66 | ``` 67 | Sample text here... 68 | Sample text here 69 | Sample text here 70 | Sample text here 71 | ``` 72 | 73 | Syntax highlighting 74 | 75 | ``` js 76 | var foo = function (bar) { 77 | return bar++; 78 | }; 79 | 80 | console.log(foo(5)); 81 | ``` 82 | 83 | ```python 84 | def hello_world(): 85 | print("Hello World!") 86 | ``` 87 | 88 | ## Tables 89 | 90 | | Option | Description | 91 | | ------ | ----------- | 92 | | data | path to data files to supply the data that will be passed into templates. | 93 | | engine | engine to be used for processing templates. Handlebars is the default. | 94 | | ext | extension to be used for dest files. | 95 | 96 | Right aligned columns 97 | 98 | | Option | Description | 99 | | ------:| -----------:| 100 | | data | path to data files to supply the data that will be passed into templates. | 101 | | engine | engine to be used for processing templates. Handlebars is the default. | 102 | | ext | extension to be used for dest files. | 103 | 104 | 105 | ## Links 106 | 107 | [link with title](https://github.com/emredkyc/react_portfolio "title text!") 108 | 109 | 110 | ## Alerts 111 | ::: warning 112 | Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. 113 | ::: 114 | 115 | ::: info 116 | Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. 117 | ::: 118 | 119 | ::: success 120 | Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. 121 | ::: 122 | 123 | ::: error 124 | Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum. 125 | ::: 126 | 127 | -------------------------------------------------------------------------------- /public/pages/education.md: -------------------------------------------------------------------------------- 1 | # 👨‍🎓 Education 2 | `2013-2017` [Suleyman Demirel University](https://international.sdu.edu.tr/) 3 | - B.Sc. : Computer Engineering 4 | - GPA : 3.1/4.0 5 | 6 | `2010-2013` [Niğde Ömer Halis Demir University](https://www.ohu.edu.tr/) 7 | - B.Sc. : Physics 8 | - GPA : 3.5/4.0 9 | -------------------------------------------------------------------------------- /public/pages/experience.md: -------------------------------------------------------------------------------- 1 | # 👨‍💻 Experience 2 | 3 | **Full-Stack Software Developer** @ [Verisoft](https://www.verisoftgroup.com) _(May 2019 - Dec 2023)_ 4 | 5 | Building Fintech businesses at Verisoft as part of a global team. More specifically, 6 | developing loyalty, payment system and card products to deliver delightful 7 | experiences to Verisoft's customers around the world. 8 | 9 | - Web applications 10 | - Backoffice development 11 | - User friendly interfaces, responsive design, user experience, performance oriented 12 | - RestAPI, WebAPI, XML services 13 | - Payment infrastructure improvements 14 | - Bank integrations 15 | - System optimization 16 | - Communication of applications 17 | 18 | - _**Technologies used:**_ C#, .NET,.NET Core, MSSQL, Oracle, Angular, React.js 19 | 20 |   21 | 22 | **Full-Stack Software Developer** @ [OKT-Trailer](https://www.okt-trailer.com) _(Agu 2017 - Sep 2018)_ 23 | 24 | Working as a full-stack developer in the team. 25 | Taking an important role in the ERP transformation project by being responsible for the 26 | finance, sales, vehicle tracking and delivery modules of the enterprise resource planning 27 | (ERP) structure. 28 | Demonstrating effective communication and project management skills during the 29 | analysis, testing and development process to ensure the successful outcome of the ERP 30 | transformation project. And actively working with business teams throughout this 31 | process. 32 | 33 | - _**Technologies used:**_ C#, ASP.NET MVC, MSSQL, Angular 34 | 35 | 36 |   37 | 38 | **Junior Front-End Developer** @ [Karton Medya](https://www.kartonmedya.com/) _(Feb 2016 - Jun 2017)_ 39 | 40 | During college, I worked on boosting knowledge in the real industry environment, mostly 41 | through a full-time job. 42 | Daily tasks required front-end development using various ReactJS and ASP.NET 43 | technologies and special attention to writing clean and extensible code required for 44 | numerous project customizations. 45 | 46 | - _**Technologies used:**_ React.js, Javascript, Typescript, Bootstrap, HTML5, CSS(SCSS,LESS) -------------------------------------------------------------------------------- /public/pages/languages.md: -------------------------------------------------------------------------------- 1 | # 💬 Languages 2 | **Turkish**: Native 3 | **English**: Professional working proficiency 4 | **German**: Beginner -------------------------------------------------------------------------------- /public/pages/overview.md: -------------------------------------------------------------------------------- 1 | # 📖 Overview 2 | 3 | ## Summary 4 | 5 | Senior Software Developer specialising in web application development. 6 | Experienced in all phases of the development cycle for dynamic web projects. Fluent in multiple programming languages including C# .NET and JavaScript/TypeScript. Strong background in both financial, audit, loyalty and software development. 7 | Reduced the gap between end users and developers, co-designing and building scalable solutions. 8 | 9 | 10 | ## Experience 11 | 12 | **Full-Stack Software Developer** @ [Verisoft](https://www.verisoftgroup.com) _(May 2019 - Dec 2023)_ 13 | 14 | Building Fintech businesses at Verisoft as part of a global team. More specifically, 15 | developing loyalty, payment system and card products to deliver delightful 16 | experiences to Verisoft's customers around the world. 17 | 18 | - Web applications 19 | - Backoffice development 20 | - User friendly interfaces, responsive design, user experience, performance oriented 21 | - RestAPI, WebAPI, XML services 22 | - Payment infrastructure improvements 23 | - Bank integrations 24 | - System optimization 25 | - Communication of applications 26 | 27 | - _**Technologies used:**_ C#, .NET, .NET Core, MSSQL, Oracle, Angular, React.js 28 | 29 |   30 | 31 | **Full-Stack Software Developer** @ [OKT-Trailer](https://www.okt-trailer.com) _(Agu 2017 - Sep 2018)_ 32 | 33 | Working as a full-stack developer in the team. 34 | Taking an important role in the ERP transformation project by being responsible for the 35 | finance, sales, vehicle tracking and delivery modules of the enterprise resource planning 36 | (ERP) structure. 37 | Demonstrating effective communication and project management skills during the 38 | analysis, testing and development process to ensure the successful outcome of the ERP 39 | transformation project. And actively working with business teams throughout this 40 | process. 41 | 42 | - _**Technologies used:**_ C#, ASP.NET MVC, MSSQL, Angular 43 | 44 | 45 |   46 | 47 | **Junior Front-End Developer** @ [Karton Medya](https://www.kartonmedya.com/) _(Feb 2016 - Jun 2017)_ 48 | 49 | During college, I worked on boosting knowledge in the real industry environment, mostly 50 | through a full-time job. 51 | Daily tasks required front-end development using various ReactJS and ASP.NET 52 | technologies and special attention to writing clean and extensible code required for 53 | numerous project customizations. 54 | 55 | - _**Technologies used:**_ React.js, Javascript, Typescript, Bootstrap, HTML5, CSS(SCSS,LESS) 56 | 57 | 58 | ## Education 59 | 60 | `2013-2017` [Suleyman Demirel University](https://w3.sdu.edu.tr/) 61 | - B.Sc.: Computer Engineering 62 | - GPA : 3.1/4.0 63 | 64 | `2010-2013` [Niğde Ömer Halis Demir University](https://www.ohu.edu.tr/) 65 | - B.Sc.: Physics 66 | - GPA : 3.5/4.0 67 | 68 | ## Skills 69 | 70 | ### General Tech Stacks 71 | - Architecture Design 72 | - Desktop App Development 73 | - Web Development (Frontend & Backend) 74 | 75 | ### Programming languages 76 | - C# .NET 77 | - JavaScript/TypeScript 78 | - Angular 79 | - React.js 80 | - Node.js 81 | - Express.js 82 | - Next.js 83 | - T-SQL 84 | 85 | ## Languages 86 | **Turkish**: Native 87 | **English**: Professional working proficiency 88 | **German**: Beginner -------------------------------------------------------------------------------- /public/pages/projects.md: -------------------------------------------------------------------------------- 1 | # 🧪 Projects 2 | 3 | ## [ClubTotal Card - Loyalty Card Application](https://totalenergies.com) 🔗 4 | Customer loyalty card developed for Total Energies Türkiye fuel stations is the application. Customers included in the application can make fuel purchases you can earn points, benefit from various campaigns and you can spend the points you earn at gas stations. 5 | 6 | Live: https://www.linkedin.com/in/burak-emre-dokuyucu/details/projects 🔗 7 | 8 | ## [Passport Card - Loyalty Card Application](https://tavhavalimanlari.com.tr) 🔗 9 | TAV Operations, one of the subsidiaries of TAV Airports Holding Services Inc. TAV Passport Card, which is a brand, is available to passengers at the airport. It is a membership program that offers privileges. Included in the membership program. Customers can choose the category of membership at airports operated by TAV. You can benefit from different services depending on your needs. 10 | 11 | Live: https://www.linkedin.com/in/burak-emre-dokuyucu/details/projects 🔗 12 | 13 | ## [MyGini - Loyalty and Offers Management](https://www.mygini.com) 🔗 14 | Create, personalize and communicate your offers in minutes and push them to your mobile app in real time. 15 | 16 | Live: https://www.linkedin.com/in/burak-emre-dokuyucu/details/projects 🔗 17 | 18 | ## [JetEMV - Card Personalization Application](https://www.verisoftgroup.com/emv-perso.html) 🔗 19 | Debit Card, Prepaid Card and Credit used in payment systems It is the personalization application of cards. The application can make Magnetic and EMV (Chip) personalization, It can work integrated with banks. 20 | 21 | Live: https://www.linkedin.com/in/burak-emre-dokuyucu/details/projects 🔗 22 | 23 | ## [event_platform](https://github.com/emredkyc/event_platform) 🔗 24 | Build an event organization web app like Eventbrite or Meetup with authentication, event management, search, filtering, categories, checkout, and payments using Next JS 14, Tailwind CSS, Shadcn, React Hook Form, Zod, Uploadthing, React-Datepicker, Mongoose, Clerk, and Stripe. 25 | 26 | Live: https://event-platform-dev.vercel.app 🔗 27 | 28 | ## [anime_world](https://github.com/emredkyc/anime_world) 🔗 29 | Curious about Server Actions in Next.js 14? How about infinite scrolling and Framer Motion animations with Next 14? This application will explain these concepts when building a server-side Next 14 Application. 30 | 31 | Live: https://anime-world-development.vercel.app 🔗 32 | 33 | ## [ai_prompt](https://github.com/emredkyc/ai_prompt) 🔗 34 | Next.js has recently become the official React framework as stated in the React documentation. In this project you will learn the most important Next.js concepts and how they fit into the React ecosystem. Finally, you will test your skills by building a modern full-stack Next 14 application. 35 | 36 | Live: https://promptify-dev.vercel.app 🔗 37 | 38 | ## [ai_summarizer](https://github.com/emredkyc/ai_summarizer) 🔗 39 | Summarize Articles with OpenAI GPT-4. Simplify your reading with Summize, an open-source article summarizer that transforms lengthy articles into clear and concise summaries. 40 | 41 | Live: https://ai-summarizer-dev.vercel.app 🔗 42 | 43 | ## [3d_portfolio](https://github.com/emredkyc/3d_portfolio) 🔗 44 | -Let's create a cool 3D website together! You will learn how to make a portfolio with fun interactive pieces like a floating island and a fox that moves when you type. This way you can show off your skills. 45 | 46 | Live: https://3d-portfolio-emredkyc.vercel.app 🔗 47 | 48 | ## [car_showcase](https://github.com/emredkyc/car_showcase) 🔗 49 | Build and Deploy a Modern Next.js 14 Application | React, Next JS 14, TypeScript, Tailwind CSS 50 | 51 | Live: https://carhub-dev.vercel.app 🔗 52 | 53 | ## [realestate](https://github.com/emredkyc/realestate) 🔗 54 | Build and Deploy a Real Estate React & Next.js Application 55 | 56 | Live: https://realtor-dev.vercel.app 🔗 57 | 58 | ## [exercise_app](https://github.com/emredkyc/exercise_app) 🔗 59 | This is a Exercise App that was built using Rapid API and is a PWA web app. It shows different exercises for gym freak as well as videos of each and every exercise with full details of the exercises with great explanation. 60 | 61 | Live: https://exercise-dev.vercel.app 🔗 62 | 63 | ## [price_tracker](https://github.com/emredkyc/price_tracker) 🔗 64 | Dive into web scraping and build a Next.js 14 eCommerce price tracker within one project that teaches you data scraping, cron jobs, sending emails, deployment, and more. 65 | 66 | Live: https://price-tracker-dev.vercel.app 🔗 67 | 68 | ## [react_vscode_portfolio](https://github.com/emredkyc/react_vscode_portfolio) 🔗 69 | Personal portfolio website. 70 | 71 | Live: https://portfolio-emredkyc.vercel.app 🔗 72 | 73 | ## [brainstorm](https://github.com/emredkyc/brainstorm) 🔗 74 | Learn to create modern websites with sleek parallax effects and bento box layouts. This project covers everything from stylish UI design to mobile-first principles while strengthening your React.js and Tailwind CSS skills. 75 | 76 | Live: https://brainstorm-dev.vercel.app 🔗 77 | 78 | ## [react_admin_dashboard](https://github.com/emredkyc/react_admin_dashboard) 🔗 79 | Build an admin dashboard with full authentication, a homepage displaying charts and activities, a comprehensive table for companies with CRUD and search, and a Kanban board with real-time synchronization. 80 | 81 | Live: https://react-dashboard-dev.vercel.app 🔗 -------------------------------------------------------------------------------- /public/pages/skills.md: -------------------------------------------------------------------------------- 1 | # 💻 Skills 2 | 3 | ## General Tech Stacks 4 | - Architecture Design 5 | - Desktop App Development 6 | - Web Development (Frontend & Backend) 7 | 8 | ## Programming languages 9 | - C# .NET 10 | - JavaScript/TypeScript 11 | - Angular 12 | - React.js 13 | - Next.js 14 | - Node.js 15 | - Express.js 16 | - T-SQL 17 | 18 | ## Databases 19 | - MSSQL 20 | - Oracle 21 | - Mongodb 22 | 23 | ## Cloud 24 | - Azure 25 | 26 | ## Vcs 27 | - Git 28 | - TFS (Team Foundation Server) 29 | - SVN (Subversion) -------------------------------------------------------------------------------- /src/app/components/MDContainer.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | Alert, 3 | Box, 4 | Chip, 5 | Container, 6 | Divider, 7 | Link, 8 | Paper, 9 | Table, 10 | TableBody, 11 | TableCell, 12 | TableContainer, 13 | TableFooter, 14 | TableHead, 15 | TableRow, 16 | Typography, 17 | } from "@mui/material"; 18 | import { ReactNode, useEffect, useState } from "react"; 19 | import ReactMarkdown from "react-markdown"; 20 | import { useLocation } from "react-router-dom"; 21 | import rehypeRaw from "rehype-raw"; 22 | import remarkBreaks from "remark-breaks"; 23 | import remarkGfm from "remark-gfm"; 24 | import { Prism as SyntaxHighlighter } from "react-syntax-highlighter"; 25 | import { 26 | materialLight, 27 | materialDark, 28 | } from "react-syntax-highlighter/dist/esm/styles/prism"; 29 | import { ReactElement } from "react-markdown/lib/react-markdown"; 30 | import { useTheme } from "@mui/material/styles"; 31 | import { tableCellClasses } from "@mui/material/TableCell"; 32 | import { styled } from "@mui/material/styles"; 33 | 34 | interface Props { 35 | path: string; 36 | } 37 | 38 | const StyledTableCell = styled(TableCell)(({ theme }) => ({ 39 | [`&.${tableCellClasses.head}`]: { 40 | backgroundColor: theme.palette.common.black, 41 | color: theme.palette.common.white, 42 | }, 43 | [`&.${tableCellClasses.body}`]: { 44 | fontSize: 14, 45 | }, 46 | })); 47 | 48 | const StyledTableRow = styled(TableRow)(({ theme }) => ({ 49 | "&:nth-of-type(odd)": { 50 | backgroundColor: theme.palette.action.hover, 51 | }, 52 | // hide last border 53 | "&:last-child td, &:last-child th": { 54 | border: 0, 55 | }, 56 | })); 57 | 58 | function MarkdownLink(props: any) { 59 | return ( 60 | 61 | {props.children} 62 | 63 | ); 64 | } 65 | 66 | function MarkdownTable(props: { children: ReactNode }) { 67 | return ( 68 | 69 | 70 | {props.children} 71 |
72 |
73 | ); 74 | } 75 | 76 | function MarkdownTableCell(props: any): ReactElement { 77 | if (props.style && props.style.textAlign === "right") { 78 | return ( 79 | 80 | {props.children} 81 | 82 | ); 83 | } else { 84 | return {props.children}; 85 | } 86 | } 87 | 88 | function MarkdownTableRow(props: { children: ReactNode }) { 89 | return {props.children}; 90 | } 91 | 92 | function MarkdownCode(props: any): ReactElement { 93 | const theme = useTheme(); 94 | const isDarkMode = theme.palette.mode === "dark"; 95 | if (props.inline) { 96 | return ; 97 | } else if (props.className) { 98 | const language = props.className.split("-")[1]; 99 | return ( 100 | 106 | {props.children.toString().trim()} 107 | 108 | ); 109 | } else { 110 | return ( 111 | 115 | {props.children} 116 | 117 | ); 118 | } 119 | } 120 | 121 | function MarkdownDivider() { 122 | const theme = useTheme(); 123 | const isDarkMode = theme.palette.mode === "dark"; 124 | return ( 125 | <> 126 | {isDarkMode ? ( 127 | 128 | ) : ( 129 | 130 | )} 131 | 132 | ); 133 | } 134 | 135 | function MarkdownH1(props: { children: ReactNode }) { 136 | return ( 137 | <> 138 | 149 | {props.children} 150 | 151 | 152 | 153 | ); 154 | } 155 | 156 | function MarkdownH2(props: { children: ReactNode }) { 157 | return ( 158 | <> 159 | 170 | {props.children} 171 | 172 | 173 | 174 | ); 175 | } 176 | 177 | function MarkdownBlockquote(props: any): ReactElement { 178 | return ( 179 | 180 |
{props.children}
181 |
182 | ); 183 | } 184 | 185 | // function MarkdownCheckbox(props: any) { 186 | // let checked = props.checked; 187 | // if (checked) { 188 | // return ( 189 | // } 192 | // label={props.label} 193 | // /> 194 | // ); 195 | // } else { 196 | // return ( 197 | // } label={props.label} /> 198 | // ); 199 | // } 200 | // } 201 | 202 | // function MarkdownImage(props: any) { 203 | // return {props.alt}; 204 | // } 205 | 206 | function MarkdownParagraph(props: any): ReactElement { 207 | const keyToCheck = "$$typeof"; 208 | const exists = props.children.some( 209 | (obj: { hasOwnProperty: (arg0: string) => any }) => 210 | obj.hasOwnProperty(keyToCheck) 211 | ); 212 | 213 | const isWarning = 214 | typeof props.children[0] === "string" && 215 | props.children[0].includes(":::") && 216 | props.children.slice(-1)[0].includes(":::"); 217 | 218 | if (isWarning) { 219 | const severity = props.children[0].split(" ")[1]; 220 | return ( 221 | 230 | {props.children.slice(2, -1)} 231 | 232 | ); 233 | } 234 | if (exists) { 235 | return ( 236 | 245 | {props.children} 246 | 247 | ); 248 | } 249 | return

{props.children}

; 250 | } 251 | 252 | export default function MDContainer({ path }: Props) { 253 | const [content, setContent] = useState(""); 254 | const { pathname } = useLocation(); 255 | useEffect(() => { 256 | fetch(path) 257 | .then((res) => res.text()) 258 | .then((text) => setContent(text)); 259 | }, [path]); 260 | 261 | useEffect(() => { 262 | let title = pathname.substring(1, pathname.length); 263 | title = title[0].toUpperCase() + title.substring(1); 264 | document.title = `${process.env.REACT_APP_NAME!} | ${title}`; 265 | }, [pathname]); 266 | 267 | return ( 268 | 269 | 293 | 294 | ); 295 | } 296 | -------------------------------------------------------------------------------- /src/app/components/globals.d.ts: -------------------------------------------------------------------------------- 1 | declare module '*.md'; 2 | -------------------------------------------------------------------------------- /src/app/hooks/usePageTracking.tsx: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from 'react'; 2 | import { useLocation } from 'react-router-dom'; 3 | import ReactGA from 'react-ga4'; 4 | 5 | const usePageTracking = () => { 6 | const location = useLocation(); 7 | const [initialized, setInitialized] = useState(false); 8 | 9 | useEffect(() => { 10 | if ( 11 | !window.location.href.includes('localhost') && 12 | process.env.REACT_APP_MEASUREMENT_ID 13 | ) { 14 | ReactGA.initialize(process.env.REACT_APP_MEASUREMENT_ID); 15 | setInitialized(true); 16 | } 17 | }, []); 18 | 19 | useEffect(() => { 20 | if (initialized) { 21 | ReactGA.send({ 22 | hitType: 'pageview', 23 | page: location.pathname + location.search, 24 | }); 25 | } 26 | }, [initialized, location]); 27 | }; 28 | 29 | export default usePageTracking; 30 | -------------------------------------------------------------------------------- /src/app/layout/App.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | Container, 3 | createTheme, 4 | CssBaseline, 5 | darkScrollbar, 6 | Grid, 7 | Stack, 8 | ThemeProvider, 9 | Typography, 10 | } from "@mui/material"; 11 | import { useEffect, useState } from "react"; 12 | import AppTree from "./AppTree"; 13 | import Footer from "./Footer"; 14 | import Sidebar from "./Sidebar"; 15 | import { Routes, Route, useNavigate, Navigate } from "react-router-dom"; 16 | import AppButtons from "./AppButtons"; 17 | import MDContainer from "../components/MDContainer"; 18 | import Home from "../pages/Home"; 19 | import { pages } from "../pages/pages"; 20 | import usePageTracking from "../hooks/usePageTracking"; 21 | import { isBrowser } from "react-device-detect"; 22 | 23 | interface Page { 24 | index: number; 25 | name: string; 26 | route: string; 27 | visible: boolean; 28 | } 29 | 30 | function initVisiblePageIndexs(pages: Page[]) { 31 | const tabs = []; 32 | for (let i = 0; i < pages.length; i++) { 33 | const page = pages[i]; 34 | if (page.visible) tabs.push(page.index); 35 | } 36 | return tabs; 37 | } 38 | 39 | export default function App() { 40 | const navigate = useNavigate(); 41 | const [expanded, setExpanded] = useState(isBrowser); 42 | const [selectedIndex, setSelectedIndex] = useState(-1); 43 | const [currentComponent, setCurrentComponent] = useState(""); 44 | const [visiblePageIndexs, setVisiblePageIndexs] = useState( 45 | initVisiblePageIndexs(pages) 46 | ); 47 | const [darkMode, setDarkMode] = useState(false); 48 | const [visiblePages, setVisiblePages] = useState( 49 | pages.filter((x) => x.visible) 50 | ); 51 | const paletteType = darkMode ? "dark" : "light"; 52 | usePageTracking(); 53 | const theme = createTheme({ 54 | palette: { 55 | mode: paletteType, 56 | background: { 57 | default: paletteType === "light" ? "#FFFFFF" : "#1e1e1e", 58 | }, 59 | }, 60 | components: { 61 | MuiCssBaseline: { 62 | styleOverrides: { 63 | body: paletteType === "dark" ? darkScrollbar() : null, 64 | }, 65 | }, 66 | MuiDivider: { 67 | styleOverrides: { 68 | root: { 69 | borderColor: "rgba(255, 255, 255, 0.12)", 70 | }, 71 | }, 72 | }, 73 | }, 74 | }); 75 | 76 | function handleThemeChange() { 77 | setDarkMode(!darkMode); 78 | localStorage.setItem("theme", darkMode ? "light" : "dark"); 79 | } 80 | 81 | useEffect(() => { 82 | const currentTheme = localStorage.getItem("theme"); 83 | if (!currentTheme) setDarkMode(true); 84 | else setDarkMode(currentTheme === "dark"); 85 | }, []); 86 | 87 | const deletedIndex = visiblePages.find( 88 | (x) => !visiblePageIndexs.includes(x.index) 89 | )?.index; 90 | 91 | useEffect(() => { 92 | const newPages = []; 93 | 94 | for (const index of visiblePageIndexs) { 95 | const page = pages.find((x) => x.index === index); 96 | if (page) newPages.push(page); 97 | } 98 | setVisiblePages(newPages); 99 | 100 | if (visiblePageIndexs.length === 0) { 101 | setSelectedIndex(-1); 102 | navigate("/"); 103 | } else if ( 104 | deletedIndex === selectedIndex && 105 | deletedIndex > Math.max(...visiblePageIndexs) 106 | ) { 107 | setSelectedIndex(Math.max(...visiblePageIndexs)); 108 | const page = pages.find( 109 | (x) => x.index === Math.max(...visiblePageIndexs) 110 | ); 111 | if (page) navigate(page.route); 112 | } else if ( 113 | deletedIndex === selectedIndex && 114 | deletedIndex < Math.max(...visiblePageIndexs) 115 | ) { 116 | setSelectedIndex(Math.min(...visiblePageIndexs)); 117 | const page = pages.find( 118 | (x) => x.index === Math.min(...visiblePageIndexs) 119 | ); 120 | if (page) navigate(page.route); 121 | } else { 122 | } 123 | }, [visiblePageIndexs, navigate, deletedIndex, selectedIndex]); 124 | 125 | return ( 126 | 127 | 128 | 133 | 134 | 135 | 136 | 143 | 144 | {expanded && ( 145 | 152 | 153 | 158 | EXPLORER 159 | 160 | x.visible)} 162 | selectedIndex={selectedIndex} 163 | setSelectedIndex={setSelectedIndex} 164 | currentComponent={currentComponent} 165 | setCurrentComponent={setCurrentComponent} 166 | visiblePageIndexs={visiblePageIndexs} 167 | setVisiblePageIndexs={setVisiblePageIndexs} 168 | /> 169 | 170 | 171 | )} 172 | 173 | 174 | 179 | 189 | 190 | 191 | 199 | 200 | } 203 | /> 204 | {pages.map(({ index, name, route }) => ( 205 | } 209 | /> 210 | ))} 211 | } 214 | /> 215 | } /> 216 | 217 | 218 | 219 | 220 | 221 |