diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index 8e6ffe4..0000000 --- a/.editorconfig +++ /dev/null @@ -1,10 +0,0 @@ -root = true - -[*] -indent_style = space -indent_size = 2 -end_of_line = lf -charset = utf-8 -trim_trailing_whitespace = true -insert_final_newline = true -quote_type = single diff --git a/.env.local b/.env.local deleted file mode 100644 index 61c9e38..0000000 --- a/.env.local +++ /dev/null @@ -1 +0,0 @@ -NEXT_PUBLIC_API_BASE_URL=https://hmrcode-backend.herokuapp.com diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..1a31aa8 --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,20 @@ +{ + "env": { + "browser": true, + "es2021": true + }, + "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended", "next/core-web-vitals", "prettier"], + "parser": "@typescript-eslint/parser", + "parserOptions": { + "ecmaVersion": "latest", + "sourceType": "module" + }, + "plugins": ["@typescript-eslint", "react"], + "rules": { + "no-console": "warn", + "no-undef": "off", + "no-unused-vars": "off", + "react/no-unescaped-entities": "off", + "@next/next/no-page-custom-font": "off" + } +} diff --git a/.github/workflows/development.yml b/.github/workflows/development.yml new file mode 100644 index 0000000..51d3a33 --- /dev/null +++ b/.github/workflows/development.yml @@ -0,0 +1,56 @@ +name: Development CI/CD Piipeline + +on: + pull_request: + branches: + - development + types: + - closed + +jobs: + build-test: + runs-on: ubuntu-latest + + steps: + - name: Checkout Code + uses: actions/checkout@v2 + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: "20" + + - name: Install Dependencies + run: yarn + + - name: Test Next.js App + run: yarn test + + - name: Build Next.js App + run: yarn build + + deploy: + runs-on: ubuntu-latest + needs: build-test + environment: development + steps: + - name: Checkout Code + uses: actions/checkout@v2 + + - name: Deploy to Development Environment + env: + VPS_IP: ${{ secrets.VPS_IP }} + VPS_USER: ${{ secrets.VPS_USER }} + VPS_KEY: ${{ secrets.VPS_KEY }} + run: | + echo "$VPS_KEY" > vps_key.pem + + chmod 600 vps_key.pem + + ssh -o StrictHostKeyChecking=no -i vps_key.pem $VPS_USER@$VPS_IP " + cd /home/hmcroot/app/development/hammercode-web && + git restore . && git clean -f && git checkout development && + git pull origin development && + yarn && + yarn build && + pm2 restart hammercode-web-dev || PORT=4001 pm2 start npm --name 'hammercode-web-dev' -- start" diff --git a/.gitignore b/.gitignore index 28d6154..fd3dbb5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,36 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# dependencies +/node_modules +/.pnp +.pnp.js +.yarn/install-state.gz + +# testing +/coverage + +# next.js +/.next/ +/out/ + +# production +/build + +# misc .DS_Store -.next -pnpm* -.yarn* -*.log -node_modules -out +*.pem + +# debug +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# local env files +.env*.local + +# vercel +.vercel + +# typescript +*.tsbuildinfo +next-env.d.ts diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100644 index 0000000..dd2184b --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1,2 @@ +npx lint-staged +yarn lint \ No newline at end of file diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..4d3b68f --- /dev/null +++ b/.prettierignore @@ -0,0 +1,8 @@ +.next +.cache +package-lock.json +public +node_modules +next-env.d.ts +next.config.ts +yarn.lock \ No newline at end of file diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..32265ab --- /dev/null +++ b/.prettierrc @@ -0,0 +1,8 @@ +{ + "trailingComma": "es5", + "bracketSpacing": true, + "printWidth": 120, + "tabWidth": 2, + "singleQuote": false, + "arrowParens": "always" +} diff --git a/README.md b/README.md index 661efd2..c403366 100644 --- a/README.md +++ b/README.md @@ -1,52 +1,36 @@ -

- -

Hammercode

- -

- -

- -

