diff --git a/.github/workflows/deploy-1000h-portal.yml b/.github/workflows/deploy-1000h-portal.yml new file mode 100644 index 00000000..1ab8daec --- /dev/null +++ b/.github/workflows/deploy-1000h-portal.yml @@ -0,0 +1,47 @@ +name: Deploy 1000h portal + +on: + workflow_dispatch: + push: + branches: + - main + paths: + - "1000h-portal/**" + pull_request: + branches: + - main + paths: + - "1000h-portal/**" + +jobs: + deploy: + runs-on: ubuntu-latest + name: Deploy + steps: + # checkout the code + - uses: actions/checkout@v4 + + - uses: actions/cache@v4 + with: + path: "**/node_modules" + key: ${{ runner.os }}-${{ hashFiles('**/yarn.lock') }} + + - name: Setup node env + uses: actions/setup-node@master + with: + node-version: "20" + + - name: Install dependencies + run: yarn install + + - name: Build + run: yarn generate + + - name: Deploy + uses: cloudflare/wrangler-action@v3 + with: + apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} + accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} + command: deploy + workingDirectory: "1000h-portal" + diff --git a/1000h-portal/.gitignore b/1000h-portal/.gitignore new file mode 100644 index 00000000..e9959059 --- /dev/null +++ b/1000h-portal/.gitignore @@ -0,0 +1,2 @@ +.output/ +dist/ \ No newline at end of file diff --git a/1000h-portal/README.md b/1000h-portal/README.md new file mode 100644 index 00000000..f5db2a2d --- /dev/null +++ b/1000h-portal/README.md @@ -0,0 +1,75 @@ +# Nuxt 3 Minimal Starter + +Look at the [Nuxt 3 documentation](https://nuxt.com/docs/getting-started/introduction) to learn more. + +## Setup + +Make sure to install the dependencies: + +```bash +# npm +npm install + +# pnpm +pnpm install + +# yarn +yarn install + +# bun +bun install +``` + +## Development Server + +Start the development server on `http://localhost:3000`: + +```bash +# npm +npm run dev + +# pnpm +pnpm run dev + +# yarn +yarn dev + +# bun +bun run dev +``` + +## Production + +Build the application for production: + +```bash +# npm +npm run build + +# pnpm +pnpm run build + +# yarn +yarn build + +# bun +bun run build +``` + +Locally preview production build: + +```bash +# npm +npm run preview + +# pnpm +pnpm run preview + +# yarn +yarn preview + +# bun +bun run preview +``` + +Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information. diff --git a/1000h-portal/app.vue b/1000h-portal/app.vue new file mode 100644 index 00000000..f8eacfa7 --- /dev/null +++ b/1000h-portal/app.vue @@ -0,0 +1,5 @@ + diff --git a/1000h-portal/components/Comments.vue b/1000h-portal/components/Comments.vue new file mode 100644 index 00000000..6d1f3b35 --- /dev/null +++ b/1000h-portal/components/Comments.vue @@ -0,0 +1,167 @@ + + + + + + + diff --git a/1000h-portal/components/Features.vue b/1000h-portal/components/Features.vue new file mode 100644 index 00000000..001fd1e2 --- /dev/null +++ b/1000h-portal/components/Features.vue @@ -0,0 +1,153 @@ + + + + + + + diff --git a/1000h-portal/components/Introduction.vue b/1000h-portal/components/Introduction.vue new file mode 100644 index 00000000..9ff996ef --- /dev/null +++ b/1000h-portal/components/Introduction.vue @@ -0,0 +1,169 @@ + + + + + + + diff --git a/1000h-portal/components/Logo.vue b/1000h-portal/components/Logo.vue new file mode 100644 index 00000000..ee903c4e --- /dev/null +++ b/1000h-portal/components/Logo.vue @@ -0,0 +1,35 @@ + + + + + + + diff --git a/1000h-portal/components/Price.vue b/1000h-portal/components/Price.vue new file mode 100644 index 00000000..086aae64 --- /dev/null +++ b/1000h-portal/components/Price.vue @@ -0,0 +1,89 @@ + + + + + + + diff --git a/1000h-portal/components/Slogan.vue b/1000h-portal/components/Slogan.vue new file mode 100644 index 00000000..fdb27799 --- /dev/null +++ b/1000h-portal/components/Slogan.vue @@ -0,0 +1,91 @@ + + + + + + + diff --git a/1000h-portal/components/layout/PageFooter.vue b/1000h-portal/components/layout/PageFooter.vue new file mode 100644 index 00000000..97e2faff --- /dev/null +++ b/1000h-portal/components/layout/PageFooter.vue @@ -0,0 +1,27 @@ + + + + + + + diff --git a/1000h-portal/components/layout/PageHeader.vue b/1000h-portal/components/layout/PageHeader.vue new file mode 100644 index 00000000..d62c84a9 --- /dev/null +++ b/1000h-portal/components/layout/PageHeader.vue @@ -0,0 +1,47 @@ + + + + + + + diff --git a/1000h-portal/layouts/default.vue b/1000h-portal/layouts/default.vue new file mode 100644 index 00000000..482eb4b8 --- /dev/null +++ b/1000h-portal/layouts/default.vue @@ -0,0 +1,20 @@ + + + + + + + diff --git a/1000h-portal/nuxt.config.ts b/1000h-portal/nuxt.config.ts new file mode 100644 index 00000000..d174b847 --- /dev/null +++ b/1000h-portal/nuxt.config.ts @@ -0,0 +1,48 @@ +// https://nuxt.com/docs/api/configuration/nuxt-config +export default defineNuxtConfig({ + devtools: { enabled: true }, + css: ["~/styles/main.css"], + site: { + url: "https://example.com", + name: "Enjoy App", + description: "Welcome to Enjoy App!", + tagline: "", + defaultLocale: "zh", // not needed if you have @nuxtjs/i18n installed + }, + app: { + head: { + viewport: + "width=device-width, initial-scale=1, maximum-scale=1.0, user-scalable=no, viewport-fit=cover", + link: [ + { + rel: "apple-touch-icon", + sizes: "180x180", + href: "/apple-touch-icon.png", + }, + { rel: "mask-icon", href: "/mask-icon.svg" }, + { + rel: "icon", + type: "image/png", + sizes: "24x24", + href: "/favicon-24x24.png", + }, + { + rel: "icon", + type: "image/png", + sizes: "12x12", + href: "favicon-12x12.png", + }, + ], + script: [], + }, + }, + + postcss: { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, + }, + + modules: ["nuxt-og-image", "@nuxtjs/seo"], +}); diff --git a/1000h-portal/package.json b/1000h-portal/package.json new file mode 100644 index 00000000..56322053 --- /dev/null +++ b/1000h-portal/package.json @@ -0,0 +1,24 @@ +{ + "name": "nuxt-app", + "private": true, + "type": "module", + "scripts": { + "build": "nuxt build", + "dev": "nuxt dev", + "generate": "nuxt generate", + "preview": "nuxt preview", + "postinstall": "nuxt prepare" + }, + "dependencies": { + "@nuxtjs/seo": "^2.0.0-rc.11", + "nuxt": "^3.12.2", + "nuxt-og-image": "^2.2.6", + "vue": "^3.4.29", + "vue-router": "^4.3.3" + }, + "devDependencies": { + "autoprefixer": "^10.4.19", + "postcss": "^8.4.38", + "tailwindcss": "^3.4.4" + } +} diff --git a/1000h-portal/pages/index.vue b/1000h-portal/pages/index.vue new file mode 100644 index 00000000..66597f30 --- /dev/null +++ b/1000h-portal/pages/index.vue @@ -0,0 +1,25 @@ + + + + + + + diff --git a/1000h-portal/public/apple-touch-icon.png b/1000h-portal/public/apple-touch-icon.png new file mode 100644 index 00000000..244b3ece Binary files /dev/null and b/1000h-portal/public/apple-touch-icon.png differ diff --git a/1000h-portal/public/favicon-12x12.png b/1000h-portal/public/favicon-12x12.png new file mode 100644 index 00000000..6ca5f3b7 Binary files /dev/null and b/1000h-portal/public/favicon-12x12.png differ diff --git a/1000h-portal/public/favicon-24x24.png b/1000h-portal/public/favicon-24x24.png new file mode 100644 index 00000000..87e9b6d0 Binary files /dev/null and b/1000h-portal/public/favicon-24x24.png differ diff --git a/1000h-portal/public/favicon.ico b/1000h-portal/public/favicon.ico new file mode 100644 index 00000000..8a8a50ee Binary files /dev/null and b/1000h-portal/public/favicon.ico differ diff --git a/1000h-portal/public/fonts/NewYorkItalic.ttf b/1000h-portal/public/fonts/NewYorkItalic.ttf new file mode 100644 index 00000000..695ae221 Binary files /dev/null and b/1000h-portal/public/fonts/NewYorkItalic.ttf differ diff --git a/1000h-portal/public/fonts/NotoSerifSC-Bold.ttf b/1000h-portal/public/fonts/NotoSerifSC-Bold.ttf new file mode 100644 index 00000000..2db03151 Binary files /dev/null and b/1000h-portal/public/fonts/NotoSerifSC-Bold.ttf differ diff --git a/1000h-portal/public/icon/arrow-right.svg b/1000h-portal/public/icon/arrow-right.svg new file mode 100644 index 00000000..8a5f7877 --- /dev/null +++ b/1000h-portal/public/icon/arrow-right.svg @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/1000h-portal/public/icon/arrow-upright.svg b/1000h-portal/public/icon/arrow-upright.svg new file mode 100644 index 00000000..6dd965d8 --- /dev/null +++ b/1000h-portal/public/icon/arrow-upright.svg @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/1000h-portal/public/icon/check.svg b/1000h-portal/public/icon/check.svg new file mode 100644 index 00000000..4b355963 --- /dev/null +++ b/1000h-portal/public/icon/check.svg @@ -0,0 +1,8 @@ + + + + \ No newline at end of file diff --git a/1000h-portal/public/icon/double-quote-2.svg b/1000h-portal/public/icon/double-quote-2.svg new file mode 100644 index 00000000..6676d29c --- /dev/null +++ b/1000h-portal/public/icon/double-quote-2.svg @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/1000h-portal/public/icon/double-quote.svg b/1000h-portal/public/icon/double-quote.svg new file mode 100644 index 00000000..43a12040 --- /dev/null +++ b/1000h-portal/public/icon/double-quote.svg @@ -0,0 +1,5 @@ + + + \ No newline at end of file diff --git a/1000h-portal/public/icon/enjoy-app.svg b/1000h-portal/public/icon/enjoy-app.svg new file mode 100644 index 00000000..d6ad1420 --- /dev/null +++ b/1000h-portal/public/icon/enjoy-app.svg @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/1000h-portal/public/images/app-logo.png b/1000h-portal/public/images/app-logo.png new file mode 100644 index 00000000..e546c8f8 Binary files /dev/null and b/1000h-portal/public/images/app-logo.png differ diff --git a/1000h-portal/public/images/avatar.png b/1000h-portal/public/images/avatar.png new file mode 100644 index 00000000..788d397c Binary files /dev/null and b/1000h-portal/public/images/avatar.png differ diff --git a/1000h-portal/public/images/bg-demo.png b/1000h-portal/public/images/bg-demo.png new file mode 100644 index 00000000..1277c704 Binary files /dev/null and b/1000h-portal/public/images/bg-demo.png differ diff --git a/1000h-portal/public/images/bg-intro-1.png b/1000h-portal/public/images/bg-intro-1.png new file mode 100644 index 00000000..ddd99cf5 Binary files /dev/null and b/1000h-portal/public/images/bg-intro-1.png differ diff --git a/1000h-portal/public/images/bg-intro-2.png b/1000h-portal/public/images/bg-intro-2.png new file mode 100644 index 00000000..1f3ac65f Binary files /dev/null and b/1000h-portal/public/images/bg-intro-2.png differ diff --git a/1000h-portal/public/images/bg-intro-3.png b/1000h-portal/public/images/bg-intro-3.png new file mode 100644 index 00000000..59c598fa Binary files /dev/null and b/1000h-portal/public/images/bg-intro-3.png differ diff --git a/1000h-portal/public/images/bg-intro-4.png b/1000h-portal/public/images/bg-intro-4.png new file mode 100644 index 00000000..05f56740 Binary files /dev/null and b/1000h-portal/public/images/bg-intro-4.png differ diff --git a/1000h-portal/public/images/book.png b/1000h-portal/public/images/book.png new file mode 100644 index 00000000..626b933e Binary files /dev/null and b/1000h-portal/public/images/book.png differ diff --git a/1000h-portal/public/images/camera.png b/1000h-portal/public/images/camera.png new file mode 100644 index 00000000..543d670a Binary files /dev/null and b/1000h-portal/public/images/camera.png differ diff --git a/1000h-portal/public/images/cham.png b/1000h-portal/public/images/cham.png new file mode 100644 index 00000000..0010bb01 Binary files /dev/null and b/1000h-portal/public/images/cham.png differ diff --git a/1000h-portal/public/images/demo.png b/1000h-portal/public/images/demo.png new file mode 100644 index 00000000..e9db978d Binary files /dev/null and b/1000h-portal/public/images/demo.png differ diff --git a/1000h-portal/public/images/head-phone.png b/1000h-portal/public/images/head-phone.png new file mode 100644 index 00000000..e9eaa232 Binary files /dev/null and b/1000h-portal/public/images/head-phone.png differ diff --git a/1000h-portal/public/images/lang.png b/1000h-portal/public/images/lang.png new file mode 100644 index 00000000..1490e443 Binary files /dev/null and b/1000h-portal/public/images/lang.png differ diff --git a/1000h-portal/public/images/note.png b/1000h-portal/public/images/note.png new file mode 100644 index 00000000..e198fd9c Binary files /dev/null and b/1000h-portal/public/images/note.png differ diff --git a/1000h-portal/public/images/og-image.png b/1000h-portal/public/images/og-image.png new file mode 100644 index 00000000..e9db978d Binary files /dev/null and b/1000h-portal/public/images/og-image.png differ diff --git a/1000h-portal/public/images/payment-2.png b/1000h-portal/public/images/payment-2.png new file mode 100644 index 00000000..a471900f Binary files /dev/null and b/1000h-portal/public/images/payment-2.png differ diff --git a/1000h-portal/public/images/payment.png b/1000h-portal/public/images/payment.png new file mode 100644 index 00000000..f773db55 Binary files /dev/null and b/1000h-portal/public/images/payment.png differ diff --git a/1000h-portal/public/images/robot.png b/1000h-portal/public/images/robot.png new file mode 100644 index 00000000..2de43fc4 Binary files /dev/null and b/1000h-portal/public/images/robot.png differ diff --git a/1000h-portal/server/tsconfig.json b/1000h-portal/server/tsconfig.json new file mode 100644 index 00000000..b9ed69c1 --- /dev/null +++ b/1000h-portal/server/tsconfig.json @@ -0,0 +1,3 @@ +{ + "extends": "../.nuxt/tsconfig.server.json" +} diff --git a/1000h-portal/styles/font.css b/1000h-portal/styles/font.css new file mode 100644 index 00000000..7b3110f6 --- /dev/null +++ b/1000h-portal/styles/font.css @@ -0,0 +1,17 @@ +@font-face { + font-family: "Noto Serif SC"; + font-display: swap; + src: url("/fonts/NotoSerifSC-Bold.ttf") format("truetype"); +} + +@font-face { + font-family: "New York"; + font-display: swap; + src: url("/fonts/NewYorkItalic.ttf") format("truetype"); +} + + +body { + font-family: PingFang SC, -apple-system, BlinkMacSystemFont, sans-serif, Arial, Helvetica; + font-weight: 400; +} \ No newline at end of file diff --git a/1000h-portal/styles/main.css b/1000h-portal/styles/main.css new file mode 100644 index 00000000..8bde9235 --- /dev/null +++ b/1000h-portal/styles/main.css @@ -0,0 +1,5 @@ +@import "./font.css"; + +@tailwind base; +@tailwind components; +@tailwind utilities; diff --git a/1000h-portal/tailwind.config.js b/1000h-portal/tailwind.config.js new file mode 100644 index 00000000..1670ec35 --- /dev/null +++ b/1000h-portal/tailwind.config.js @@ -0,0 +1,27 @@ +/** @type {import('tailwindcss').Config} */ +export default { + content: [ + "./components/**/*.{js,vue,ts}", + "./layouts/**/*.vue", + "./pages/**/*.vue", + "./plugins/**/*.{js,ts}", + "./app.vue", + "./error.vue", + ], + theme: { + container: { + padding: "1rem", + }, + colors: { + white: "#ffffff", + primary: "#4797F5", + greyscale_1: "#0D0D0D", + greyscale_2: "#212121", + greyscale_3: "#252525", + greyscale_4: "#8D8D8D", + greyscale_5: "#d7d7d7", + }, + extend: {}, + }, + plugins: [], +}; diff --git a/1000h-portal/tsconfig.json b/1000h-portal/tsconfig.json new file mode 100644 index 00000000..a746f2a7 --- /dev/null +++ b/1000h-portal/tsconfig.json @@ -0,0 +1,4 @@ +{ + // https://nuxt.com/docs/guide/concepts/typescript + "extends": "./.nuxt/tsconfig.json" +} diff --git a/1000h-portal/workers-site/.cargo-ok b/1000h-portal/workers-site/.cargo-ok new file mode 100644 index 00000000..e69de29b diff --git a/1000h-portal/workers-site/.gitignore b/1000h-portal/workers-site/.gitignore new file mode 100644 index 00000000..75c573a4 --- /dev/null +++ b/1000h-portal/workers-site/.gitignore @@ -0,0 +1,2 @@ +node_modules +worker diff --git a/1000h-portal/workers-site/index.js b/1000h-portal/workers-site/index.js new file mode 100644 index 00000000..9b0d4095 --- /dev/null +++ b/1000h-portal/workers-site/index.js @@ -0,0 +1,142 @@ +import { getAssetFromKV, mapRequestToAsset } from '@cloudflare/kv-asset-handler' + +/** + * The DEBUG flag will do two things that help during development: + * 1. we will skip caching on the edge, which makes it easier to + * debug. + * 2. we will return an error message on exception in your Response rather + * than the default 404.html page. + */ +const DEBUG = true + +addEventListener('fetch', event => { + try { + event.respondWith(handleEvent(event)) + } catch (e) { + if (DEBUG) { + return event.respondWith( + new Response(e.message || e.toString(), { + status: 500, + }), + ) + } + event.respondWith(new Response('Internal Error', { status: 500 })) + } +}) + +async function handleEvent(event) { + // const url = new URL(event.request.url) + let options = {} + + // const key = url.pathname.slice(1); + // if (event.request.method === 'GET' && key.startsWith("storage/")) { + // const object = await STORAGE_BUCKET.get(key); + + // if (object === null) { + // event.respondWith(Response('Object Not Found', { status: 404 })); + // return + // } + + // const headers = new Headers(); + // object.writeHttpMetadata(headers); + // headers.set('etag', object.httpEtag); + + // event.respondWith(new Response(object.body, { + // headers, + // })); + // return ; + // } + + /** + * You can add custom logic to how we fetch your assets + * by configuring the function `mapRequestToAsset` + */ + // options.mapRequestToAsset = handlePrefix(/^\/docs/) + + try { + if (DEBUG) { + // customize caching + options.cacheControl = { + bypassCache: true, + }; + } + + // no extension and not end with '/', redirect to the same path with '/' + if (!event.request.url.endsWith("/")) { + if (!event.request.url.split("/").pop().includes(".")) { + return Response.redirect(`${event.request.url}/`, 301); + } + } + + const page = await getAssetFromKV(event, options); + + // allow headers to be altered + const response = new Response(page.body, page); + + response.headers.set("X-XSS-Protection", "1; mode=block"); + response.headers.set("X-Content-Type-Options", "nosniff"); + response.headers.set("X-Frame-Options", "DENY"); + response.headers.set("Referrer-Policy", "unsafe-url"); + response.headers.set("Feature-Policy", "none"); + + return response; + + } catch (e) { + // if an error is thrown try to serve the asset at 404.html + // if (!DEBUG) { + // try { + // let notFoundResponse = await getAssetFromKV(event, { + // mapRequestToAsset: req => new Request(`${new URL(req.url).origin}/404.html`, req), + // }) + + // return new Response(notFoundResponse.body, { ...notFoundResponse, status: 404 }) + // } catch (e) {} + // } + return getAssetFromKV(event, { + mapRequestToAsset: (req) => { + const url = new URL(req.url); + let pathname = url.pathname; + + if (pathname.startsWith("/tools/")) { + // remove the '/tools' prefix + pathname = pathname.substring(6); + } + + // If the pathname ends with '/', assume it's a directory and append 'index.html' + if (pathname.endsWith('/')) { + pathname += 'index.html'; + } + + // If it doesn't have an extension, assume it's a directory and append '/index.html' + else if (!pathname.split("/").pop().includes(".")) { + pathname += '/index.html'; + } + + return new Request(`${url.origin}${pathname}`, req); + }, + }) + + // return new Response(e.message || e.toString(), { status: 500 }) + } +} + +/** + * Here's one example of how to modify a request to + * remove a specific prefix, in this case `/docs` from + * the url. This can be useful if you are deploying to a + * route on a zone, or if you only want your static content + * to exist at a specific path. + */ +function handlePrefix(prefix) { + return request => { + // compute the default (e.g. / -> index.html) + let defaultAssetKey = mapRequestToAsset(request) + let url = new URL(defaultAssetKey.url) + + // strip the prefix from the path for lookup + url.pathname = url.pathname.replace(prefix, '/') + + // inherit all other props from the default request + return new Request(url.toString(), defaultAssetKey) + } +} \ No newline at end of file diff --git a/1000h-portal/workers-site/package.json b/1000h-portal/workers-site/package.json new file mode 100644 index 00000000..d298f1bc --- /dev/null +++ b/1000h-portal/workers-site/package.json @@ -0,0 +1,12 @@ +{ + "private": true, + "name": "worker", + "version": "1.0.0", + "description": "A template for kick starting a Cloudflare Workers project", + "main": "index.js", + "author": "Ashley Lewis ", + "license": "MIT", + "dependencies": { + "@cloudflare/kv-asset-handler": "~0.1.2" + } +} diff --git a/1000h-portal/wrangler.toml b/1000h-portal/wrangler.toml new file mode 100644 index 00000000..739c3937 --- /dev/null +++ b/1000h-portal/wrangler.toml @@ -0,0 +1,5 @@ +name = "1000h-portal" +main = "index.js" +workers_dev = false +compatibility_date = "2023-03-23" +