├── .eslintrc.json ├── .github └── FUNDING.yml ├── .gitignore ├── README.md ├── jsconfig.json ├── next.config.js ├── package-lock.json ├── package.json ├── postcss.config.js ├── public ├── favicon.svg ├── fonts │ └── OverusedGrotesk-VF.woff2 ├── images │ └── profile.webp └── logos │ ├── 404logo.svg │ ├── Logofull.svg │ ├── Logouppercase.svg │ ├── footer.svg │ └── logosimple.svg ├── src ├── app │ ├── about │ │ └── page.jsx │ ├── globals.css │ ├── layout.jsx │ ├── legal │ │ └── page.jsx │ ├── not-found.jsx │ ├── opengraph-image-alt.txt │ ├── opengraph-image.png │ ├── page.jsx │ ├── resources │ │ └── [slug] │ │ │ └── page.jsx │ ├── robots.jsx │ ├── sitemap.js │ ├── twitter-image.alt.txt │ └── twitter-image.png └── components │ ├── Button │ ├── Button.jsx │ └── LoadMoreButton.jsx │ ├── Card │ ├── ResourceCard.jsx │ ├── ResourceContainer.jsx │ └── Skeleton.jsx │ ├── Footer │ └── Footer.jsx │ ├── Header │ └── Navbar.jsx │ ├── SVGs │ ├── FooterTitle.jsx │ ├── Logofull.jsx │ └── Logosimple.jsx │ └── TabNavigation │ ├── TabButtons.jsx │ └── TabButtonsMobile.jsx └── tailwind.config.js /.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "next/core-web-vitals" 3 | } 4 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: supporthuyng 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 14 | -------------------------------------------------------------------------------- /.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 | .yarn/install-state.gz 8 | 9 | # testing 10 | /coverage 11 | 12 | # next.js 13 | /.next/ 14 | /out/ 15 | 16 | # production 17 | /build 18 | 19 | # misc 20 | .DS_Store 21 | *.pem 22 | 23 | # debug 24 | npm-debug.log* 25 | yarn-debug.log* 26 | yarn-error.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts 37 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "paths": { 4 | "@/*": ["./src/*"] 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /next.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | images: { 3 | dangerouslyAllowSVG: true, 4 | remotePatterns: [ 5 | { 6 | protocol: 'https', 7 | hostname: 'images.ctfassets.net', 8 | }, 9 | { 10 | protocol: 'https', 11 | hostname: 'api.producthunt.com', 12 | }, 13 | ], 14 | }, 15 | experimental: { 16 | scrollRestoration: true, 17 | }, 18 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "webstack", 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 | "@tailwindcss/container-queries": "^0.1.1", 13 | "@vercel/analytics": "^1.1.1", 14 | "contentful": "^10.6.5", 15 | "framer-motion": "^10.16.4", 16 | "next": "^14.0.3", 17 | "react": "^18", 18 | "react-copy-to-clipboard": "^5.1.0", 19 | "react-dom": "^18", 20 | "react-icons": "^4.11.0", 21 | "sharp": "^0.32.6" 22 | }, 23 | "devDependencies": { 24 | "autoprefixer": "^10.4.17", 25 | "eslint": "^8", 26 | "eslint-config-next": "14.0.1", 27 | "postcss": "^8.4.33", 28 | "prettier": "^3.0.3", 29 | "prettier-plugin-tailwindcss": "^0.5.6", 30 | "tailwindcss": "^3.4.1" 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {}, 5 | }, 6 | } 7 | -------------------------------------------------------------------------------- /public/favicon.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /public/fonts/OverusedGrotesk-VF.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithUsman0/Pillarstack/94f6f97d73aca7ef71fe32df36fbbcf3d7e4b28d/public/fonts/OverusedGrotesk-VF.woff2 -------------------------------------------------------------------------------- /public/images/profile.webp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CodeWithUsman0/Pillarstack/94f6f97d73aca7ef71fe32df36fbbcf3d7e4b28d/public/images/profile.webp -------------------------------------------------------------------------------- /public/logos/404logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /public/logos/Logofull.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /public/logos/Logouppercase.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /public/logos/footer.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /public/logos/logosimple.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /src/app/about/page.jsx: -------------------------------------------------------------------------------- 1 | "use client" 2 | 3 | import profile from "../../../public/images/profile.webp"; 4 | import Image from "next/image"; 5 | 6 | import { useState } from "react"; 7 | import { CopyToClipboard } from "react-copy-to-clipboard"; 8 | 9 | 10 | // export const metadata = { 11 | // metadataBase: new URL('https://pillarstack.com'), 12 | // alternates: { 13 | // canonical: '/about', 14 | // languages: { 15 | // 'en-US': '/en-US', 16 | // }, 17 | // }, 18 | // title: "Pillarstack — About Pillarstack", 19 | // description: 20 | // "Learn more about Pillarstack and the rationale behind its creation.", 21 | // }; 22 | 23 | export default function About() { 24 | const [copied, setCopied] = useState(false); 25 | 26 | const handleCopy = () => { 27 | setCopied(true); 28 | setTimeout(() => { 29 | setCopied(false); 30 | }, 2000); 31 | }; 32 | 33 | 34 | 35 | return ( 36 |
37 |
38 |

