├── .eslintrc.json ├── README.md ├── public └── assets │ ├── png │ ├── meta.png │ ├── zap.png │ ├── header.jpg │ ├── stats.png │ ├── pc-thumbnail.jpg │ ├── ss-thumbnail.png │ ├── atm-thumbnail.jpg │ └── display picture.png │ └── svg │ ├── link.svg │ ├── top.svg │ ├── credits.svg │ ├── projects.svg │ ├── home.svg │ └── uses.svg ├── postcss.config.js ├── .prettierrc ├── next.config.js ├── src ├── pages │ ├── uses.tsx │ ├── index.tsx │ ├── credits.tsx │ ├── projects.tsx │ ├── _app.tsx │ ├── _document.tsx │ └── api │ │ └── spotify.ts ├── styles │ └── globals.css ├── components │ ├── common │ │ ├── SectionWrapper.tsx │ │ ├── ParagraphWrapper.tsx │ │ ├── PageName.tsx │ │ ├── SectionHeading.tsx │ │ ├── PageSubheading.tsx │ │ ├── Tag.tsx │ │ ├── index.ts │ │ ├── ListWrapper.tsx │ │ ├── DivWBorderWrapper.tsx │ │ └── LinkWrapper.tsx │ ├── Layout.tsx │ ├── Footer.tsx │ ├── Menu.tsx │ └── Loader.tsx ├── containers │ ├── projects │ │ ├── index.tsx │ │ └── ProjectsList.tsx │ ├── uses │ │ ├── index.tsx │ │ ├── Applications.tsx │ │ ├── Equipments.tsx │ │ └── Extensions.tsx │ ├── credits │ │ ├── index.tsx │ │ └── CreditsList.tsx │ └── home │ │ ├── Skills.tsx │ │ ├── AboutMe.tsx │ │ ├── index.tsx │ │ ├── Social.tsx │ │ ├── Extras.tsx │ │ ├── Profile.tsx │ │ └── Experience.tsx └── utils │ └── index.ts ├── tailwind.config.js ├── .gitignore ├── tsconfig.json └── package.json /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Portfolio 2 | 3 | Coming soon. [Work in progress. ⚠️ ] 4 | -------------------------------------------------------------------------------- /public/assets/png/meta.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lostgirljourney/falgunisarkar/HEAD/public/assets/png/meta.png -------------------------------------------------------------------------------- /public/assets/png/zap.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lostgirljourney/falgunisarkar/HEAD/public/assets/png/zap.png -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /public/assets/png/header.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lostgirljourney/falgunisarkar/HEAD/public/assets/png/header.jpg -------------------------------------------------------------------------------- /public/assets/png/stats.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lostgirljourney/falgunisarkar/HEAD/public/assets/png/stats.png -------------------------------------------------------------------------------- /public/assets/png/pc-thumbnail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lostgirljourney/falgunisarkar/HEAD/public/assets/png/pc-thumbnail.jpg -------------------------------------------------------------------------------- /public/assets/png/ss-thumbnail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lostgirljourney/falgunisarkar/HEAD/public/assets/png/ss-thumbnail.png -------------------------------------------------------------------------------- /public/assets/png/atm-thumbnail.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lostgirljourney/falgunisarkar/HEAD/public/assets/png/atm-thumbnail.jpg -------------------------------------------------------------------------------- /public/assets/png/display picture.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lostgirljourney/falgunisarkar/HEAD/public/assets/png/display picture.png -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "semi": true, 3 | "trailingComma": "none", 4 | "singleQuote": true, 5 | "tabWidth": 2, 6 | "useTabs": true 7 | } 8 | -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const nextConfig = { 3 | reactStrictMode: true 4 | }; 5 | 6 | module.exports = nextConfig; 7 | -------------------------------------------------------------------------------- /src/pages/uses.tsx: -------------------------------------------------------------------------------- 1 | import { NextPage } from 'next'; 2 | import Uses from '@/containers/uses'; 3 | 4 | const UsesPage: NextPage = () => ; 5 | 6 | export default UsesPage; 7 | -------------------------------------------------------------------------------- /src/pages/index.tsx: -------------------------------------------------------------------------------- 1 | import { NextPage } from 'next'; 2 | import Home from '@/containers/home'; 3 | 4 | const HomePage: NextPage = () => ; 5 | 6 | export default HomePage; 7 | -------------------------------------------------------------------------------- /src/styles/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | html { 6 | width: 100%; 7 | height: 100%; 8 | scroll-behavior: smooth; 9 | } 10 | -------------------------------------------------------------------------------- /src/components/common/SectionWrapper.tsx: -------------------------------------------------------------------------------- 1 | export const SectionWrapper: React.FC<{ 2 | children: React.ReactNode; 3 | }> = ({ children }) =>
{children}
; 4 | -------------------------------------------------------------------------------- /src/pages/credits.tsx: -------------------------------------------------------------------------------- 1 | import { NextPage } from 'next'; 2 | import Credits from '@/containers/credits'; 3 | 4 | const CreditsPage: NextPage = () => ; 5 | 6 | export default CreditsPage; 7 | -------------------------------------------------------------------------------- /src/pages/projects.tsx: -------------------------------------------------------------------------------- 1 | import { NextPage } from 'next'; 2 | import Projects from '@/containers/projects'; 3 | 4 | const ProjectsPage: NextPage = () => ; 5 | 6 | export default ProjectsPage; 7 | -------------------------------------------------------------------------------- /src/components/common/ParagraphWrapper.tsx: -------------------------------------------------------------------------------- 1 | export const ParagraphWrapper: React.FC<{ 2 | children: React.ReactNode; 3 | }> = ({ children }) => ( 4 |
{children}
5 | ); 6 | -------------------------------------------------------------------------------- /public/assets/svg/link.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /public/assets/svg/top.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/components/common/PageName.tsx: -------------------------------------------------------------------------------- 1 | export const PageName: React.FC<{ 2 | label: string; 3 | }> = ({ label }) => ( 4 |

8 | {label} 9 |

10 | ); 11 | -------------------------------------------------------------------------------- /src/components/common/SectionHeading.tsx: -------------------------------------------------------------------------------- 1 | export const SectionHeading: React.FC<{ 2 | heading: string; 3 | fontColor: string; 4 | }> = ({ heading, fontColor }) => ( 5 |

6 | {heading} 7 |

8 | ); 9 | -------------------------------------------------------------------------------- /public/assets/svg/credits.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('tailwindcss').Config} */ 2 | module.exports = { 3 | content: ['./src/**/*.{js,ts,jsx,tsx,mdx}'], 4 | theme: { 5 | extend: { 6 | colors: { 7 | black: '#080808' 8 | }, 9 | height: { 10 | 50: '200px' 11 | } 12 | } 13 | }, 14 | plugins: [] 15 | }; 16 | -------------------------------------------------------------------------------- /src/components/common/PageSubheading.tsx: -------------------------------------------------------------------------------- 1 | export const PageSubheading: React.FC<{ 2 | description: string; 3 | }> = ({ description }) => ( 4 |

10 | {description} 11 |

12 | ); 13 | -------------------------------------------------------------------------------- /src/components/common/Tag.tsx: -------------------------------------------------------------------------------- 1 | export const Tag: React.FC<{ 2 | label: string; 3 | tagProps?: any; 4 | }> = ({ label, tagProps }) => ( 5 |

10 | {label} 11 |

12 | ); 13 | -------------------------------------------------------------------------------- /src/components/common/index.ts: -------------------------------------------------------------------------------- 1 | export * from './DivWBorderWrapper'; 2 | export * from './LinkWrapper'; 3 | export * from './ListWrapper'; 4 | export * from './PageName'; 5 | export * from './PageSubheading'; 6 | export * from './ParagraphWrapper'; 7 | export * from './SectionHeading'; 8 | export * from './SectionWrapper'; 9 | export * from './Tag'; 10 | -------------------------------------------------------------------------------- /public/assets/svg/projects.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/components/common/ListWrapper.tsx: -------------------------------------------------------------------------------- 1 | export const ListWrapper: React.FC<{ 2 | children: React.ReactNode; 3 | liProps?: React.HTMLProps; 4 | }> = ({ children, liProps }) => { 5 | let cls = 'space-y-1 list-disc w-full list-outside pl-6 text-sm font-normal'; 6 | 7 | if (liProps) { 8 | cls = `${cls} ${liProps.className}`; 9 | } 10 | 11 | return
    {children}
; 12 | }; 13 | -------------------------------------------------------------------------------- /src/containers/projects/index.tsx: -------------------------------------------------------------------------------- 1 | import { PageName } from '@/components/common'; 2 | import Layout from '@/components/Layout'; 3 | import ProjectsList from './ProjectsList'; 4 | 5 | const Projects = () => ( 6 | 7 |
8 | 9 |
10 | 11 |
12 | ); 13 | 14 | export default Projects; 15 | -------------------------------------------------------------------------------- /public/assets/svg/home.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/components/common/DivWBorderWrapper.tsx: -------------------------------------------------------------------------------- 1 | export const DivWBorderWrapper: React.FC<{ 2 | children: React.ReactNode; 3 | }> = ({ children }) => { 4 | return ( 5 |
13 | {children} 14 |
15 | ); 16 | }; 17 | -------------------------------------------------------------------------------- /public/assets/svg/uses.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /src/containers/uses/index.tsx: -------------------------------------------------------------------------------- 1 | import { PageName } from '@/components/common'; 2 | import Layout from '@/components/Layout'; 3 | import Applications from './Applications'; 4 | import Equipments from './Equipments'; 5 | import Extensions from './Extensions'; 6 | 7 | const Uses = () => ( 8 | 9 |
10 | 11 |
12 | 13 | 14 | 15 |
16 | ); 17 | 18 | export default Uses; 19 | -------------------------------------------------------------------------------- /src/utils/index.ts: -------------------------------------------------------------------------------- 1 | import { ClassValue, clsx } from 'clsx'; 2 | import { twMerge } from 'tailwind-merge'; 3 | 4 | export function cn(...inputs: ClassValue[]) { 5 | return twMerge(clsx(inputs)); 6 | } 7 | 8 | export interface SpotifyData { 9 | isPlaying: boolean; 10 | title?: string; 11 | songUrl?: string; 12 | } 13 | 14 | export const colorMap = { 15 | 'full-time': '#F6D860', 16 | internship: '#FFE6BC', 17 | 'hackathon winner': '#FF78C4', 18 | 'group project': '#E1AEFF', 19 | 'solo project': '#99DBF5' 20 | }; 21 | -------------------------------------------------------------------------------- /src/containers/credits/index.tsx: -------------------------------------------------------------------------------- 1 | import Layout from '@/components/Layout'; 2 | import { PageName, PageSubheading } from '@/components/common'; 3 | import CreditsList from './CreditsList'; 4 | 5 | const Credits = () => { 6 | return ( 7 | 8 |
9 | 10 | 11 |
12 | 13 |
14 | ); 15 | }; 16 | 17 | export default Credits; 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | 27 | # local env files 28 | .env*.local 29 | .env 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "lib": ["dom", "dom.iterable", "esnext"], 5 | "allowJs": true, 6 | "skipLibCheck": true, 7 | "strict": true, 8 | "forceConsistentCasingInFileNames": true, 9 | "noEmit": true, 10 | "esModuleInterop": true, 11 | "module": "esnext", 12 | "moduleResolution": "node", 13 | "resolveJsonModule": true, 14 | "isolatedModules": true, 15 | "jsx": "preserve", 16 | "incremental": true, 17 | "paths": { 18 | "@/*": ["./src/*"] 19 | } 20 | }, 21 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"], 22 | "exclude": ["node_modules"] 23 | } 24 | -------------------------------------------------------------------------------- /src/containers/home/Skills.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | ListWrapper, 3 | SectionHeading, 4 | SectionWrapper 5 | } from '@/components/common'; 6 | 7 | const skills = [ 8 | 'JavaScript | TypeScript', 9 | 'React.js | Next.js', 10 | 'React-Redux | React Query', 11 | 'TailwindCSS | Chakra-UI', 12 | 'Vite.js | Node.js' 13 | ]; 14 | 15 | const Skills = () => { 16 | return ( 17 | 18 | 19 | 20 | {skills.map((skill, index) => ( 21 |
  • 22 | {skill} 23 |
  • 24 | ))} 25 |
    26 |
    27 | ); 28 | }; 29 | 30 | export default Skills; 31 | -------------------------------------------------------------------------------- /src/containers/home/AboutMe.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | ParagraphWrapper, 3 | SectionHeading, 4 | SectionWrapper 5 | } from '@/components/common'; 6 | 7 | const AboutMe = () => ( 8 | 9 | 10 | 11 |

    12 | Passionate about crafting exceptional user experiences, I strive to 13 | create pixel-perfect interfaces that seamlessly blend design and 14 | engineering principles. 15 |

    16 |
    17 |

    18 | A lifelong learner, always seeking to expand my horizons. Thus, 19 | continuously exploring my capabilities to build efficient and scalable 20 | web applications. 21 |

    22 |
    23 |
    24 | ); 25 | 26 | export default AboutMe; 27 | -------------------------------------------------------------------------------- /src/containers/home/index.tsx: -------------------------------------------------------------------------------- 1 | import { useQuery } from '@tanstack/react-query'; 2 | import { SpotifyData } from '@/utils'; 3 | import Layout from '@/components/Layout'; 4 | import Profile from './Profile'; 5 | import AboutMe from './AboutMe'; 6 | import Social from './Social'; 7 | import Extras from './Extras'; 8 | import Experience from './Experience'; 9 | import Skills from './Skills'; 10 | 11 | const Home = () => { 12 | const { data, isError } = useQuery({ 13 | queryKey: ['now-playing'], 14 | queryFn: () => fetch('/api/spotify').then((r) => r.json()), 15 | refetchInterval: 1000 * 60 * 3, 16 | refetchOnWindowFocus: true 17 | }); 18 | 19 | return ( 20 | 21 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | ); 32 | }; 33 | 34 | export default Home; 35 | -------------------------------------------------------------------------------- /src/components/common/LinkWrapper.tsx: -------------------------------------------------------------------------------- 1 | import Image from 'next/image'; 2 | import Link, { LinkProps } from 'next/link'; 3 | import { cn } from '@/utils'; 4 | 5 | interface LinkWrapperProps extends LinkProps { 6 | href: string; 7 | children: React.ReactNode; 8 | linkIcon?: boolean; 9 | className?: string; 10 | } 11 | 12 | export const LinkWrapper: React.FC = ({ 13 | href, 14 | children, 15 | linkIcon, 16 | className 17 | }) => { 18 | return ( 19 | 32 |
    {children}
    33 | {linkIcon && ( 34 | link 41 | )} 42 | 43 | ); 44 | }; 45 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "falgunisarkar", 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 | "@tanstack/react-query": "^5.29.2", 13 | "@tanstack/react-query-devtools": "^5.29.2", 14 | "@types/node": "^20.12.7", 15 | "@types/react": "^18.2.79", 16 | "@types/react-dom": "^18.2.25", 17 | "@vercel/analytics": "^1.2.2", 18 | "@vercel/speed-insights": "^1.0.10", 19 | "animejs": "^3.2.2", 20 | "autoprefixer": "^10.4.19", 21 | "axios": "^1.12.0", 22 | "clsx": "^2.1.0", 23 | "eslint": "^9.1.0", 24 | "eslint-config-next": "^14.2.2", 25 | "next": "^14.2.32", 26 | "nextjs-progressbar": "^0.0.16", 27 | "postcss": "^8.4.38", 28 | "react": "^18.2.0", 29 | "react-dom": "^18.2.0", 30 | "tailwind-merge": "^2.3.0", 31 | "tailwindcss": "^3.4.3", 32 | "typescript": "^5.4.5" 33 | }, 34 | "devDependencies": { 35 | "@tanstack/eslint-plugin-query": "^5.28.11", 36 | "@types/animejs": "^3.1.12" 37 | }, 38 | "repository": { 39 | "url": "https://github.com/lostgirljourney/falgunisarkar.git" 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/containers/uses/Applications.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | LinkWrapper, 3 | ListWrapper, 4 | SectionHeading, 5 | SectionWrapper 6 | } from '@/components/common'; 7 | 8 | const applications = [ 9 | <> 10 | Figma for designing 11 | my projects. 12 | , 13 | <> 14 | 15 | Visual Studio Code 16 | {' '} 17 | for development. 18 | , 19 | <> 20 | Discord to hangout w/ 21 | community friends. 22 | , 23 | <> 24 | Spotify for 25 | listening to music (I am a melophile). 26 | , 27 | <> 28 | Brave (chromium 29 | browser) for browsing on internet. 30 | 31 | ]; 32 | 33 | const Applications = () => { 34 | return ( 35 | 36 | 37 | 38 | {applications.map((application, index) => ( 39 |
  • 40 | {application} 41 |
  • 42 | ))} 43 |
    44 |
    45 | ); 46 | }; 47 | 48 | export default Applications; 49 | -------------------------------------------------------------------------------- /src/containers/home/Social.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | LinkWrapper, 3 | ListWrapper, 4 | SectionHeading, 5 | SectionWrapper 6 | } from '@/components/common'; 7 | 8 | const socials = [ 9 | <> 10 | Shitposting at{' '} 11 | 12 | twitter.com/isshefalguni 13 | 14 | . 15 | , 16 | <> 17 | Mail me at{' '} 18 | 19 | falgunisarkar526@gmail.com 20 | 21 | . 22 | , 23 | <> 24 | Check my codes at{' '} 25 | 26 | github.com/lostgirljourney 27 | 28 | . 29 | , 30 | <> 31 | Prefer networking at{' '} 32 | 33 | linkedin.com/in/falgunisarkar 34 | 35 | . 36 | , 37 | <> 38 | Not so active (but oke) at{' '} 39 | 40 | instagram.com/lostgirljourney_ 41 | 42 | . 43 | 44 | ]; 45 | 46 | const Social = () => ( 47 | 48 | 49 | 50 | {socials.map((social, index) => ( 51 |
  • {social}
  • 52 | ))} 53 |
    54 |
    55 | ); 56 | 57 | export default Social; 58 | -------------------------------------------------------------------------------- /src/containers/home/Extras.tsx: -------------------------------------------------------------------------------- 1 | import { useQuery } from '@tanstack/react-query'; 2 | import { SpotifyData } from '@/utils'; 3 | import { 4 | SectionWrapper, 5 | SectionHeading, 6 | ListWrapper, 7 | LinkWrapper 8 | } from '@/components/common'; 9 | 10 | const Extras = () => { 11 | const { data, isLoading } = useQuery({ 12 | queryKey: ['now-playing'], 13 | queryFn: () => fetch('/api/spotify').then((r) => r.json()), 14 | refetchInterval: 1000 * 60 * 3, 15 | refetchOnWindowFocus: true 16 | }); 17 | let spotifyLabel = <>; 18 | 19 | if (isLoading) { 20 | spotifyLabel = <>loading spotify data..; 21 | } else if (data?.isPlaying) { 22 | spotifyLabel = ( 23 | <> 24 | Currently listening to{' '} 25 | {{data.title}} on 26 | Spotify 27 | 28 | ); 29 | } else { 30 | spotifyLabel = <>Not listening to anything on Spotify; 31 | } 32 | 33 | const extras = [ 34 | spotifyLabel, 35 | <> 36 | 37 | Resume 38 | 39 | 40 | ]; 41 | 42 | return ( 43 | 44 | 45 | 46 | {extras.map((extra, index) => ( 47 |
  • {extra}.
  • 48 | ))} 49 |
    50 |
    51 | ); 52 | }; 53 | export default Extras; 54 | -------------------------------------------------------------------------------- /src/components/Layout.tsx: -------------------------------------------------------------------------------- 1 | import Head from 'next/head'; 2 | import Image from 'next/image'; 3 | import Footer from './Footer'; 4 | import Menus from './Menu'; 5 | import { Outfit } from 'next/font/google'; 6 | 7 | const outfit = Outfit({ subsets: ['latin'] }); 8 | 9 | const Layout: React.FC<{ 10 | children: React.ReactNode; 11 | title: string; 12 | sectionProps?: React.DetailedHTMLProps< 13 | React.HTMLAttributes, 14 | HTMLElement 15 | >; 16 | isHome?: boolean; 17 | }> = ({ children, title, sectionProps, isHome }) => ( 18 | <> 19 | 20 | {`${title} | Falguni Sarkar`} 21 | 22 |
    26 |
    27 | header image.classList.remove('opacity-0')} 36 | /> 37 |
    41 | {children} 42 |
    43 |
    44 |
    45 |
    46 | 47 | 48 | ); 49 | 50 | export default Layout; 51 | -------------------------------------------------------------------------------- /src/containers/uses/Equipments.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | LinkWrapper, 3 | ListWrapper, 4 | SectionHeading, 5 | SectionWrapper 6 | } from '@/components/common'; 7 | 8 | const equipments = [ 9 | 10 | MacBook Air 13″ M2 chip 11 | , 12 | 16 | Portronics Toad 24 17 | , 18 | 22 | Zebronics War Gaming Keyboard 23 | , 24 | 28 | Galaxy A34 5G 29 | , 30 | 34 | Galaxy Watch4 Classic Bluetooth 35 | , 36 | 40 | Nothing Ear (2) 41 | 42 | ]; 43 | 44 | const Equipments = () => { 45 | return ( 46 | 47 | 48 | 49 | {equipments.map((application, index) => ( 50 |
  • 51 | {application} 52 |
  • 53 | ))} 54 |
    55 |
    56 | ); 57 | }; 58 | 59 | export default Equipments; 60 | -------------------------------------------------------------------------------- /src/pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import { QueryClient, QueryClientProvider } from '@tanstack/react-query'; 2 | import { ReactQueryDevtools } from '@tanstack/react-query-devtools'; 3 | import { SpeedInsights } from '@vercel/speed-insights/next'; 4 | import { Analytics } from '@vercel/analytics/react'; 5 | import React, { useEffect, useState } from 'react'; 6 | import NextNProgress from 'nextjs-progressbar'; 7 | import type { AppProps } from 'next/app'; 8 | import Loader from '@/components/Loader'; 9 | import '@/styles/globals.css'; 10 | 11 | const Splash: React.FC<{ children: any }> = ({ children }) => { 12 | const [loading, setLoading] = useState(true); 13 | useEffect(() => { 14 | const timeout = setTimeout(() => { 15 | setLoading(false); 16 | }, 1700); 17 | return () => clearTimeout(timeout); 18 | }, []); 19 | 20 | return loading ? : children; 21 | }; 22 | 23 | const App = ({ Component, pageProps }: AppProps) => { 24 | const queryClient = new QueryClient(); 25 | const [randomColor, setRandomColor] = useState('#fff'); 26 | 27 | useEffect(() => { 28 | const colors = [ 29 | '#1586EC', 30 | '#1EAEC9', 31 | '#FB3B08', 32 | '#A847B5', 33 | '#CE2B60', 34 | '#F73E03', 35 | '#F0EC03' 36 | ]; 37 | setRandomColor(colors[Math.floor(Math.random() * colors.length)]); 38 | }, []); 39 | 40 | return ( 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | ); 51 | }; 52 | 53 | export default App; 54 | -------------------------------------------------------------------------------- /src/containers/home/Profile.tsx: -------------------------------------------------------------------------------- 1 | import Image from 'next/image'; 2 | import { PageName, PageSubheading } from '../../components/common'; 3 | 4 | const Profile: React.FC<{ 5 | src: string; 6 | isPlaying: boolean; 7 | }> = ({ src, isPlaying }) => ( 8 |
    9 |
    10 | display picture image.classList.remove('opacity-0')} 18 | /> 19 | {isPlaying && ( 20 | <> 21 |
    22 | status image.classList.remove('opacity-0')} 30 | /> 31 |
    32 |

    33 | this mode is always on! 🎶 34 |

    35 | 36 | )} 37 |
    38 |
    39 | 40 | 41 |
    42 |
    43 | ); 44 | 45 | export default Profile; 46 | -------------------------------------------------------------------------------- /src/components/Footer.tsx: -------------------------------------------------------------------------------- 1 | import { useQuery } from '@tanstack/react-query'; 2 | import { SpotifyData } from '@/utils'; 3 | import { LinkWrapper } from './common'; 4 | 5 | const Footer: React.FC<{ 6 | isHome?: boolean; 7 | }> = ({ isHome }) => { 8 | const { data: spotifyData, isLoading } = useQuery({ 9 | queryKey: ['now-playing'], 10 | queryFn: () => fetch('/api/spotify').then((r) => r.json()), 11 | refetchInterval: 1000 * 60 * 3, 12 | refetchOnWindowFocus: true 13 | }); 14 | let spotifyLabel = <>; 15 | 16 | if (!isHome) { 17 | if (isLoading) { 18 | spotifyLabel = <> | loading spotify data..; 19 | } else if (spotifyData?.isPlaying) { 20 | spotifyLabel = ( 21 | <> 22 | {' '} 23 | | now playing{' '} 24 | { 25 | 26 | {spotifyData.title?.toLowerCase()} 27 | 28 | }{' '} 29 | on spotify 30 | 31 | ); 32 | } 33 | } 34 | 35 | const { data: ghData } = useQuery({ 36 | queryKey: ['github'], 37 | queryFn: () => 38 | fetch('https://api.github.com/repos/lostgirljourney/falgunisarkar') 39 | .then((res) => res.json()) 40 | .then((data) => data), 41 | refetchInterval: 1000 * 60 * 60 42 | }); 43 | 44 | return ( 45 |
    46 | Artfully designed with{' '} 47 | Figma, coded with{' '} 48 | Next.js, and{' '} 49 | TailwindCSS |{' '} 50 | {ghData?.stargazers_count || 0} stars • {ghData?.forks_count || 0} forks 51 | on github 52 | {spotifyLabel} 53 |
    54 | ); 55 | }; 56 | 57 | export default Footer; 58 | -------------------------------------------------------------------------------- /src/pages/_document.tsx: -------------------------------------------------------------------------------- 1 | import { Html, Head, Main, NextScript } from 'next/document'; 2 | 3 | export default function Document() { 4 | return ( 5 | 6 | 7 | 8 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 26 | 30 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 44 | 45 | 49 | 53 | 54 | 55 |
    56 | 57 | 58 | 59 | ); 60 | } 61 | -------------------------------------------------------------------------------- /src/pages/api/spotify.ts: -------------------------------------------------------------------------------- 1 | import axios from 'axios'; 2 | import { NextApiRequest, NextApiResponse } from 'next'; 3 | import querystring from 'querystring'; 4 | 5 | const { 6 | SPOTIFY_CLIENT_ID: client_id, 7 | SPOTIFY_CLIENT_SECRET: client_secret, 8 | SPOTIFY_REFRESH_TOKEN: refresh_token 9 | } = process.env; 10 | 11 | const token = Buffer.from(`${client_id}:${client_secret}`).toString('base64'); 12 | const NOW_PLAYING_ENDPOINT = `https://api.spotify.com/v1/me/player/currently-playing`; 13 | const TOKEN_ENDPOINT = `https://accounts.spotify.com/api/token`; 14 | 15 | interface SpotifyData { 16 | is_playing: boolean; 17 | item: { 18 | name: string; 19 | album: { 20 | name: string; 21 | artists: Array<{ name: string }>; 22 | images: [{ url: string }]; 23 | }; 24 | external_urls: { 25 | spotify: string; 26 | }; 27 | }; 28 | currently_playing_type: string; 29 | } 30 | 31 | const getAccessToken = async () => { 32 | const res = await axios.post<{ access_token: string }>( 33 | TOKEN_ENDPOINT, 34 | querystring.stringify({ 35 | grant_type: 'refresh_token', 36 | refresh_token 37 | }), 38 | { 39 | headers: { 40 | Authorization: `Basic ${token}`, 41 | 'Content-Type': 'application/x-www-form-urlencoded' 42 | } 43 | } 44 | ); 45 | 46 | return res.data.access_token; 47 | }; 48 | 49 | export const getNowPlaying = async () => { 50 | const access_token = await getAccessToken(); 51 | 52 | return axios.get(NOW_PLAYING_ENDPOINT, { 53 | headers: { 54 | Authorization: `Bearer ${access_token}` 55 | } 56 | }); 57 | }; 58 | 59 | export default async function spotify( 60 | req: NextApiRequest, 61 | res: NextApiResponse 62 | ) { 63 | if (req.method === 'GET') { 64 | const response = await getNowPlaying(); 65 | 66 | if ( 67 | response.status === 204 || 68 | response.status > 400 || 69 | response.data.currently_playing_type !== 'track' 70 | ) { 71 | return res.status(200).json({ isPlaying: false }); 72 | } 73 | 74 | const data = { 75 | isPlaying: response.data.is_playing, 76 | title: response.data.item.name, 77 | songUrl: response.data.item.external_urls.spotify 78 | }; 79 | 80 | return res.status(200).json(data); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/components/Menu.tsx: -------------------------------------------------------------------------------- 1 | import { useState } from 'react'; 2 | import Image from 'next/image'; 3 | import Link from 'next/link'; 4 | 5 | const MenuItem: React.FC<{ 6 | src: string; 7 | name: string; 8 | color: string; 9 | href?: string; 10 | menuProps?: any; 11 | }> = ({ src, name, color, href, menuProps }) => { 12 | const commonClasses = 13 | 'flex justify-center items-center rounded-full w-11 h-11'; 14 | 15 | return ( 16 | <> 17 | {href ? ( 18 | 25 | {name} 26 | 27 | ) : ( 28 |

    35 | {name} 36 |

    37 | )} 38 | 39 | ); 40 | }; 41 | 42 | const menuItems = [ 43 | { 44 | href: '/', 45 | src: '/home.svg', 46 | name: 'home', 47 | color: '#FFFAE7' 48 | }, 49 | { 50 | href: '/projects', 51 | src: '/projects.svg', 52 | name: 'projects', 53 | color: '#F2C0FF' 54 | }, 55 | { 56 | href: '/uses', 57 | src: '/uses.svg', 58 | name: 'uses', 59 | color: '#F5F0BB' 60 | }, 61 | { 62 | href: '/credits', 63 | src: '/credits.svg', 64 | name: 'credits', 65 | color: '#C4DFAA' 66 | }, 67 | { 68 | menuProps: { 69 | onClick: () => window.scrollTo({ top: 0, behavior: 'smooth' }) 70 | }, 71 | src: '/top.svg', 72 | name: 'go to top', 73 | color: '#FCC5C0' 74 | } 75 | ]; 76 | 77 | const Menus = () => ( 78 |
    82 | {menuItems.map(({ color, href, name, src, menuProps }) => 83 | href ? ( 84 | 91 | ) : ( 92 | 99 | ) 100 | )} 101 |
    102 | ); 103 | 104 | export default Menus; 105 | -------------------------------------------------------------------------------- /src/containers/uses/Extensions.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | SectionWrapper, 3 | SectionHeading, 4 | DivWBorderWrapper, 5 | LinkWrapper, 6 | ParagraphWrapper 7 | } from '@/components/common'; 8 | 9 | const extensions = [ 10 | { 11 | name: 'Console Ninja', 12 | desc: 'JavaScript console.log output and runtime errors right next to your code.', 13 | link: 'https://marketplace.visualstudio.com/items?itemName=WallabyJs.console-ninja' 14 | }, 15 | { 16 | name: 'ES7+ React/Redux/React-Native snippets', 17 | desc: 'Extensions for React, React-Native and Redux in JS/TS with ES7+ syntax. Customizable. Built-in integration with prettier.', 18 | link: 'https://marketplace.visualstudio.com/items?itemName=dsznajder.es7-react-js-snippets' 19 | }, 20 | { 21 | name: 'Figma for VS Code', 22 | desc: 'Bring Figma into the text editor. Inspect designs, receive notifications, and get code suggestions.', 23 | link: 'https://marketplace.visualstudio.com/items?itemName=figma.figma-vscode-extension' 24 | }, 25 | { 26 | name: 'GitLens — Git supercharged', 27 | desc: 'Supercharge Git and unlock untapped knowledge within your repository to better understand, write, and review code. Focus, collaborate, accelerate.', 28 | link: 'https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens' 29 | }, 30 | { 31 | name: 'JavaScript and TypeScript Nightly', 32 | desc: "Enables typescript@next to power VS Code's built-in JavaScript and TypeScript support", 33 | link: 'https://marketplace.visualstudio.com/items?itemName=ms-vscode.vscode-typescript-next' 34 | }, 35 | { 36 | name: 'Tailwind CSS IntelliSense', 37 | desc: 'Intelligent Tailwind CSS tooling for VS Code', 38 | link: 'https://marketplace.visualstudio.com/items?itemName=bradlc.vscode-tailwindcss' 39 | }, 40 | { 41 | name: 'vscode-pets', 42 | desc: 'Pets for your VS Code', 43 | link: 'https://marketplace.visualstudio.com/items?itemName=tonybaloney.vscode-pets' 44 | } 45 | ]; 46 | 47 | const Extensions = () => ( 48 | 49 | 53 | {extensions.map(({ name, desc, link }, index) => ( 54 | 55 |
    56 |
    57 |

    58 | {name} 59 |

    60 | 61 | website 62 | 63 |
    64 | 65 |

    {desc}

    66 |
    67 |
    68 |
    69 | ))} 70 |
    71 | ); 72 | 73 | export default Extensions; 74 | -------------------------------------------------------------------------------- /src/containers/projects/ProjectsList.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | DivWBorderWrapper, 3 | LinkWrapper, 4 | ListWrapper, 5 | SectionHeading, 6 | SectionWrapper, 7 | Tag 8 | } from '@/components/common'; 9 | import Image from 'next/image'; 10 | import { colorMap } from '@/utils'; 11 | 12 | const projects = [ 13 | { 14 | tags: ['hackathon winner', 'group project'], 15 | tagBgColors: [colorMap['hackathon winner'], colorMap['group project']], 16 | code: 'https://github.com/BlankCoders/awesome-todo-maintainer-extension', 17 | preview: 'https://devpost.com/software/awesome-todo-maintainer', 18 | title: 'Awesome Todo Maintainer', 19 | desc: ( 20 | 21 | {[ 22 | 'Awesome Todo Maintainer Extension for Awesome Hackers; powered by NotionAPI.', 23 | 'Manage your Notion TO-DOs Database right from VSCode.', 24 | 'In this project, I worked on the extension UI and functionality part.', 25 | 'Tech stacks involved are JavaScript, Node.js, Express.js, Visual Studio Code.' 26 | ].map((item, index) => ( 27 |
  • {item}
  • 28 | ))} 29 |
    30 | ), 31 | thumbnail: 'atm-thumbnail.jpg' 32 | }, 33 | { 34 | tags: ['hackathon winner', 'group project'], 35 | tagBgColors: [colorMap['hackathon winner'], colorMap['group project']], 36 | code: 'https://github.com/OctoplusNinja/Pride-Campus', 37 | preview: 'https://devpost.com/software/pride-campus', 38 | title: 'Pride Campus', 39 | desc: ( 40 | 41 | {[ 42 | 'Spreading awareness about the LGBTQ+ Community with our Discord Bot.', 43 | 'I worked on the bot UI/UX logic & interaction part.', 44 | 'Tech stacks involved are JavaScript, Discord.js.' 45 | ].map((item, index) => ( 46 |
  • {item}
  • 47 | ))} 48 |
    49 | ), 50 | thumbnail: 'pc-thumbnail.jpg' 51 | }, 52 | { 53 | tags: ['solo project'], 54 | tagBgColors: [colorMap['solo project']], 55 | code: 'https://github.com/lostgirljourney/social-sphere', 56 | preview: 'https://mysocialsphere.vercel.app/', 57 | title: 'Social Sphere', 58 | desc: ( 59 | 60 | {[ 61 | 'This is my website which shows all my links in a single place.', 62 | ' It is designed and developed by myself.', 63 | 'Tech stacks involved are TypeScript, React.js, Vite.js, TailwindCSS.' 64 | ].map((item, index) => ( 65 |
  • {item}
  • 66 | ))} 67 |
    68 | ), 69 | thumbnail: 'ss-thumbnail.png' 70 | } 71 | ]; 72 | 73 | const ProjectsList = () => ( 74 | 75 | 76 |
    77 | {projects.map( 78 | ( 79 | { desc, tagBgColors, tags, title, code, preview, thumbnail }, 80 | index 81 | ) => { 82 | return ( 83 | 84 |
    85 |

    86 | {title} 87 |

    88 |
    89 | 90 | Code 91 | 92 | 93 | Preview 94 | 95 |
    96 |
    97 | {tags.map((tag, i) => { 98 | return ( 99 | 108 | ); 109 | })} 110 |
    111 |
    {desc}
    112 | {title} 121 | image.classList.remove('opacity-0') 122 | } 123 | /> 124 |
    125 |
    126 | ); 127 | } 128 | )} 129 |
    130 |
    131 | ); 132 | 133 | export default ProjectsList; 134 | -------------------------------------------------------------------------------- /src/containers/credits/CreditsList.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | DivWBorderWrapper, 3 | LinkWrapper, 4 | ParagraphWrapper, 5 | SectionHeading, 6 | SectionWrapper, 7 | Tag 8 | } from '@/components/common'; 9 | 10 | const credits = [ 11 | { 12 | site: 'https://cretu.dev/', 13 | title: 'cretu.dev', 14 | desc: ( 15 | 16 | This site inspired me to create something minimal. Especially keeping it 17 | to the point. I came across the site from the famous{' '} 18 | light bulb. I 19 | really loved the menu style and took a reference from it. 20 | 21 | ) 22 | }, 23 | { 24 | site: 'https://www.yashsehgal.com/', 25 | title: 'yashsehgal.com', 26 | desc: ( 27 | 28 | I took the major design inspiration from this site only. Since, it was 29 | in light 🌕 mode, I thought of having my site in dark 🌑 mode. 30 | 31 | ) 32 | }, 33 | { 34 | site: 'https://sreetamdas.com/', 35 | title: 'sreetamdas.com', 36 | desc: ( 37 | 38 | The first portfolio I came across, my site is heavily inspired by this 39 | site. This credits page is also inspired by this site's{' '} 40 | 41 | /credits 42 | 43 | . Also, other pages, such as /uses. 44 | 45 | ) 46 | }, 47 | { 48 | site: 'https://read.cv/', 49 | title: 'read.cv', 50 | desc: ( 51 | 52 | I really loved the ui of{' '} 53 | read.cv. Another 54 | major design inspiration I took for here only. This site is also helpful 55 | to publish your own cv. Check here{' '} 56 | 57 | mine 58 | 59 | . 60 | 61 | ) 62 | }, 63 | { 64 | site: 'https://notion.so/', 65 | title: 'notion.so', 66 | desc: ( 67 | 68 | I am a big fan of notion's ui. The cover photo for each page is 69 | inspired from notion pages only. 70 | 71 | ) 72 | } 73 | ]; 74 | 75 | const CreditsList = () => ( 76 | <> 77 | 78 | 79 |
    80 | {credits.map(({ desc, title, site }, index) => { 81 | return ( 82 | 83 |
    84 |
    85 |

    86 | {title} 87 |

    88 |
    89 | 94 | website 95 | 96 |
    97 |
    98 | {desc} 99 |
    100 |
    101 | ); 102 | })} 103 |
    104 |
    105 | 106 | 107 | 108 |
    109 |
    110 |

    111 | Aniruddha Das 112 |

    113 |
    114 | 119 | twitter 120 | 121 | 126 | github 127 | 128 |
    129 |
    130 | 131 |

    132 | For helping me to keep designing this site better and better. 133 |
    134 | PS. This is v3 of my site, previous two were rejected by him. 135 | Sigh. 🙂 136 |

    137 |
    138 |
    139 |
    140 |
    141 | 142 | ); 143 | 144 | export default CreditsList; 145 | -------------------------------------------------------------------------------- /src/containers/home/Experience.tsx: -------------------------------------------------------------------------------- 1 | import { 2 | DivWBorderWrapper, 3 | LinkWrapper, 4 | ListWrapper, 5 | SectionHeading, 6 | SectionWrapper, 7 | Tag 8 | } from '@/components/common'; 9 | import { colorMap } from '@/utils'; 10 | 11 | const experiences = [ 12 | { 13 | duration: "Aug '23 - Present", 14 | tags: ['full-time'], 15 | tagBgColors: [colorMap['full-time']], 16 | href: 'https://www.salesforce.com/in/?ir=1', 17 | get title() { 18 | return ( 19 | 20 | Associate Technical Support Engineer{' '} 21 | at Salesforce 22 | 23 | ); 24 | }, 25 | location: 'Hybrid', 26 | desc: ( 27 | 32 |
  • I am a new hire at the training phase. ✨
  • 33 |
    34 | ) 35 | }, 36 | { 37 | duration: "Dec '22 - Apr '23", 38 | tags: ['internship'], 39 | tagBgColors: [colorMap.internship], 40 | href: 'https://theinternetfolks.com/', 41 | get title() { 42 | return ( 43 | 44 | SWE Intern at The Internet Folks 45 | 46 | ); 47 | }, 48 | location: 'Remote', 49 | desc: ( 50 | 55 |
  • 56 | I worked and created POCs for different projects and also solved many 57 | high-priority bugs related to the core functionality of the given 58 | projects. 59 |
  • 60 |
  • 61 | I've mainly worked on Typescript, Next.js, React-Redux, React 62 | Query and Chakra UI for CSS. 63 |
  • 64 |
    65 | ) 66 | }, 67 | { 68 | duration: "Aug '22 - Nov '22", 69 | tags: ['full-time'], 70 | tagBgColors: [colorMap['full-time']], 71 | href: 'https://fleapo.com/', 72 | get title() { 73 | return ( 74 | 75 | Full Stack Developer at Fleapo 76 | 77 | ); 78 | }, 79 | location: 'On-site', 80 | desc: ( 81 | 86 |
  • 87 | I've been here as a full stack developer, working for the first 88 | time in backend space with the tech stack MongoDB and Node.js. 89 |
  • 90 |
  • 91 | I've built a project from scratch in the backend and also worked 92 | forward to integrate the frontend. 93 |
  • 94 |
    95 | ) 96 | }, 97 | { 98 | duration: "Mar '22 - Aug '22", 99 | tags: ['internship'], 100 | tagBgColors: [colorMap.internship], 101 | href: 'https://procedure.tech/', 102 | get title() { 103 | return ( 104 | 105 | SDE0 (Intern) at Procedure 106 | 107 | ); 108 | }, 109 | location: 'Remote', 110 | desc: ( 111 | 116 |
  • 117 | I've worked as a Frontend Developer Intern on projects based on 118 | Next.js + Typescript. 119 |
  • 120 |
  • 121 | I've fixed most of the high-priority UI fixes as well as 122 | developed complex UI components per the requirement. 123 |
  • 124 |
    125 | ) 126 | } 127 | ]; 128 | 129 | const Experience = () => ( 130 | 131 | 132 |
    133 | {experiences.map( 134 | ({ desc, duration, location, tagBgColors, tags, title }, index) => { 135 | return ( 136 | 137 |
    138 |
    139 |

    140 | {duration} 141 |

    142 | {tags.map((tag, i) => { 143 | return ( 144 | 153 | ); 154 | })} 155 |
    156 |
    157 |
    158 | {title} 159 |
    160 | {location} 161 |
    162 | {desc} 163 |
    164 |
    165 |
    166 | ); 167 | } 168 | )} 169 |
    170 |
    171 | ); 172 | 173 | export default Experience; 174 | -------------------------------------------------------------------------------- /src/components/Loader.tsx: -------------------------------------------------------------------------------- 1 | import anime from 'animejs'; 2 | import Head from 'next/head'; 3 | import React, { useEffect, useState } from 'react'; 4 | 5 | const Loader: React.FC = () => { 6 | const [animationRef, setAnimationRef] = useState< 7 | ReturnType | undefined 8 | >(); 9 | 10 | useEffect(() => { 11 | setAnimationRef( 12 | anime({ 13 | targets: '#loader path', 14 | strokeDashoffset: [anime.setDashoffset, 0], 15 | easing: 'easeInOutSine', 16 | duration: 1500, 17 | direction: 'alternate', 18 | loop: false 19 | }) 20 | ); 21 | }, []); 22 | 23 | return ( 24 | <> 25 | 26 | Falguni Sarkar 🌈 27 | 28 |
    29 | 37 | 41 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 66 | 72 | 78 | 84 | 90 | 96 | 102 | 108 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 132 | 138 | 144 | 150 | 156 | 162 | 168 | 172 | 173 |
    174 | 175 | ); 176 | }; 177 | 178 | export default Loader; 179 | --------------------------------------------------------------------------------