+This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app). ## Getting Started -Visit https://nextjs.org/learn to get started with Next.js. - -## Documentation - -Visit [https://nextjs.org/docs](https://nextjs.org/docs) to view the full documentation. - -## Who is using Next.js? - -Next.js is used by the world's leading companies. Check out the [Next.js Showcase](https://nextjs.org/showcase) to learn more. - -## Community - -The Next.js community can be found on [GitHub Discussions](https://github.com/vercel/next.js/discussions), where you can ask questions, voice ideas, and share your projects. +First, run the development server: -To chat with other community members you can join the [Next.js Discord](https://nextjs.org/discord). +```bash +npm run dev +# or +yarn dev +# or +pnpm dev +# or +bun dev +``` -Our [Code of Conduct](https://github.com/vercel/next.js/blob/canary/CODE_OF_CONDUCT.md) applies to all Next.js community channels. +Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. -## Contributing +You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file. -Please see our [contributing.md](/contributing.md). +This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font. -### Good First Issues +## Learn More -We have a list of [good first issues](https://github.com/vercel/next.js/labels/good%20first%20issue) that contain bugs that have a relatively limited scope. This is a great place to get started, gain experience, and get familiar with our contribution process. +To learn more about Next.js, take a look at the following resources: -## Authors +- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. +- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. -- Tim Neutkens ([@timneutkens](https://twitter.com/timneutkens)) -- Naoyuki Kanezawa ([@nkzawa](https://twitter.com/nkzawa)) -- Guillermo Rauch ([@rauchg](https://twitter.com/rauchg)) -- Arunoda Susiripala ([@arunoda](https://twitter.com/arunoda)) -- Tony Kovanen ([@tonykovanen](https://twitter.com/tonykovanen)) -- Dan Zajdband ([@impronunciable](https://twitter.com/impronunciable)) +You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! -## Security +## Deploy on Vercel -If you believe you have found a security vulnerability in Next.js, we encourage you to responsibly disclose this and not open a public issue. We will investigate all legitimate reports. Email `security@vercel.com` to disclose any security vulnerabilities. +The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js. - +Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details. diff --git a/components.json b/components.json new file mode 100644 index 0000000..7559f63 --- /dev/null +++ b/components.json @@ -0,0 +1,17 @@ +{ + "$schema": "https://ui.shadcn.com/schema.json", + "style": "default", + "rsc": true, + "tsx": true, + "tailwind": { + "config": "tailwind.config.ts", + "css": "src/app/globals.css", + "baseColor": "slate", + "cssVariables": true, + "prefix": "" + }, + "aliases": { + "components": "@/components", + "utils": "@/lib/utils" + } +} diff --git a/jest.config.ts b/jest.config.ts new file mode 100644 index 0000000..a1da983 --- /dev/null +++ b/jest.config.ts @@ -0,0 +1,27 @@ +import type { Config } from "jest"; +import nextJest from "next/jest.js"; + +const createJestConfig = nextJest({ + // Provide the path to your Next.js app to load next.config.js and .env files in your test environment + dir: "./", +}); + +// Add any custom config to be passed to Jest +const config: Config = { + preset: "ts-jest", + transform: { + "^.+\\.(t|j)sx?$": ["ts-jest", { isolatedModules: true }], + }, + coverageProvider: "v8", + testEnvironment: "jsdom", + moduleNameMapper: { + "^@/components/(.*)$": "/components/$1", + "^@/fetaures/(.*)$": "/fetaures/$1", + }, + setupFilesAfterEnv: ["/jest.setup.ts"], + // Add more setup options before each test is run + // setupFilesAfterEnv: ['/jest.setup.ts'], +}; + +// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async +export default createJestConfig(config); diff --git a/jest.setup.ts b/jest.setup.ts new file mode 100644 index 0000000..d0de870 --- /dev/null +++ b/jest.setup.ts @@ -0,0 +1 @@ +import "@testing-library/jest-dom"; diff --git a/next.config.js b/next.config.js deleted file mode 100644 index bec49a1..0000000 --- a/next.config.js +++ /dev/null @@ -1,17 +0,0 @@ -module.exports = { - i18n: { - // These are all the locales you want to support in - // your application - locales: ['id-ID', 'en-US'], - // This is the default locale you want to be used when visiting - // a non-locale prefixed path e.g. `/hello` - defaultLocale: 'id-ID', - localeDetection: false, - // This is a list of locale domains and the default locale they - // should handle (these are only required when setting up domain routing) - // Note: subdomains must be included in the domain value to be matched e.g. "fr.example.com". - }, - images: { - domains: ['drive.google.com'], - }, -}; diff --git a/next.config.mjs b/next.config.mjs new file mode 100644 index 0000000..1a9794e --- /dev/null +++ b/next.config.mjs @@ -0,0 +1,18 @@ +import createNextIntlPlugin from "next-intl/plugin"; + +const withNextIntl = createNextIntlPlugin("./src/lib/i18n.ts"); + +/** @type {import('next').NextConfig} */ +const nextConfig = { + images: { + remotePatterns: [ + { + protocol: "https", + hostname: "**", + }, + ], + }, + trailingSlash: true, +}; + +export default withNextIntl(nextConfig); diff --git a/package.json b/package.json index e496073..40c2c10 100644 --- a/package.json +++ b/package.json @@ -1,26 +1,68 @@ { - "name": "hammercode.org", - "dependencies": { - "autoprefixer": "^10.4.8", - "markdown-to-jsx": "^7.1.7", - "next": "^13.0.3", - "next-intl": "^2.7.4", - "postcss": "^8.4.16", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "react-icons": "^4.7.1", - "sharp": "^0.32.0", - "tailwindcss": "^3.1.8" - }, + "name": "hammercode-web", + "version": "0.1.0", + "private": true, + "type": "module", "scripts": { "dev": "next dev", "build": "next build", "start": "next start", - "export": "rm -rf .next out && next build && next export" + "lint": "next lint", + "format": "prettier --write .", + "check-format": "prettier --check .", + "prepare": "husky", + "test": "jest", + "test:watch": "jest --watch" + }, + "husky": { + "hooks": { + "pre-commit": "yarn format && git add -A . --allow-empty" + } + }, + "dependencies": { + "@radix-ui/react-dropdown-menu": "^2.1.1", + "@radix-ui/react-select": "^2.1.1", + "@radix-ui/react-slot": "^1.1.0", + "class-variance-authority": "^0.7.0", + "clsx": "^2.1.1", + "embla-carousel-autoplay": "^8.2.0", + "embla-carousel-react": "^8.2.0", + "lucide-react": "^0.428.0", + "next": "14.2.5", + "next-intl": "^3.17.6", + "next-themes": "^0.3.0", + "react": "^18", + "react-dom": "^18", + "tailwind-merge": "^2.5.2", + "tailwindcss-animate": "^1.0.7" }, "devDependencies": { - "@types/node": "^18.7.3", - "@types/react": "^18.0.17", - "typescript": "^4.7.4" + "@testing-library/dom": "^10.4.0", + "@testing-library/jest-dom": "^6.4.8", + "@testing-library/react": "^16.0.0", + "@testing-library/user-event": "^14.5.2", + "@types/jest": "^29.5.12", + "@types/node": "^20", + "@types/react": "^18", + "@types/react-dom": "^18", + "@typescript-eslint/eslint-plugin": "^8.0.1", + "@typescript-eslint/parser": "^8.0.1", + "eslint": "^8", + "eslint-config-next": "14.2.5", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-react": "^7.35.0", + "husky": "^9.1.4", + "jest": "^29.7.0", + "jest-environment-jsdom": "^29.7.0", + "lint-staged": "^15.2.8", + "postcss": "^8", + "prettier": "3.3.3", + "tailwindcss": "^3.4.1", + "ts-jest": "^29.2.4", + "ts-node": "^10.9.2", + "typescript": "^5" + }, + "lint-staged": { + "**/*": "prettier --write --ignore-unknown" } } diff --git a/postcss.config.js b/postcss.config.js deleted file mode 100644 index 96bb01e..0000000 --- a/postcss.config.js +++ /dev/null @@ -1,6 +0,0 @@ -module.exports = { - plugins: { - tailwindcss: {}, - autoprefixer: {}, - }, -} \ No newline at end of file diff --git a/postcss.config.mjs b/postcss.config.mjs new file mode 100644 index 0000000..1a69fd2 --- /dev/null +++ b/postcss.config.mjs @@ -0,0 +1,8 @@ +/** @type {import('postcss-load-config').Config} */ +const config = { + plugins: { + tailwindcss: {}, + }, +}; + +export default config; diff --git a/public/assets/icons/ic_discord.svg b/public/assets/icons/ic_discord.svg new file mode 100644 index 0000000..8f58120 --- /dev/null +++ b/public/assets/icons/ic_discord.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/assets/icons/ic_figma.svg b/public/assets/icons/ic_figma.svg new file mode 100644 index 0000000..e49d222 --- /dev/null +++ b/public/assets/icons/ic_figma.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/public/assets/icons/ic_golang.svg b/public/assets/icons/ic_golang.svg new file mode 100644 index 0000000..165c94b --- /dev/null +++ b/public/assets/icons/ic_golang.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/public/assets/icons/ic_hmc-dark.svg b/public/assets/icons/ic_hmc-dark.svg new file mode 100644 index 0000000..3d7b4b8 --- /dev/null +++ b/public/assets/icons/ic_hmc-dark.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/public/assets/icons/ic_hmc-full-dark.svg b/public/assets/icons/ic_hmc-full-dark.svg new file mode 100644 index 0000000..7df1ca3 --- /dev/null +++ b/public/assets/icons/ic_hmc-full-dark.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/public/assets/icons/ic_hmc-full.svg b/public/assets/icons/ic_hmc-full.svg new file mode 100644 index 0000000..73d9d0a --- /dev/null +++ b/public/assets/icons/ic_hmc-full.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/public/assets/icons/ic_hmc-light.svg b/public/assets/icons/ic_hmc-light.svg new file mode 100644 index 0000000..7bdbf05 --- /dev/null +++ b/public/assets/icons/ic_hmc-light.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/public/assets/icons/ic_instagram.svg b/public/assets/icons/ic_instagram.svg new file mode 100644 index 0000000..8be3255 --- /dev/null +++ b/public/assets/icons/ic_instagram.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/assets/icons/ic_linkedin.svg b/public/assets/icons/ic_linkedin.svg new file mode 100644 index 0000000..7caf80f --- /dev/null +++ b/public/assets/icons/ic_linkedin.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/assets/icons/ic_python.svg b/public/assets/icons/ic_python.svg new file mode 100644 index 0000000..d741b1a --- /dev/null +++ b/public/assets/icons/ic_python.svg @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/public/assets/icons/ic_qoute.svg b/public/assets/icons/ic_qoute.svg new file mode 100644 index 0000000..1c99266 --- /dev/null +++ b/public/assets/icons/ic_qoute.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/assets/icons/ic_react.svg b/public/assets/icons/ic_react.svg new file mode 100644 index 0000000..96d61d8 --- /dev/null +++ b/public/assets/icons/ic_react.svg @@ -0,0 +1,4 @@ + + + + diff --git a/public/assets/images/illustrations/about.webp b/public/assets/images/illustrations/about.webp new file mode 100644 index 0000000..04a7f7c Binary files /dev/null and b/public/assets/images/illustrations/about.webp differ diff --git a/public/assets/images/illustrations/classes.png b/public/assets/images/illustrations/classes.png new file mode 100644 index 0000000..04920ca Binary files /dev/null and b/public/assets/images/illustrations/classes.png differ diff --git a/public/assets/images/illustrations/discuss.png b/public/assets/images/illustrations/discuss.png new file mode 100644 index 0000000..2e7a050 Binary files /dev/null and b/public/assets/images/illustrations/discuss.png differ diff --git a/public/assets/images/illustrations/hero-section.webp b/public/assets/images/illustrations/hero-section.webp new file mode 100644 index 0000000..dc2cd8d Binary files /dev/null and b/public/assets/images/illustrations/hero-section.webp differ diff --git a/public/assets/images/illustrations/partnership.png b/public/assets/images/illustrations/partnership.png new file mode 100644 index 0000000..e36aafc Binary files /dev/null and b/public/assets/images/illustrations/partnership.png differ diff --git a/public/assets/images/illustrations/shape-about1.svg b/public/assets/images/illustrations/shape-about1.svg new file mode 100644 index 0000000..295db78 --- /dev/null +++ b/public/assets/images/illustrations/shape-about1.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/public/assets/images/illustrations/shape-about2.svg b/public/assets/images/illustrations/shape-about2.svg new file mode 100644 index 0000000..d3bc159 --- /dev/null +++ b/public/assets/images/illustrations/shape-about2.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/public/assets/images/illustrations/shape-overlay.svg b/public/assets/images/illustrations/shape-overlay.svg new file mode 100644 index 0000000..4afaf33 --- /dev/null +++ b/public/assets/images/illustrations/shape-overlay.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/public/assets/images/logos/efishery-logo.png b/public/assets/images/logos/efishery-logo.png new file mode 100644 index 0000000..8b51bff Binary files /dev/null and b/public/assets/images/logos/efishery-logo.png differ diff --git a/public/assets/images/logos/icehouse-logo.png b/public/assets/images/logos/icehouse-logo.png new file mode 100644 index 0000000..068632d Binary files /dev/null and b/public/assets/images/logos/icehouse-logo.png differ diff --git a/public/assets/images/logos/shipper-logo.png b/public/assets/images/logos/shipper-logo.png new file mode 100644 index 0000000..d2a611e Binary files /dev/null and b/public/assets/images/logos/shipper-logo.png differ diff --git a/public/assets/images/logos/warungpintar-logo.png b/public/assets/images/logos/warungpintar-logo.png new file mode 100644 index 0000000..d0c99bf Binary files /dev/null and b/public/assets/images/logos/warungpintar-logo.png differ diff --git a/public/assets/images/peoples/ades.webp b/public/assets/images/peoples/ades.webp new file mode 100644 index 0000000..5dc3d94 Binary files /dev/null and b/public/assets/images/peoples/ades.webp differ diff --git a/public/assets/images/peoples/afandy.webp b/public/assets/images/peoples/afandy.webp new file mode 100644 index 0000000..086a927 Binary files /dev/null and b/public/assets/images/peoples/afandy.webp differ diff --git a/public/assets/images/peoples/akwan.webp b/public/assets/images/peoples/akwan.webp new file mode 100644 index 0000000..ef01c18 Binary files /dev/null and b/public/assets/images/peoples/akwan.webp differ diff --git a/public/assets/images/peoples/alung.webp b/public/assets/images/peoples/alung.webp new file mode 100644 index 0000000..ec9b7d6 Binary files /dev/null and b/public/assets/images/peoples/alung.webp differ diff --git a/public/assets/images/peoples/anggi.webp b/public/assets/images/peoples/anggi.webp new file mode 100644 index 0000000..93570da Binary files /dev/null and b/public/assets/images/peoples/anggi.webp differ diff --git a/public/assets/images/peoples/cipta.webp b/public/assets/images/peoples/cipta.webp new file mode 100644 index 0000000..ad66c76 Binary files /dev/null and b/public/assets/images/peoples/cipta.webp differ diff --git a/public/assets/images/peoples/faldi.webp b/public/assets/images/peoples/faldi.webp new file mode 100644 index 0000000..8517e5b Binary files /dev/null and b/public/assets/images/peoples/faldi.webp differ diff --git a/public/assets/images/peoples/fendi.webp b/public/assets/images/peoples/fendi.webp new file mode 100644 index 0000000..b62955a Binary files /dev/null and b/public/assets/images/peoples/fendi.webp differ diff --git a/public/assets/images/peoples/nadya.webp b/public/assets/images/peoples/nadya.webp new file mode 100644 index 0000000..d51d96c Binary files /dev/null and b/public/assets/images/peoples/nadya.webp differ diff --git a/public/assets/images/peoples/vicky.webp b/public/assets/images/peoples/vicky.webp new file mode 100644 index 0000000..ba37c05 Binary files /dev/null and b/public/assets/images/peoples/vicky.webp differ diff --git a/public/assets/images/peoples/widya.webp b/public/assets/images/peoples/widya.webp new file mode 100644 index 0000000..fce3f94 Binary files /dev/null and b/public/assets/images/peoples/widya.webp differ diff --git a/public/assets/images/peoples/yaya.webp b/public/assets/images/peoples/yaya.webp new file mode 100644 index 0000000..e2f27a5 Binary files /dev/null and b/public/assets/images/peoples/yaya.webp differ diff --git a/public/eshos.png b/public/eshos.png deleted file mode 100644 index 3d8736d..0000000 Binary files a/public/eshos.png and /dev/null differ diff --git a/public/h-logo.svg b/public/h-logo.svg deleted file mode 100644 index 2f45794..0000000 --- a/public/h-logo.svg +++ /dev/null @@ -1,15 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/public/hc-logo-new.svg b/public/hc-logo-new.svg deleted file mode 100644 index 1b994e7..0000000 --- a/public/hc-logo-new.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - hammercode - - - - - - - diff --git a/public/logo-h.svg b/public/logo-h.svg deleted file mode 100644 index 50d6b2d..0000000 --- a/public/logo-h.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/public/next.svg b/public/next.svg new file mode 100644 index 0000000..5174b28 --- /dev/null +++ b/public/next.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/shipper.svg b/public/shipper.svg deleted file mode 100644 index 4678334..0000000 --- a/public/shipper.svg +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/public/tkp.svg b/public/tkp.svg deleted file mode 100644 index 025f6bb..0000000 --- a/public/tkp.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/public/vercel.svg b/public/vercel.svg new file mode 100644 index 0000000..d2f8422 --- /dev/null +++ b/public/vercel.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/public/warpin.png b/public/warpin.png deleted file mode 100644 index 206f5ac..0000000 Binary files a/public/warpin.png and /dev/null differ diff --git a/src/app/[locale]/about/page.tsx b/src/app/[locale]/about/page.tsx new file mode 100644 index 0000000..e08c782 --- /dev/null +++ b/src/app/[locale]/about/page.tsx @@ -0,0 +1,6 @@ +import AboutPage from "@/features/about"; + +const About = () => { + return ; +}; +export default About; diff --git a/src/app/[locale]/certificates/[slug]/page.tsx b/src/app/[locale]/certificates/[slug]/page.tsx new file mode 100644 index 0000000..ac94b76 --- /dev/null +++ b/src/app/[locale]/certificates/[slug]/page.tsx @@ -0,0 +1,33 @@ +import { notFound } from "next/navigation"; + +import Certificate from "@/features/certificate/Certificate"; +import { CertificateType } from "@/features/certificate/types"; + +export async function getCertificate(slug: string) { + try { + const response = await fetch(`https://moonlight.hammercode.org/v1/certificates/${slug}`); + if (!response.ok) return null; + + return response.json(); + } catch (error) { + console.error("Error fetching certificate:", error); + return null; + } +} + +type Props = { + params: { + slug: string; + }; +}; + +const CertificateDetail = async ({ params }: Props) => { + const certificate: CertificateType = await getCertificate(params.slug); + if (!certificate.name) { + return notFound(); + } + + return ; +}; + +export default CertificateDetail; diff --git a/src/app/[locale]/events/page.tsx b/src/app/[locale]/events/page.tsx new file mode 100644 index 0000000..996387e --- /dev/null +++ b/src/app/[locale]/events/page.tsx @@ -0,0 +1,6 @@ +import EventsPage from "@/features/events"; + +const Events = () => { + return ; +}; +export default Events; diff --git a/src/app/[locale]/globals.css b/src/app/[locale]/globals.css new file mode 100644 index 0000000..45b94c1 --- /dev/null +++ b/src/app/[locale]/globals.css @@ -0,0 +1,77 @@ +@tailwind base; +@tailwind components; +@tailwind utilities; + +@layer base { + :root { + --hmc-primary: #0f3665; + --hmc-primary-foreground: #fff; + --hmc-tertiary: #04bce9; + --hmc-tertiary-foreground: #fff; + --background: 0 0% 100%; + --foreground: 222.2 84% 4.9%; + --card: 0 0% 100%; + --card-foreground: 222.2 84% 4.9%; + --popover: 0 0% 100%; + --popover-foreground: 222.2 84% 4.9%; + --primary: 221.2 83.2% 53.3%; + --primary-foreground: 210 40% 98%; + --secondary: 210 40% 96.1%; + --secondary-foreground: 222.2 47.4% 11.2%; + --muted: 210 40% 96.1%; + --muted-foreground: 215.4 16.3% 46.9%; + --accent: 210 40% 96.1%; + --accent-foreground: 222.2 47.4% 11.2%; + --destructive: 0 84.2% 60.2%; + --destructive-foreground: 210 40% 98%; + --border: 214.3 31.8% 91.4%; + --input: 214.3 31.8% 91.4%; + --ring: 221.2 83.2% 53.3%; + --radius: 0.5rem; + --chart-1: 12 76% 61%; + --chart-2: 173 58% 39%; + --chart-3: 197 37% 24%; + --chart-4: 43 74% 66%; + --chart-5: 27 87% 67%; + } + + .dark { + --hmc-primary: #fff; + --hmc-primary-foreground: #0f3665; + --hmc-tertiary: #fff; + --hmc-tertiary-foreground: #0f3665; + --background: 222.2 84% 4.9%; + --foreground: 210 40% 98%; + --card: 222.2 84% 4.9%; + --card-foreground: 210 40% 98%; + --popover: 222.2 84% 4.9%; + --popover-foreground: 210 40% 98%; + --primary: 217.2 91.2% 59.8%; + --primary-foreground: 222.2 47.4% 11.2%; + --secondary: 217.2 32.6% 17.5%; + --secondary-foreground: 210 40% 98%; + --muted: 217.2 32.6% 17.5%; + --muted-foreground: 215 20.2% 65.1%; + --accent: 217.2 32.6% 17.5%; + --accent-foreground: 210 40% 98%; + --destructive: 0 62.8% 30.6%; + --destructive-foreground: 210 40% 98%; + --border: 217.2 32.6% 17.5%; + --input: 217.2 32.6% 17.5%; + --ring: 224.3 76.3% 48%; + --chart-1: 220 70% 50%; + --chart-2: 160 60% 45%; + --chart-3: 30 80% 55%; + --chart-4: 280 65% 60%; + --chart-5: 340 75% 55%; + } +} + +@layer base { + * { + @apply border-border; + } + body { + @apply bg-background text-foreground; + } +} diff --git a/src/app/[locale]/layout.tsx b/src/app/[locale]/layout.tsx new file mode 100644 index 0000000..8002f7c --- /dev/null +++ b/src/app/[locale]/layout.tsx @@ -0,0 +1,50 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import { NextIntlClientProvider } from "next-intl"; +import { getMessages, getTranslations, unstable_setRequestLocale } from "next-intl/server"; +import { Sora } from "next/font/google"; +import "./globals.css"; +import Wrapper from "@/components/layout/wrapper"; +import { locales } from "@/lib/config"; +import { notFound } from "next/navigation"; +const sora = Sora({ subsets: ["latin"] }); + +type Props = { + params: { + locale: string; + }; + children: React.ReactNode; +}; + +export function generateStaticParams() { + return locales.map((locale) => ({ locale })); +} + +export async function generateMetadata({ params: { locale } }: Props) { + const t = await getTranslations({ locale, namespace: "LocaleLayout" }); + + return { + title: t("title"), + description: t("description"), + }; +} + +export default async function LocaleRootLayout({ children, params: { locale } }: Readonly) { + if (!locales.includes(locale as any)) notFound(); + + unstable_setRequestLocale(locale); + + const messages = await getMessages(); + + return ( + + + + + + + {children} + + + + ); +} diff --git a/src/app/[locale]/page.tsx b/src/app/[locale]/page.tsx new file mode 100644 index 0000000..724ad1b --- /dev/null +++ b/src/app/[locale]/page.tsx @@ -0,0 +1,18 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import Home from "@/features/home"; +import { locales } from "@/lib/config"; +import { unstable_setRequestLocale } from "next-intl/server"; +import { notFound } from "next/navigation"; + +type Props = { + params: { + locale: string; + }; +}; + +export default function HomePage({ params: { locale } }: Props) { + if (!locales.includes(locale as any)) notFound(); + unstable_setRequestLocale(locale); + + return ; +} diff --git a/src/app/favicon.ico b/src/app/favicon.ico new file mode 100644 index 0000000..718d6fe Binary files /dev/null and b/src/app/favicon.ico differ diff --git a/src/app/layout.tsx b/src/app/layout.tsx new file mode 100644 index 0000000..568d357 --- /dev/null +++ b/src/app/layout.tsx @@ -0,0 +1,9 @@ +import { ReactNode } from "react"; + +type Props = { + children: ReactNode; +}; + +export default function RootLayout({ children }: Props) { + return children; +} diff --git a/src/app/not-found.tsx b/src/app/not-found.tsx new file mode 100644 index 0000000..23405db --- /dev/null +++ b/src/app/not-found.tsx @@ -0,0 +1,13 @@ +"use client"; + +import Error from "next/error"; + +export default function NotFound() { + return ( + + + + + + ); +} diff --git a/src/app/page.tsx b/src/app/page.tsx new file mode 100644 index 0000000..7c8b9a1 --- /dev/null +++ b/src/app/page.tsx @@ -0,0 +1,18 @@ +import { unstable_setRequestLocale } from "next-intl/server"; +import { redirect } from "@/lib/navigation"; +import { notFound } from "next/navigation"; +import { locales } from "@/lib/config"; + +type Props = { + params: { + locale: string; + }; +}; + +export default function RootPage({ params: { locale } }: Props) { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + if (!locales.includes(locale as any)) notFound(); + unstable_setRequestLocale(locale); + + redirect("/en"); +} diff --git a/src/components/Footer/Footer.module.css b/src/components/Footer/Footer.module.css deleted file mode 100644 index d6d998d..0000000 --- a/src/components/Footer/Footer.module.css +++ /dev/null @@ -1,4 +0,0 @@ -.footer { - @apply border-t py-12; - @apply border-dashed; -} diff --git a/src/components/Footer/index.tsx b/src/components/Footer/index.tsx deleted file mode 100644 index cab6fca..0000000 --- a/src/components/Footer/index.tsx +++ /dev/null @@ -1,108 +0,0 @@ -import { useTranslations } from 'next-intl'; -import Link from 'next/link'; -import { whatsappLink, whatsappNo } from 'src/lib/url'; -import styles from './Footer.module.css'; - -export default function Footer() { - const t = useTranslations('footer-component'); - - const year = new Date().getFullYear(); - return ( - - ); -} diff --git a/src/components/Header/Header.module.css b/src/components/Header/Header.module.css deleted file mode 100644 index 9504e70..0000000 --- a/src/components/Header/Header.module.css +++ /dev/null @@ -1,8 +0,0 @@ -.img-logo { - width: 180px; -} - -.header { - @apply py-4; - @apply border-b; -} diff --git a/src/components/Header/index.tsx b/src/components/Header/index.tsx deleted file mode 100644 index e5626aa..0000000 --- a/src/components/Header/index.tsx +++ /dev/null @@ -1,81 +0,0 @@ -import Link from "next/link"; -import { useRouter } from "next/router"; -import React from "react"; -import styles from "./Header.module.css"; -// About.js -import { useTranslations } from "next-intl"; -import LocaleSwitcher from "../home/LocaleSwitcher"; - -function NavLink({ - href, - children, -}: { - href: string; - children?: React.ReactNode; -}) { - const router = useRouter(); - const isActive = router.pathname === href; - const className = isActive ? "text-secondary" : ""; - - const mappedChildren = React.Children.map(children, function (node) { - if (!React.isValidElement(node)) return node; - - return React.cloneElement(node, { className, ...node.props }); - }); - - if (!mappedChildren?.length) return null; - - return ( - - {mappedChildren[0]} - - ); -} - -export default function Header() { - const t = useTranslations("nav"); - - return ( -
-
-
-
- - - - - -
- -
- -
-
-
-
- ); -} diff --git a/src/components/common/footer/Footer.tsx b/src/components/common/footer/Footer.tsx new file mode 100644 index 0000000..66e13e9 --- /dev/null +++ b/src/components/common/footer/Footer.tsx @@ -0,0 +1,81 @@ +import React from "react"; +import { dataFooter } from "./constants"; +import { Link } from "@/lib/navigation"; +import Image from "next/image"; +import { Button } from "@/components/ui/button"; +import { useTranslations } from "next-intl"; + +const Footer = () => { + const date = new Date(); + const { resource, social_media, contact } = dataFooter; + + const t = useTranslations("Footer"); + + return ( + <> +
+
+
+ hammercode-logo + + {/* Resources */} +
+

{t("resource.title")}

+
+ {resource.data.map((data, index) => ( + + {t(`resource.data.${index}.name`)} + + ))} +
+
+ + {/* Social Media */} +
+

{t("social_media.title")}

+
+ {social_media.data.map((data) => ( + + {data.name} + + ))} +
+
+ + {/* Contact */} +
+

{t("contact.title")}

+
+ {contact.data.map((data) => ( + + ))} +
+
+
+
+
+
+

+ {date.getFullYear()} © Penggiat Teknologi Palu Berkarya +

+
+ + ); +}; + +export default Footer; diff --git a/src/components/common/footer/constants.ts b/src/components/common/footer/constants.ts new file mode 100644 index 0000000..56dbfb3 --- /dev/null +++ b/src/components/common/footer/constants.ts @@ -0,0 +1,55 @@ +import { FooterType } from "./types"; + +export const dataFooter: FooterType = { + resource: { + title: "Resources", + data: [ + { + name: "Home", + navigate_url: "/", + }, + { + name: "About Us", + navigate_url: "/about", + }, + ], + }, + social_media: { + title: "Let's Join", + data: [ + { + name: "Discord", + navigate_url: "https://discord.com/invite/M9mNK6MBbu", + }, + { + name: "Instagram", + navigate_url: "https://instagram.com/hmrcode", + }, + { + name: "Linkedin", + navigate_url: "https://www.linkedin.com/company/hammercode", + }, + { + name: "Github", + navigate_url: "https://github.com/hammer-code", + }, + ], + }, + contact: { + title: "Contact", + data: [ + { + value: "081355893352", + navigate_url: "https://wa.me/6281355893352", + }, + { + value: "hammercode28@gmail.com", + navigate_url: "hammercode28@gmail.com", + }, + { + value: "Jl. Lagarutu No. 28, Tanamodindi, Palu", + navigate_url: undefined, + }, + ], + }, +}; diff --git a/src/components/common/footer/types.ts b/src/components/common/footer/types.ts new file mode 100644 index 0000000..49e726f --- /dev/null +++ b/src/components/common/footer/types.ts @@ -0,0 +1,24 @@ +type Resource = { + name: string; + navigate_url: string; +}; + +type Contact = { + value: string; + navigate_url?: string; +}; + +export type FooterType = { + resource: { + title: string; + data: Resource[]; + }; + social_media: { + title: string; + data: Resource[]; + }; + contact: { + title: string; + data: Contact[]; + }; +}; diff --git a/src/components/common/locale-toggle/index.tsx b/src/components/common/locale-toggle/index.tsx new file mode 100644 index 0000000..acc497a --- /dev/null +++ b/src/components/common/locale-toggle/index.tsx @@ -0,0 +1,54 @@ +import { useTransition } from "react"; +import { useLocale } from "next-intl"; +import { useParams } from "next/navigation"; + +import { usePathname, useRouter } from "@/lib/navigation"; +import { Locale } from "@/lib/i18n"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; +import { Button } from "@/components/ui/button"; + +const LocaleToggle = () => { + const locale = useLocale(); + const router = useRouter(); + const [isPending, startTransition] = useTransition(); + const pathname = usePathname(); + const params = useParams(); + + const handleSwitch = (value: string) => { + const nextLocale = value as Locale; + startTransition(() => { + router.replace( + // @ts-expect-error -- TypeScript will validate that only known `params` + // are used in combination with a given `pathname`. Since the two will + // always match for the current route, we can skip runtime checks. + { pathname, params }, + { locale: nextLocale } + ); + }); + }; + return ( + + + + + + handleSwitch("id")} className="cursor-pointer"> + 🇮🇩 ID + + handleSwitch("en")} className="cursor-pointer"> + 🇬🇧 EN + + + + ); +}; + +export default LocaleToggle; diff --git a/src/components/common/mode-toggle/index.tsx b/src/components/common/mode-toggle/index.tsx new file mode 100644 index 0000000..ab0d340 --- /dev/null +++ b/src/components/common/mode-toggle/index.tsx @@ -0,0 +1,25 @@ +import * as React from "react"; +import { Moon, Sun } from "lucide-react"; +import { useTheme } from "next-themes"; + +import { Button } from "@/components/ui/button"; + +export function ModeToggle() { + const { theme, setTheme } = useTheme(); + + const handleSetTheme = () => { + if (theme === "light") { + setTheme("dark"); + } else { + setTheme("light"); + } + }; + + return ( + + ); +} diff --git a/src/components/common/navbar/NavbarList.tsx b/src/components/common/navbar/NavbarList.tsx new file mode 100644 index 0000000..09ae151 --- /dev/null +++ b/src/components/common/navbar/NavbarList.tsx @@ -0,0 +1,15 @@ +import { Link } from "@/lib/navigation"; +import { ComponentProps } from "react"; +import { pathnames } from "@/lib/config"; + +export type NavbarListProps = ComponentProps>; + +function NavbarList({ href, ...rest }: NavbarListProps) { + return ( + + {rest.title} + + ); +} + +export default NavbarList; diff --git a/src/components/common/navbar/constant.ts b/src/components/common/navbar/constant.ts new file mode 100644 index 0000000..ea7c658 --- /dev/null +++ b/src/components/common/navbar/constant.ts @@ -0,0 +1,17 @@ +import { NavbarListProps } from "./NavbarList"; +import { ValidPathnames } from "./type"; + +export const LINK: NavbarListProps[] = [ + { + id: "1", + href: "/about", + }, + { + id: "2", + href: "/events", + }, + // { + // id: "3", + // href: "/contact", + // }, +]; diff --git a/src/components/common/navbar/index.tsx b/src/components/common/navbar/index.tsx new file mode 100644 index 0000000..dc4ae80 --- /dev/null +++ b/src/components/common/navbar/index.tsx @@ -0,0 +1,34 @@ +import { Link } from "@/lib/navigation"; + +import NavbarList from "./NavbarList"; +import { ModeToggle } from "../mode-toggle"; +import { useTranslations } from "next-intl"; +import LocaleToggle from "../locale-toggle"; +import { LINK } from "./constant"; + +const Navbar = () => { + const t = useTranslations("Layout"); + return ( +
+
+
+ +
+ + + +
+
+
+ ); +}; + +export default Navbar; diff --git a/src/components/common/navbar/type.ts b/src/components/common/navbar/type.ts new file mode 100644 index 0000000..c2c6eac --- /dev/null +++ b/src/components/common/navbar/type.ts @@ -0,0 +1,7 @@ +import { pathnames } from "@/lib/config"; + +export type PathnamesKeys = keyof typeof pathnames; +export type PathnameValues = { + [K in PathnamesKeys]: (typeof pathnames)[K] extends string ? string : keyof (typeof pathnames)[K]; +}; +export type ValidPathnames = PathnamesKeys; diff --git a/src/components/event/EventFilter.tsx b/src/components/event/EventFilter.tsx deleted file mode 100644 index 759a501..0000000 --- a/src/components/event/EventFilter.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import React from "react"; - -function EventFilter() { - return ( -
-
- -
-
- -
-
- ); -} - -export default EventFilter; diff --git a/src/components/event/EventItem.tsx b/src/components/event/EventItem.tsx deleted file mode 100644 index 297211c..0000000 --- a/src/components/event/EventItem.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import React from 'react'; -import Link from 'next/link'; - -import { formatDate } from 'src/lib/date'; - -import { IHMCEvent } from 'src/lib/types'; - -function EventItem({ locale, event }: { locale: string; event: IHMCEvent }) { - return ( -
-
-
-
-

{formatDate(event.date, locale)}

-

- {event.name} -

-

Online

-
-
-
- ); -} - -export default EventItem; diff --git a/src/components/home/AboutUsSection.tsx b/src/components/home/AboutUsSection.tsx deleted file mode 100644 index 24274d9..0000000 --- a/src/components/home/AboutUsSection.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import React from "react"; -import {useTranslations} from "next-intl"; - -function AboutUsSection() { - const t = useTranslations('home-page'); - return ( -
-
-
-
-
-
-

{t('about-us-section-title')}

-

- {t('about-us-section-sub-title')} -

-

- {t('about-us-section-description')} -

-
-
-
-
-
- ); -} - -export default AboutUsSection; diff --git a/src/components/home/ContactUsSection.tsx b/src/components/home/ContactUsSection.tsx deleted file mode 100644 index 871055a..0000000 --- a/src/components/home/ContactUsSection.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import React from 'react'; - -import { useTranslations } from 'next-intl'; -import { whatsappLink } from 'src/lib/url'; - -function ContactUsSection() { - const t = useTranslations('home-page'); - - return ( -
-
-
-

- {t('contact-us-section-title')} -

-

- {t('contact-us-section-description')} -

- - {t('contact-us-section-cta')} - -
-
-
- ); -} - -export default ContactUsSection; diff --git a/src/components/home/HeroSection.tsx b/src/components/home/HeroSection.tsx deleted file mode 100644 index 4e258f4..0000000 --- a/src/components/home/HeroSection.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import React from "react"; -import {useTranslations} from "next-intl"; - -function HeroSection() { - const t = useTranslations('home-page'); - - return ( -
-
-
-
-

{t('hero-section-title')}

-

{t('hero-section-sub-title')}

- {t('hero-section-cta')} -
-
-
-
- ); -} - -export default HeroSection; diff --git a/src/components/home/LocaleSwitcher.tsx b/src/components/home/LocaleSwitcher.tsx deleted file mode 100644 index 7b25b0d..0000000 --- a/src/components/home/LocaleSwitcher.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import { useRouter } from "next/router"; -import { ChangeEvent, useCallback } from "react"; - -export default function LocaleSwitcher() { - const router = useRouter(); - - const { pathname, asPath, query, locale, locales = [] } = router; - const handleChange = useCallback((e: ChangeEvent) => { - router.push({ pathname, query }, asPath, { locale: e.target.value }); - }, [router, pathname, query]); - - return ( -
- 🌎 - -
- ); -} diff --git a/src/components/home/MentorsSection.tsx b/src/components/home/MentorsSection.tsx deleted file mode 100644 index 0e94769..0000000 --- a/src/components/home/MentorsSection.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import React from "react"; -import {useTranslations} from "next-intl"; - -function MentorsSection() { - const t = useTranslations('home-page'); - - return ( -
-
-
-

{t('mentor-section-title')}

-

{t('mentor-section-sub-title')}

-
-
- -
-
- -
-
- -
-
- -
-
-
-
-
- ); -} - -export default MentorsSection; diff --git a/src/components/home/ProgramsSection/ProgramsSection.module.css b/src/components/home/ProgramsSection/ProgramsSection.module.css deleted file mode 100644 index 63e1559..0000000 --- a/src/components/home/ProgramsSection/ProgramsSection.module.css +++ /dev/null @@ -1,20 +0,0 @@ -.program-card-wrapper { - @apply flex-1 mx-2; -} - -.program-card-wrapper:first-child { - @apply ml-0; -} - -.program-card-wrapper:last-child { - @apply mr-0; -} - -.program-card { - border: 1px solid rgba(0, 0, 0, 0); - @apply rounded-lg p-6 transition-all ease-in duration-300 bg-white; -} - -.program-card:hover { - @apply shadow-lg border border-gray-300; -} diff --git a/src/components/home/ProgramsSection/index.tsx b/src/components/home/ProgramsSection/index.tsx deleted file mode 100644 index 1150f30..0000000 --- a/src/components/home/ProgramsSection/index.tsx +++ /dev/null @@ -1,81 +0,0 @@ -import React from 'react'; - -import style from './ProgramsSection.module.css'; - -import { useTranslations } from 'next-intl'; -import { whatsappLink } from 'src/lib/url'; - -function ProgramsSection() { - const t = useTranslations('home-page'); - return ( -
-
-
-
-

- {t('program-section-title')} -

-

- {t('program-section-sub-title')} -

-
-
-
-
-

- {t('program-section-1-title')} -

-

- {t('program-section-1-description')} -

- - {t('program-section-cta')} - -
-
-
-
-

- {t('program-section-2-title')} -

-

- {t('program-section-2-description')} -

- - {t('program-section-cta')} - -
-
-
-
-

- {t('program-section-3-title')} -

-

- {t('program-section-3-description')} -

- - {t('program-section-cta')} - -
-
-
-
-
-
- ); -} - -export default ProgramsSection; diff --git a/src/components/home/TestimonySection/TestimonyCard.tsx b/src/components/home/TestimonySection/TestimonyCard.tsx deleted file mode 100644 index 7710402..0000000 --- a/src/components/home/TestimonySection/TestimonyCard.tsx +++ /dev/null @@ -1,21 +0,0 @@ -import React from 'react'; - -import { ITestimony } from 'src/lib/types'; - -type TestimonyCard = ITestimony; - -function TestimonyCard({ text, name, school = '', title = '' }: TestimonyCard) { - return ( -
-

- - {text} -

-

{name}

- {school &&

{school}

} - {title &&

{title}

} -
- ); -} - -export default TestimonyCard; diff --git a/src/components/home/TestimonySection/index.tsx b/src/components/home/TestimonySection/index.tsx deleted file mode 100644 index 963160b..0000000 --- a/src/components/home/TestimonySection/index.tsx +++ /dev/null @@ -1,58 +0,0 @@ -import React from 'react'; - -import TestimonyCard from './TestimonyCard'; - -import { ITestimony } from 'src/lib/types'; -import { useTranslations } from 'next-intl'; - -function TestimonySection() { - const t = useTranslations('home-page'); - const testimonies: ITestimony[] = [ - { - name: 'Agi', - school: "Universitas Tadulako '17", - text: 'hammercode komunitas nya friendly banget, baik mentor, dan peserta pelajarnya. Kelas di hammercode jg itu sangat seru, metode mengajar para mentornya sangat membntu, dijamin paham 1000%', - }, - { - name: 'Zulnabil', - school: "Universitas Tadulako '16", - title: 'Frontend Engineer @ 99.co', - text: 'As a software engineer or who wants to, prepare yourself to face the real IT industry. Since studying from college is not enough, you have to find your mentor. In hammercode you can find it, and expand your network. Because your network is your net worth', - }, - { - name: 'Akwan', - school: "Universitas Tadulako '19", - title: 'Backend Engineer Intern @ Bareksa', - text: 'Dengan bantuan dan dorongan teman-teman dan mentor yg ada di komunitas, saya berhasil mendapatkan kesempatan magang di tahun pertama dan kedua kuliah', - }, - ]; - return ( -
-
-
-
-

- {t('impact-section-title')} -

-

- {t('impact-section-sub-title')} -

-
-
-
- -
-
- -
-
- -
-
-
-
-
- ); -} - -export default TestimonySection; diff --git a/src/components/layout/MainLayout.tsx b/src/components/layout/MainLayout.tsx deleted file mode 100644 index 2b7e1d1..0000000 --- a/src/components/layout/MainLayout.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import Footer from 'src/components/Footer'; -import Header from 'src/components/Header'; -import React from 'react'; - -export default function MainLayout({ - children, -}: { - children?: React.ReactNode; -}) { - return ( - <> -
- {children} -