39 | About Pillarstack 40 |

41 |
42 |
43 |

44 | 45 | I created Pillarstack to address the frustrations I encountered when 46 | I started out in frontend development and web design. Hunting for 47 | resources and tools consumed a lot valuable time that could have 48 | been better spent honing my skills.{" "} 49 | 50 | 51 | 52 | Now Pillarstack exists to support those that have similar issues. 53 | These resources are handpicked and curated by me and other amazing 54 | contributors. 55 | 56 |

57 |
58 |
59 | profile headshot of Huy Nguyen 65 |
66 |
67 |

Huy Nguyen

68 | 69 | 70 | {copied ? "Copied to clipboard!" : "hello@huyng.xyz"} 71 | 72 | 73 |
74 |
75 |
76 |
77 | ); 78 | } 79 | -------------------------------------------------------------------------------- /src/app/globals.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | 5 | @layer base { 6 | *, 7 | *::before, 8 | *::after { 9 | box-sizing: border-box; 10 | } 11 | 12 | * { 13 | /* border: 1px solid red; */ 14 | margin: 0; 15 | padding: 0; 16 | font: inherit; 17 | } 18 | 19 | img, 20 | svg { 21 | display: block; 22 | max-width: 100%; 23 | } 24 | 25 | p { 26 | @apply tracking-base; 27 | } 28 | 29 | .section-padding { 30 | @apply px-6 sm:px-[5%]; 31 | } 32 | 33 | h1, 34 | h2, 35 | h3, 36 | h4, 37 | h5 { 38 | @apply tracking-close; 39 | } 40 | 41 | ::-moz-selection { 42 | background: #555555; 43 | } 44 | ::-webkit-selection { 45 | background: #555555; 46 | } 47 | ::selection { 48 | background: #555555; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/app/layout.jsx: -------------------------------------------------------------------------------- 1 | import localFont from "next/font/local"; 2 | import "./globals.css"; 3 | import Navbar from "@/components/Header/Navbar"; 4 | import Footer from "@/components/Footer/Footer"; 5 | import { Analytics } from "@vercel/analytics/react"; 6 | 7 | const overusedgrotesk = localFont({ 8 | src: [ 9 | { 10 | path: "../../public/fonts/OverusedGrotesk-VF.woff2", 11 | }, 12 | ], 13 | display: "block", 14 | variable: "--font-overusedgrotesk", 15 | }); 16 | 17 | export const metadata = { 18 | metadataBase: new URL('https://pillarstack.com'), 19 | alternates: { 20 | canonical: '/', 21 | languages: { 22 | 'en-US': '/en-US', 23 | }, 24 | }, 25 | title: "Pillarstack — Resources for web developers and designers", 26 | description: 27 | "Assorted resources for frontend developers and web designers. Explore curated and handpicked goodies that enhance your workflow and cultivate your growth.", 28 | }; 29 | 30 | export default function RootLayout({ children }) { 31 | return ( 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | {children} 40 |