├── .husky ├── .gitignore └── pre-commit ├── apps ├── app │ ├── components │ │ ├── index.ts │ │ ├── Filetree │ │ │ └── branch.tsx │ │ └── Layout │ │ │ └── index.tsx │ ├── postcss.config.js │ ├── tailwind.config.js │ ├── .eslintrc.js │ ├── public │ │ ├── favicon.ico │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ └── static │ │ │ └── images │ │ │ ├── logo.png │ │ │ ├── jata_192.png │ │ │ ├── jata_512.png │ │ │ ├── og_en-GB.png │ │ │ ├── og_ms-MY.png │ │ │ ├── icons │ │ │ ├── csv.png │ │ │ ├── json.png │ │ │ ├── geojson.png │ │ │ ├── parquet.png │ │ │ ├── marker-red.png │ │ │ ├── icon-512x512.png │ │ │ ├── marker-icon.png │ │ │ ├── favicon-16x16.png │ │ │ ├── favicon-32x32.png │ │ │ ├── marker-icon-2x.png │ │ │ ├── marker-red-2x.png │ │ │ ├── marker-shadow.png │ │ │ ├── touch-icon-ipad.png │ │ │ ├── apple_splash_1125.png │ │ │ ├── apple_splash_1242.png │ │ │ ├── apple_splash_1536.png │ │ │ ├── apple_splash_1668.png │ │ │ ├── apple_splash_2048.png │ │ │ ├── apple_splash_640.png │ │ │ ├── apple_splash_750.png │ │ │ ├── touch-icon-iphone.png │ │ │ ├── android-chrome-192x192.png │ │ │ ├── android-chrome-384x384.png │ │ │ ├── android-chrome-512x512.png │ │ │ ├── touch-icon-ipad-retina.png │ │ │ └── touch-icon-iphone-retina.png │ │ │ ├── jata_logo.png │ │ │ ├── states │ │ │ ├── jhr.jpeg │ │ │ ├── kdh.jpeg │ │ │ ├── ktn.jpeg │ │ │ ├── kul.jpeg │ │ │ ├── kvy.jpeg │ │ │ ├── lbn.jpeg │ │ │ ├── mlk.jpeg │ │ │ ├── mys.jpeg │ │ │ ├── nsn.jpeg │ │ │ ├── phg.jpeg │ │ │ ├── pjy.jpeg │ │ │ ├── pls.jpeg │ │ │ ├── png.jpeg │ │ │ ├── prk.jpeg │ │ │ ├── sbh.jpeg │ │ │ ├── sgr.jpeg │ │ │ ├── swk.jpeg │ │ │ ├── trg.jpeg │ │ │ ├── wp.jpeg │ │ │ └── Overseas.jpeg │ │ │ ├── github-mark.svg │ │ │ └── github-mark-white.svg │ ├── templates │ │ ├── dashboard-translation.json.hbs │ │ └── dashboard-component.tsx.hbs │ ├── next-env.d.ts │ ├── lib │ │ ├── events.ts │ │ └── dts │ │ │ └── mixpanel.d.ts │ ├── next-sitemap.config.js │ ├── pages │ │ ├── gui │ │ │ └── index.tsx │ │ ├── api │ │ │ ├── data-catalogue │ │ │ │ └── fetch-category.ts │ │ │ └── embed.ts │ │ ├── datagpt.tsx │ │ ├── community │ │ │ └── index.tsx │ │ ├── helpdesk │ │ │ └── index.tsx │ │ ├── _offline.tsx │ │ └── 500.tsx │ ├── tsconfig.json │ ├── script │ │ ├── assets │ │ │ └── icons │ │ │ │ ├── MERS.svg │ │ │ │ ├── MOH.svg │ │ │ │ ├── PHCorp.svg │ │ │ │ ├── PDN.svg │ │ │ │ ├── JPN.svg │ │ │ │ ├── BOMBA.svg │ │ │ │ ├── MOT.svg │ │ │ │ └── SOCSO.svg │ │ └── feature_extract.js │ ├── types │ │ └── next-auth.d.ts │ ├── .env.example │ └── dashboards │ │ ├── public-safety │ │ └── crime │ │ │ └── index.tsx │ │ ├── environment │ │ └── flood-warning │ │ │ └── index.tsx │ │ ├── demography │ │ ├── circle-of-life │ │ │ └── index.tsx │ │ └── name-popularity │ │ │ └── coming_soon.tsx │ │ ├── economy │ │ └── public-pension │ │ │ └── index.tsx │ │ ├── public-finances │ │ └── public-contracting │ │ │ └── index.tsx │ │ └── digitalisation │ │ └── government-site-tracker │ │ └── index.tsx ├── dc-dev │ ├── components │ │ ├── index.ts │ │ └── Layout │ │ │ ├── index.tsx │ │ │ └── Header.tsx │ ├── postcss.config.js │ ├── tailwind.config.js │ ├── .eslintrc.js │ ├── lib │ │ ├── routes.ts │ │ └── dts │ │ │ └── mixpanel.d.ts │ ├── public │ │ ├── favicon.ico │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ └── static │ │ │ └── images │ │ │ ├── logo.png │ │ │ ├── jata_192.png │ │ │ ├── jata_512.png │ │ │ ├── og_en-GB.png │ │ │ ├── og_ms-MY.png │ │ │ ├── icons │ │ │ ├── csv.png │ │ │ ├── json.png │ │ │ ├── geojson.png │ │ │ ├── parquet.png │ │ │ ├── icon-512x512.png │ │ │ ├── marker-icon.png │ │ │ ├── marker-red.png │ │ │ ├── favicon-16x16.png │ │ │ ├── favicon-32x32.png │ │ │ ├── marker-icon-2x.png │ │ │ ├── marker-red-2x.png │ │ │ ├── marker-shadow.png │ │ │ ├── apple_splash_1125.png │ │ │ ├── apple_splash_1242.png │ │ │ ├── apple_splash_1536.png │ │ │ ├── apple_splash_1668.png │ │ │ ├── apple_splash_2048.png │ │ │ ├── apple_splash_640.png │ │ │ ├── apple_splash_750.png │ │ │ ├── touch-icon-ipad.png │ │ │ ├── touch-icon-iphone.png │ │ │ ├── android-chrome-192x192.png │ │ │ ├── android-chrome-384x384.png │ │ │ ├── android-chrome-512x512.png │ │ │ ├── touch-icon-ipad-retina.png │ │ │ └── touch-icon-iphone-retina.png │ │ │ └── jata_logo.png │ ├── next-env.d.ts │ ├── next-i18next.config.js │ ├── next-sitemap.config.js │ ├── .env.example │ ├── tsconfig.json │ ├── middleware.ts │ ├── pages │ │ ├── _offline.tsx │ │ ├── _app.tsx │ │ ├── api │ │ │ └── embed.ts │ │ └── 500.tsx │ └── index.d.ts └── docs │ ├── templates │ ├── _meta.json.hbs │ └── docs.mdx.hbs │ ├── public │ ├── favicon.ico │ └── assets │ │ ├── logo.png │ │ ├── og_en.png │ │ ├── og_ms.png │ │ ├── jata_logo.png │ │ ├── apple_splash_1125.png │ │ ├── apple_splash_1242.png │ │ ├── apple_splash_1536.png │ │ ├── apple_splash_1668.png │ │ ├── apple_splash_2048.png │ │ ├── apple_splash_640.png │ │ └── apple_splash_750.png │ ├── pages │ ├── static-api │ │ ├── _meta.en.json │ │ └── _meta.ms.json │ ├── realtime-api │ │ ├── _meta.en.json │ │ └── _meta.ms.json │ ├── _meta.en.json │ ├── _meta.ms.json │ ├── authentication.en.mdx │ ├── faq.en.mdx │ ├── faq.ms.mdx │ ├── authentication.ms.mdx │ └── rate-limit.en.mdx │ ├── next-env.d.ts │ ├── lib │ └── dts │ │ └── mixpanel.d.ts │ ├── index.d.ts │ ├── tsconfig.json │ ├── .env.example │ ├── next-sitemap.config.js │ ├── package.json │ ├── README.md │ └── next.config.js ├── lambda └── roll_auth_token │ ├── .env.example │ └── package.json ├── packages ├── datagovmy-ui │ ├── types │ │ ├── misc.d.ts │ │ ├── components.d.ts │ │ ├── helpers.d.ts │ │ ├── constants.d.ts │ │ ├── decorators.d.ts │ │ ├── i18n.d.ts │ │ └── hooks.d.ts │ ├── postcss.config.cjs │ ├── src │ │ ├── misc │ │ │ └── index.tsx │ │ ├── charts │ │ │ ├── partials │ │ │ │ ├── types.ts │ │ │ │ ├── geojson.tsx │ │ │ │ ├── geochoropleth.tsx │ │ │ │ ├── choropleth.tsx │ │ │ │ ├── mapplot.tsx │ │ │ │ └── heatmap.tsx │ │ │ ├── donut-meter.tsx │ │ │ └── chart-header.tsx │ │ ├── lib │ │ │ ├── dts │ │ │ │ ├── mixpanel.d.ts │ │ │ │ └── leaflet.d.ts │ │ │ ├── api-edge.ts │ │ │ ├── geojson │ │ │ │ ├── dun │ │ │ │ │ ├── n.31_batu_lancang.ts │ │ │ │ │ ├── n.09_kota_lama.ts │ │ │ │ │ ├── n.29_datok_keramat.ts │ │ │ │ │ ├── n.09_bagan_dalam.ts │ │ │ │ │ ├── n.20_kota_laksamana.ts │ │ │ │ │ ├── n.25_pulau_tikus.ts │ │ │ │ │ ├── n.27_pengkalan_kota.ts │ │ │ │ │ ├── n.04_sekinchan.ts │ │ │ │ │ ├── n.10_bunut_payong.ts │ │ │ │ │ ├── n.16_perai.ts │ │ │ │ │ ├── n.28_komtar.ts │ │ │ │ │ ├── n.08_bagan_jermal.ts │ │ │ │ │ ├── n.26_padang_kota.ts │ │ │ │ │ ├── n.09_padungan.ts │ │ │ │ │ ├── n.33_air_itam.ts │ │ │ │ │ ├── n.47_kempas.ts │ │ │ │ │ ├── n.45_stulang.ts │ │ │ │ │ ├── n.27_pasir_pinji.ts │ │ │ │ │ ├── n.32_menglembu.ts │ │ │ │ │ ├── n.74_pujut.ts │ │ │ │ │ ├── n.35_kampung_tunku.ts │ │ │ │ │ └── n.30_buntong.ts │ │ │ │ ├── parlimen │ │ │ │ │ ├── p.049_tanjong.ts │ │ │ │ │ └── p.050_jelutong.ts │ │ │ │ └── state │ │ │ │ │ └── index.ts │ │ │ └── mixpanel.ts │ │ ├── configs │ │ │ ├── mixpanel.ts │ │ │ └── font.ts │ │ ├── components │ │ │ ├── Markdown │ │ │ │ └── index.tsx │ │ │ ├── Spinner │ │ │ │ └── index.tsx │ │ │ ├── Label │ │ │ │ └── index.tsx │ │ │ ├── Card │ │ │ │ └── index.tsx │ │ │ ├── Container │ │ │ │ └── index.tsx │ │ │ ├── Skeleton │ │ │ │ └── index.tsx │ │ │ ├── Toast │ │ │ │ └── index.tsx │ │ │ ├── Banner │ │ │ │ └── index.tsx │ │ │ ├── LeftRightCard │ │ │ │ └── index.tsx │ │ │ ├── Layout │ │ │ │ └── Header.tsx │ │ │ ├── Textarea │ │ │ │ └── index.tsx │ │ │ └── Callout │ │ │ │ └── index.tsx │ │ ├── hooks │ │ │ ├── useCache.ts │ │ │ ├── useLanguage.ts │ │ │ ├── useLocalStorage.ts │ │ │ ├── useTranslation.ts │ │ │ ├── useWatch.ts │ │ │ ├── useSessionStorage.ts │ │ │ ├── useSlice.ts │ │ │ ├── index.ts │ │ │ ├── useScrollIntersect.ts │ │ │ ├── useAnalytics.ts │ │ │ └── useExport.ts │ │ ├── data-catalogue │ │ │ └── index.ts │ │ ├── contexts │ │ │ └── slider.tsx │ │ ├── styles │ │ │ └── markdown.css │ │ └── i18n │ │ │ └── index.cjs │ ├── tailwind.config.cjs │ ├── tsconfig.node.json │ ├── .eslintrc.js │ ├── tsconfig.json │ ├── README.md │ ├── script │ │ ├── assets │ │ │ └── icons │ │ │ │ ├── MERS.svg │ │ │ │ ├── MOH.svg │ │ │ │ ├── PHCorp.svg │ │ │ │ ├── PDN.svg │ │ │ │ ├── JPN.svg │ │ │ │ ├── BOMBA.svg │ │ │ │ └── MOT.svg │ │ ├── barrel_geojson.js │ │ └── feature_extract.js │ └── index.d.ts ├── tsconfig │ ├── README.md │ ├── postcss.js │ ├── playwright.json │ ├── react-library.json │ ├── package.json │ ├── base.json │ └── nextjs.json ├── datagovmy-nextra │ ├── src │ │ ├── env.d.ts │ │ ├── utils │ │ │ ├── index.ts │ │ │ ├── use-git-edit-url.ts │ │ │ ├── render.tsx │ │ │ └── get-git-issue-url.ts │ │ ├── components │ │ │ ├── table.tsx │ │ │ ├── td.tsx │ │ │ ├── th.tsx │ │ │ ├── tr.tsx │ │ │ ├── steps.tsx │ │ │ ├── bleed.tsx │ │ │ ├── code.tsx │ │ │ ├── not-found.tsx │ │ │ ├── index.ts │ │ │ ├── server-side-error.tsx │ │ │ ├── highlight-matches.tsx │ │ │ ├── input.tsx │ │ │ └── text-area.tsx │ │ ├── contexts │ │ │ ├── index.ts │ │ │ ├── details.ts │ │ │ └── menu.ts │ │ ├── polyfill.ts │ │ └── types.ts │ ├── README.md │ ├── postcss.config.js │ ├── tsup.config.ts │ ├── tsconfig.json │ ├── css │ │ ├── anchor.css │ │ ├── typesetting-article.css │ │ ├── ai.css │ │ ├── hamburger.css │ │ └── scrollbar.css │ ├── vite.config.ts │ └── LICENSE └── eslint-config-datagovmy │ ├── package.json │ └── index.js ├── prettier.config.js ├── .prettierignore ├── vercel.json ├── package.json ├── .gitignore ├── LICENSE.md └── turbo.json /.husky/.gitignore: -------------------------------------------------------------------------------- 1 | _ 2 | -------------------------------------------------------------------------------- /apps/app/components/index.ts: -------------------------------------------------------------------------------- 1 | export { default as Layout } from "./Layout"; 2 | -------------------------------------------------------------------------------- /apps/app/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = require("tsconfig/postcss"); 2 | -------------------------------------------------------------------------------- /lambda/roll_auth_token/.env.example: -------------------------------------------------------------------------------- 1 | EDGE_CONFIG_URL= 2 | VERCEL_ACCESS_TOKEN= -------------------------------------------------------------------------------- /apps/app/tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = require("tsconfig/tailwindcss"); 2 | -------------------------------------------------------------------------------- /apps/dc-dev/components/index.ts: -------------------------------------------------------------------------------- 1 | export { default as Layout } from "./Layout"; 2 | -------------------------------------------------------------------------------- /apps/dc-dev/postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = require("tsconfig/postcss"); 2 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/types/misc.d.ts: -------------------------------------------------------------------------------- 1 | export * from "datagovmy-ui/src/misc"; 2 | -------------------------------------------------------------------------------- /apps/dc-dev/tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = require("tsconfig/tailwindcss"); 2 | -------------------------------------------------------------------------------- /.husky/pre-commit: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | . "$(dirname "$0")/_/husky.sh" 3 | 4 | npx lint-staged 5 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/postcss.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = require("tsconfig/postcss"); 2 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/types/components.d.ts: -------------------------------------------------------------------------------- 1 | export * from "datagovmy-ui/src/components"; 2 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/types/helpers.d.ts: -------------------------------------------------------------------------------- 1 | export * from "datagovmy-ui/src/lib/helpers"; 2 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/misc/index.tsx: -------------------------------------------------------------------------------- 1 | export { default as OdinDashboard } from "./odin"; 2 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/tailwind.config.cjs: -------------------------------------------------------------------------------- 1 | module.exports = require("tsconfig/tailwindcss"); 2 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/types/constants.d.ts: -------------------------------------------------------------------------------- 1 | export * from "datagovmy-ui/src/lib/constants"; 2 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/types/decorators.d.ts: -------------------------------------------------------------------------------- 1 | export * from "datagovmy-ui/src/lib/decorators"; 2 | -------------------------------------------------------------------------------- /apps/app/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: ["datagovmy"], 4 | }; 5 | -------------------------------------------------------------------------------- /apps/dc-dev/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: ["datagovmy"], 4 | }; 5 | -------------------------------------------------------------------------------- /apps/docs/templates/_meta.json.hbs: -------------------------------------------------------------------------------- 1 | { 2 | "{{ dashCase docs_name }}": "{{ titleCase docs_name }}" 3 | } 4 | -------------------------------------------------------------------------------- /apps/app/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/favicon.ico -------------------------------------------------------------------------------- /apps/dc-dev/lib/routes.ts: -------------------------------------------------------------------------------- 1 | export const routes = { 2 | HOME: "/", 3 | DATA_CATALOGUE: "/data-catalogue", 4 | }; 5 | -------------------------------------------------------------------------------- /apps/dc-dev/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/dc-dev/public/favicon.ico -------------------------------------------------------------------------------- /apps/docs/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/docs/public/favicon.ico -------------------------------------------------------------------------------- /apps/docs/public/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/docs/public/assets/logo.png -------------------------------------------------------------------------------- /apps/app/public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/favicon-16x16.png -------------------------------------------------------------------------------- /apps/app/public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/favicon-32x32.png -------------------------------------------------------------------------------- /apps/docs/pages/static-api/_meta.en.json: -------------------------------------------------------------------------------- 1 | { 2 | "data-catalogue": "Data Catalogue API", 3 | "opendosm": "OpenDOSM API" 4 | } 5 | -------------------------------------------------------------------------------- /apps/docs/pages/static-api/_meta.ms.json: -------------------------------------------------------------------------------- 1 | { 2 | "data-catalogue": "API Katalog Data", 3 | "opendosm": "API OpenDOSM" 4 | } 5 | -------------------------------------------------------------------------------- /apps/docs/public/assets/og_en.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/docs/public/assets/og_en.png -------------------------------------------------------------------------------- /apps/docs/public/assets/og_ms.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/docs/public/assets/og_ms.png -------------------------------------------------------------------------------- /apps/dc-dev/public/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/dc-dev/public/favicon-16x16.png -------------------------------------------------------------------------------- /apps/dc-dev/public/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/dc-dev/public/favicon-32x32.png -------------------------------------------------------------------------------- /apps/docs/public/assets/jata_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/docs/public/assets/jata_logo.png -------------------------------------------------------------------------------- /apps/app/public/static/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/logo.png -------------------------------------------------------------------------------- /apps/app/public/static/images/jata_192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/jata_192.png -------------------------------------------------------------------------------- /apps/app/public/static/images/jata_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/jata_512.png -------------------------------------------------------------------------------- /apps/app/public/static/images/og_en-GB.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/og_en-GB.png -------------------------------------------------------------------------------- /apps/app/public/static/images/og_ms-MY.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/og_ms-MY.png -------------------------------------------------------------------------------- /apps/dc-dev/public/static/images/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/dc-dev/public/static/images/logo.png -------------------------------------------------------------------------------- /packages/tsconfig/README.md: -------------------------------------------------------------------------------- 1 | # `tsconfig` 2 | 3 | These are base shared `tsconfig.json`s from which all other `tsconfig.json`'s inherit from. 4 | -------------------------------------------------------------------------------- /apps/app/public/static/images/icons/csv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/icons/csv.png -------------------------------------------------------------------------------- /apps/app/public/static/images/icons/json.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/icons/json.png -------------------------------------------------------------------------------- /apps/app/public/static/images/jata_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/jata_logo.png -------------------------------------------------------------------------------- /apps/app/public/static/images/states/jhr.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/states/jhr.jpeg -------------------------------------------------------------------------------- /apps/app/public/static/images/states/kdh.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/states/kdh.jpeg -------------------------------------------------------------------------------- /apps/app/public/static/images/states/ktn.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/states/ktn.jpeg -------------------------------------------------------------------------------- /apps/app/public/static/images/states/kul.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/states/kul.jpeg -------------------------------------------------------------------------------- /apps/app/public/static/images/states/kvy.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/states/kvy.jpeg -------------------------------------------------------------------------------- /apps/app/public/static/images/states/lbn.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/states/lbn.jpeg -------------------------------------------------------------------------------- /apps/app/public/static/images/states/mlk.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/states/mlk.jpeg -------------------------------------------------------------------------------- /apps/app/public/static/images/states/mys.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/states/mys.jpeg -------------------------------------------------------------------------------- /apps/app/public/static/images/states/nsn.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/states/nsn.jpeg -------------------------------------------------------------------------------- /apps/app/public/static/images/states/phg.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/states/phg.jpeg -------------------------------------------------------------------------------- /apps/app/public/static/images/states/pjy.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/states/pjy.jpeg -------------------------------------------------------------------------------- /apps/app/public/static/images/states/pls.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/states/pls.jpeg -------------------------------------------------------------------------------- /apps/app/public/static/images/states/png.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/states/png.jpeg -------------------------------------------------------------------------------- /apps/app/public/static/images/states/prk.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/states/prk.jpeg -------------------------------------------------------------------------------- /apps/app/public/static/images/states/sbh.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/states/sbh.jpeg -------------------------------------------------------------------------------- /apps/app/public/static/images/states/sgr.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/states/sgr.jpeg -------------------------------------------------------------------------------- /apps/app/public/static/images/states/swk.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/states/swk.jpeg -------------------------------------------------------------------------------- /apps/app/public/static/images/states/trg.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/states/trg.jpeg -------------------------------------------------------------------------------- /apps/app/public/static/images/states/wp.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/states/wp.jpeg -------------------------------------------------------------------------------- /apps/dc-dev/public/static/images/jata_192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/dc-dev/public/static/images/jata_192.png -------------------------------------------------------------------------------- /apps/dc-dev/public/static/images/jata_512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/dc-dev/public/static/images/jata_512.png -------------------------------------------------------------------------------- /apps/dc-dev/public/static/images/og_en-GB.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/dc-dev/public/static/images/og_en-GB.png -------------------------------------------------------------------------------- /apps/dc-dev/public/static/images/og_ms-MY.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/dc-dev/public/static/images/og_ms-MY.png -------------------------------------------------------------------------------- /apps/docs/public/assets/apple_splash_1125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/docs/public/assets/apple_splash_1125.png -------------------------------------------------------------------------------- /apps/docs/public/assets/apple_splash_1242.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/docs/public/assets/apple_splash_1242.png -------------------------------------------------------------------------------- /apps/docs/public/assets/apple_splash_1536.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/docs/public/assets/apple_splash_1536.png -------------------------------------------------------------------------------- /apps/docs/public/assets/apple_splash_1668.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/docs/public/assets/apple_splash_1668.png -------------------------------------------------------------------------------- /apps/docs/public/assets/apple_splash_2048.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/docs/public/assets/apple_splash_2048.png -------------------------------------------------------------------------------- /apps/docs/public/assets/apple_splash_640.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/docs/public/assets/apple_splash_640.png -------------------------------------------------------------------------------- /apps/docs/public/assets/apple_splash_750.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/docs/public/assets/apple_splash_750.png -------------------------------------------------------------------------------- /apps/app/public/static/images/icons/geojson.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/icons/geojson.png -------------------------------------------------------------------------------- /apps/app/public/static/images/icons/parquet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/icons/parquet.png -------------------------------------------------------------------------------- /apps/dc-dev/public/static/images/icons/csv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/dc-dev/public/static/images/icons/csv.png -------------------------------------------------------------------------------- /apps/dc-dev/public/static/images/icons/json.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/dc-dev/public/static/images/icons/json.png -------------------------------------------------------------------------------- /apps/dc-dev/public/static/images/jata_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/dc-dev/public/static/images/jata_logo.png -------------------------------------------------------------------------------- /apps/app/public/static/images/icons/marker-red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/icons/marker-red.png -------------------------------------------------------------------------------- /apps/app/public/static/images/states/Overseas.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/states/Overseas.jpeg -------------------------------------------------------------------------------- /apps/dc-dev/public/static/images/icons/geojson.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/dc-dev/public/static/images/icons/geojson.png -------------------------------------------------------------------------------- /apps/dc-dev/public/static/images/icons/parquet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/dc-dev/public/static/images/icons/parquet.png -------------------------------------------------------------------------------- /apps/app/public/static/images/icons/icon-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/icons/icon-512x512.png -------------------------------------------------------------------------------- /apps/app/public/static/images/icons/marker-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/icons/marker-icon.png -------------------------------------------------------------------------------- /apps/app/public/static/images/icons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/icons/favicon-16x16.png -------------------------------------------------------------------------------- /apps/app/public/static/images/icons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/icons/favicon-32x32.png -------------------------------------------------------------------------------- /apps/app/public/static/images/icons/marker-icon-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/icons/marker-icon-2x.png -------------------------------------------------------------------------------- /apps/app/public/static/images/icons/marker-red-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/icons/marker-red-2x.png -------------------------------------------------------------------------------- /apps/app/public/static/images/icons/marker-shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/icons/marker-shadow.png -------------------------------------------------------------------------------- /apps/app/public/static/images/icons/touch-icon-ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/icons/touch-icon-ipad.png -------------------------------------------------------------------------------- /apps/dc-dev/public/static/images/icons/icon-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/dc-dev/public/static/images/icons/icon-512x512.png -------------------------------------------------------------------------------- /apps/dc-dev/public/static/images/icons/marker-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/dc-dev/public/static/images/icons/marker-icon.png -------------------------------------------------------------------------------- /apps/dc-dev/public/static/images/icons/marker-red.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/dc-dev/public/static/images/icons/marker-red.png -------------------------------------------------------------------------------- /apps/app/public/static/images/icons/apple_splash_1125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/icons/apple_splash_1125.png -------------------------------------------------------------------------------- /apps/app/public/static/images/icons/apple_splash_1242.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/icons/apple_splash_1242.png -------------------------------------------------------------------------------- /apps/app/public/static/images/icons/apple_splash_1536.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/icons/apple_splash_1536.png -------------------------------------------------------------------------------- /apps/app/public/static/images/icons/apple_splash_1668.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/icons/apple_splash_1668.png -------------------------------------------------------------------------------- /apps/app/public/static/images/icons/apple_splash_2048.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/icons/apple_splash_2048.png -------------------------------------------------------------------------------- /apps/app/public/static/images/icons/apple_splash_640.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/icons/apple_splash_640.png -------------------------------------------------------------------------------- /apps/app/public/static/images/icons/apple_splash_750.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/icons/apple_splash_750.png -------------------------------------------------------------------------------- /apps/app/public/static/images/icons/touch-icon-iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/icons/touch-icon-iphone.png -------------------------------------------------------------------------------- /apps/dc-dev/public/static/images/icons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/dc-dev/public/static/images/icons/favicon-16x16.png -------------------------------------------------------------------------------- /apps/dc-dev/public/static/images/icons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/dc-dev/public/static/images/icons/favicon-32x32.png -------------------------------------------------------------------------------- /apps/dc-dev/public/static/images/icons/marker-icon-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/dc-dev/public/static/images/icons/marker-icon-2x.png -------------------------------------------------------------------------------- /apps/dc-dev/public/static/images/icons/marker-red-2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/dc-dev/public/static/images/icons/marker-red-2x.png -------------------------------------------------------------------------------- /apps/dc-dev/public/static/images/icons/marker-shadow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/dc-dev/public/static/images/icons/marker-shadow.png -------------------------------------------------------------------------------- /apps/dc-dev/public/static/images/icons/apple_splash_1125.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/dc-dev/public/static/images/icons/apple_splash_1125.png -------------------------------------------------------------------------------- /apps/dc-dev/public/static/images/icons/apple_splash_1242.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/dc-dev/public/static/images/icons/apple_splash_1242.png -------------------------------------------------------------------------------- /apps/dc-dev/public/static/images/icons/apple_splash_1536.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/dc-dev/public/static/images/icons/apple_splash_1536.png -------------------------------------------------------------------------------- /apps/dc-dev/public/static/images/icons/apple_splash_1668.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/dc-dev/public/static/images/icons/apple_splash_1668.png -------------------------------------------------------------------------------- /apps/dc-dev/public/static/images/icons/apple_splash_2048.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/dc-dev/public/static/images/icons/apple_splash_2048.png -------------------------------------------------------------------------------- /apps/dc-dev/public/static/images/icons/apple_splash_640.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/dc-dev/public/static/images/icons/apple_splash_640.png -------------------------------------------------------------------------------- /apps/dc-dev/public/static/images/icons/apple_splash_750.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/dc-dev/public/static/images/icons/apple_splash_750.png -------------------------------------------------------------------------------- /apps/dc-dev/public/static/images/icons/touch-icon-ipad.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/dc-dev/public/static/images/icons/touch-icon-ipad.png -------------------------------------------------------------------------------- /apps/dc-dev/public/static/images/icons/touch-icon-iphone.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/dc-dev/public/static/images/icons/touch-icon-iphone.png -------------------------------------------------------------------------------- /apps/docs/pages/realtime-api/_meta.en.json: -------------------------------------------------------------------------------- 1 | { 2 | "gtfs-static": "Transport API (GTFS)", 3 | "gtfs-realtime": "Transport API (GTFS-R)", 4 | "weather": "Weather API" 5 | } 6 | -------------------------------------------------------------------------------- /apps/docs/pages/realtime-api/_meta.ms.json: -------------------------------------------------------------------------------- 1 | { 2 | "gtfs-static": "API Pengangkutan (GTFS)", 3 | "gtfs-realtime": "API Pengangkutan (GTFS-R)", 4 | "weather": "API Cuaca" 5 | } 6 | -------------------------------------------------------------------------------- /apps/app/public/static/images/icons/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/icons/android-chrome-192x192.png -------------------------------------------------------------------------------- /apps/app/public/static/images/icons/android-chrome-384x384.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/icons/android-chrome-384x384.png -------------------------------------------------------------------------------- /apps/app/public/static/images/icons/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/icons/android-chrome-512x512.png -------------------------------------------------------------------------------- /apps/app/public/static/images/icons/touch-icon-ipad-retina.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/icons/touch-icon-ipad-retina.png -------------------------------------------------------------------------------- /apps/app/templates/dashboard-translation.json.hbs: -------------------------------------------------------------------------------- 1 | { 2 | "header": "{{titleCase dashboard_name}}", 3 | "category": "{{titleCase dashboard_category}}", 4 | "description": "" 5 | } -------------------------------------------------------------------------------- /apps/app/public/static/images/icons/touch-icon-iphone-retina.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/app/public/static/images/icons/touch-icon-iphone-retina.png -------------------------------------------------------------------------------- /apps/dc-dev/public/static/images/icons/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/dc-dev/public/static/images/icons/android-chrome-192x192.png -------------------------------------------------------------------------------- /apps/dc-dev/public/static/images/icons/android-chrome-384x384.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/dc-dev/public/static/images/icons/android-chrome-384x384.png -------------------------------------------------------------------------------- /apps/dc-dev/public/static/images/icons/android-chrome-512x512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/dc-dev/public/static/images/icons/android-chrome-512x512.png -------------------------------------------------------------------------------- /apps/dc-dev/public/static/images/icons/touch-icon-ipad-retina.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/dc-dev/public/static/images/icons/touch-icon-ipad-retina.png -------------------------------------------------------------------------------- /apps/dc-dev/public/static/images/icons/touch-icon-iphone-retina.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/data-gov-my/datagovmy-front/HEAD/apps/dc-dev/public/static/images/icons/touch-icon-iphone-retina.png -------------------------------------------------------------------------------- /packages/datagovmy-nextra/src/env.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace NodeJS { 2 | export interface ProcessEnv { 3 | APP_URL: string; 4 | APP_ENV: string; 5 | NEXT_PUBLIC_AI_URL: string; 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /packages/datagovmy-nextra/README.md: -------------------------------------------------------------------------------- 1 | # nextra-theme-docs 2 | 3 | A documentation site theme for [Nextra](https://github.com/shuding/nextra). 4 | 5 | ## Example 6 | 7 | [nextra.vercel.app](https://nextra.vercel.app/) 8 | -------------------------------------------------------------------------------- /packages/tsconfig/postcss.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: { 3 | "postcss-import": {}, 4 | "tailwindcss/nesting": "postcss-nesting", 5 | "tailwindcss": {}, 6 | "autoprefixer": {}, 7 | }, 8 | }; 9 | -------------------------------------------------------------------------------- /prettier.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | singleQuote: false, 3 | semi: true, 4 | trailingComma: "es5", 5 | tabWidth: 2, 6 | quoteProps: "consistent", 7 | arrowParens: "avoid", 8 | printWidth: 100, 9 | }; 10 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/charts/partials/types.ts: -------------------------------------------------------------------------------- 1 | export type OptionType = { 2 | label: L; 3 | value: V; 4 | }; 5 | 6 | export const isOptionType = (value: any): value is OptionType => "value" in value; 7 | -------------------------------------------------------------------------------- /apps/app/next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/basic-features/typescript for more information. 6 | -------------------------------------------------------------------------------- /apps/dc-dev/next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/basic-features/typescript for more information. 6 | -------------------------------------------------------------------------------- /apps/docs/next-env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | /// 3 | 4 | // NOTE: This file should not be edited 5 | // see https://nextjs.org/docs/basic-features/typescript for more information. 6 | -------------------------------------------------------------------------------- /packages/tsconfig/playwright.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "display": "Playwright", 4 | "extends": "./base.json", 5 | "exclude": ["node_modules", ".turbo", "playwright-report", "test-results"] 6 | } 7 | -------------------------------------------------------------------------------- /apps/app/lib/events.ts: -------------------------------------------------------------------------------- 1 | import mitt from "mitt"; 2 | 3 | type Events = { 4 | "chat-create": string; // chat-id 5 | "chat-delete": string | string[]; // chat-id 6 | "chat-reset": void; 7 | }; 8 | 9 | export default mitt(); 10 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/types/i18n.d.ts: -------------------------------------------------------------------------------- 1 | import { UserConfig } from "next-i18next"; 2 | 3 | export type I18nConfig = UserConfig & { autoloadNs: string[] }; 4 | 5 | export type defineConfig = (namespace: string[], autoloadNs: string[]) => I18nConfig; 6 | -------------------------------------------------------------------------------- /apps/app/lib/dts/mixpanel.d.ts: -------------------------------------------------------------------------------- 1 | import type { OverridedMixpanel, Mixpanel } from "mixpanel-browser"; 2 | 3 | declare global { 4 | interface Window { 5 | mixpanel: OverridedMixpanel & { 6 | instance: Mixpanel; 7 | }; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /apps/dc-dev/lib/dts/mixpanel.d.ts: -------------------------------------------------------------------------------- 1 | import type { OverridedMixpanel, Mixpanel } from "mixpanel-browser"; 2 | 3 | declare global { 4 | interface Window { 5 | mixpanel: OverridedMixpanel & { 6 | instance: Mixpanel; 7 | }; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /apps/docs/lib/dts/mixpanel.d.ts: -------------------------------------------------------------------------------- 1 | import type { OverridedMixpanel, Mixpanel } from "mixpanel-browser"; 2 | 3 | declare global { 4 | interface Window { 5 | mixpanel: OverridedMixpanel & { 6 | instance: Mixpanel; 7 | }; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/datagovmy-nextra/src/utils/index.ts: -------------------------------------------------------------------------------- 1 | export { getGitIssueUrl } from "./get-git-issue-url"; 2 | export { renderComponent, renderString } from "./render"; 3 | export { usePopper } from "./use-popper"; 4 | export { useGitEditUrl } from "./use-git-edit-url"; 5 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/lib/dts/mixpanel.d.ts: -------------------------------------------------------------------------------- 1 | import { OverridedMixpanel, Mixpanel } from "mixpanel-browser"; 2 | 3 | declare global { 4 | interface Window { 5 | mixpanel: OverridedMixpanel & { 6 | instance: Mixpanel; 7 | }; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /packages/datagovmy-nextra/src/components/table.tsx: -------------------------------------------------------------------------------- 1 | import type { ComponentProps } from "react"; 2 | 3 | export const Table = ({ className = "", ...props }: ComponentProps<"table">) => ( 4 | 5 | ); 6 | -------------------------------------------------------------------------------- /apps/docs/templates/docs.mdx.hbs: -------------------------------------------------------------------------------- 1 | # {{titleCase docs_name}} 2 | 3 | Lorem ipsum dolor sit amet consectetur adipisicing elit. Recusandae iusto quam natus eum molestias 4 | impedit, magnam error harum quos vitae illum quidem, quod modi doloremque iste adipisci nam corrupti 5 | quo? -------------------------------------------------------------------------------- /apps/dc-dev/next-i18next.config.js: -------------------------------------------------------------------------------- 1 | const defineConfig = require("datagovmy-ui/i18n"); 2 | 3 | const namespaces = ["common", "catalogue", "countries", "agencies", "validations"]; 4 | 5 | module.exports = defineConfig(namespaces, ["common", "agencies", "dashboards", "validations"]); 6 | -------------------------------------------------------------------------------- /apps/docs/index.d.ts: -------------------------------------------------------------------------------- 1 | declare namespace NodeJS { 2 | export interface ProcessEnv { 3 | APP_URL: string; 4 | APP_ENV: string; 5 | NEXT_PUBLIC_APP_URL: string; 6 | NEXT_PUBLIC_AI_URL: string; 7 | NEXT_PUBLIC_APP_ENV: string; 8 | AUTH_TOKEN: string; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /apps/docs/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tsconfig/nextjs.json", 3 | "mdx": { 4 | "plugins": [["remark-frontmatter", ["toml", "yaml"]], "remark-gfm"] 5 | }, 6 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], 7 | "exclude": ["node_modules", ".next"] 8 | } 9 | -------------------------------------------------------------------------------- /packages/datagovmy-nextra/src/contexts/index.ts: -------------------------------------------------------------------------------- 1 | export { useActiveAnchor, useSetActiveAnchor, ActiveAnchorProvider } from "./active-anchor"; 2 | export { useConfig, ConfigProvider } from "./config"; 3 | export { useDetails, DetailsProvider } from "./details"; 4 | export { useMenu } from "./menu"; 5 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/tsconfig.node.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "composite": true, 4 | "skipLibCheck": true, 5 | "module": "ESNext", 6 | "moduleResolution": "bundler", 7 | "allowSyntheticDefaultImports": true 8 | }, 9 | "include": ["vite.config.ts"] 10 | } 11 | -------------------------------------------------------------------------------- /packages/datagovmy-nextra/src/components/td.tsx: -------------------------------------------------------------------------------- 1 | import type { ComponentProps } from "react"; 2 | 3 | export const Td = ({ className = "", ...props }: ComponentProps<"td">) => ( 4 | 12 | ); 13 | -------------------------------------------------------------------------------- /packages/datagovmy-nextra/tsup.config.ts: -------------------------------------------------------------------------------- 1 | import { defineConfig } from "tsup"; 2 | import tsconfig from "./tsconfig.json"; 3 | 4 | export default defineConfig({ 5 | name: "datagovmy-nextra", 6 | entry: ["src/index.tsx"], 7 | format: "esm", 8 | dts: true, 9 | external: ["nextra"], 10 | outExtension: () => ({ js: ".js" }), 11 | target: tsconfig.compilerOptions.target as "es2016", 12 | }); 13 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/components/Markdown/index.tsx: -------------------------------------------------------------------------------- 1 | import { FunctionComponent } from "react"; 2 | import ReactMarkdown, { Options } from "react-markdown"; 3 | 4 | interface MarkdownProps extends Options {} 5 | 6 | const Markdown: FunctionComponent = ({ className = "markdown", ...props }) => { 7 | return ; 8 | }; 9 | 10 | export default Markdown; 11 | -------------------------------------------------------------------------------- /packages/datagovmy-nextra/src/utils/use-git-edit-url.ts: -------------------------------------------------------------------------------- 1 | import gitUrlParse from "git-url-parse"; 2 | import { useConfig } from "../contexts"; 3 | 4 | export function useGitEditUrl(filePath = ""): string { 5 | const config = useConfig(); 6 | const repo = gitUrlParse(config.docsRepositoryBase || ""); 7 | 8 | if (!repo) throw new Error("Invalid `docsRepositoryBase` URL!"); 9 | 10 | return `${repo.href}/${filePath}`; 11 | } 12 | -------------------------------------------------------------------------------- /apps/dc-dev/.env.example: -------------------------------------------------------------------------------- 1 | APP_URL=http://localhost:3000 2 | APP_ENV=development 3 | REVALIDATE_TOKEN= 4 | AUTH_TOKEN= 5 | 6 | # datagovmy Frontend 7 | NEXT_PUBLIC_APP_URL=$APP_URL 8 | NEXT_PUBLIC_APP_ENV=$APP_ENV 9 | 10 | # datagovmy Backend 11 | NEXT_PUBLIC_AUTHORIZATION_TOKEN= 12 | NEXT_PUBLIC_API_URL= 13 | NEXT_PUBLIC_I18N_URL=https://dlz3uh7rpztx1.cloudfront.net 14 | 15 | # datagovmy Tileserver 16 | NEXT_PUBLIC_TILESERVER_URL= 17 | 18 | -------------------------------------------------------------------------------- /packages/tsconfig/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tsconfig", 3 | "version": "0.0.0", 4 | "private": true, 5 | "files": [ 6 | "base.json", 7 | "nextjs.json", 8 | "react-library.json", 9 | "playwright.json", 10 | "tailwindcss.js", 11 | "postcss.js" 12 | ], 13 | "devDependencies": { 14 | "@tailwindcss/forms": "^0.5.3", 15 | "tailwindcss": "^3.3.1", 16 | "tailwindcss-animate": "^1.0.7" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /lambda/roll_auth_token/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "roll_auth_token", 3 | "description": "Lambda function that rolls authentication token for datagovmy services", 4 | "private": true, 5 | "version": "0.0.0", 6 | "type": "module", 7 | "files": [ 8 | "index.mjs" 9 | ], 10 | "scripts": { 11 | "package": "zip -r ./dist/package.zip * -x dist/* -x .env*" 12 | }, 13 | "dependencies": { 14 | "node-fetch": "^3.3.2" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /packages/datagovmy-nextra/src/polyfill.ts: -------------------------------------------------------------------------------- 1 | import { IS_BROWSER } from "./constants"; 2 | 3 | if (IS_BROWSER) { 4 | let resizeTimer: any; 5 | 6 | const addResizingClass = () => { 7 | document.body.classList.add("resizing"); 8 | clearTimeout(resizeTimer); 9 | resizeTimer = setTimeout(() => { 10 | document.body.classList.remove("resizing"); 11 | }, 200); 12 | }; 13 | 14 | window.addEventListener("resize", addResizingClass); 15 | } 16 | -------------------------------------------------------------------------------- /packages/datagovmy-nextra/src/types.ts: -------------------------------------------------------------------------------- 1 | /* eslint typescript-sort-keys/interface: error */ 2 | import { PageOpts } from "nextra"; 3 | import { ReactNode } from "react"; 4 | import { DocsThemeConfig } from "./constants"; 5 | 6 | export type Context = { 7 | pageOpts: PageOpts; 8 | themeConfig: DocsThemeConfig; 9 | }; 10 | 11 | export type SearchResult = { 12 | children: ReactNode; 13 | id: string; 14 | prefix?: ReactNode; 15 | route: string; 16 | }; 17 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { browser: true, es2020: true }, 3 | extends: [ 4 | "eslint:recommended", 5 | "plugin:@typescript-eslint/recommended", 6 | "plugin:react-hooks/recommended", 7 | ], 8 | parser: "@typescript-eslint/parser", 9 | parserOptions: { ecmaVersion: "latest", sourceType: "module" }, 10 | plugins: ["react-refresh"], 11 | rules: { 12 | "react-refresh/only-export-components": "warn", 13 | }, 14 | }; 15 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/hooks/useCache.ts: -------------------------------------------------------------------------------- 1 | import { useRef } from "react"; 2 | 3 | /** 4 | * Cache hook. Simple caching mechanism using Map 5 | * @param data data 6 | * @returns {{cache: Map}} cache 7 | */ 8 | export const useCache = (data: Record = {}): { cache: Map } => { 9 | const cache = useRef>(new Map(Object.entries(data))); 10 | 11 | return { 12 | cache: cache.current, 13 | }; 14 | }; 15 | -------------------------------------------------------------------------------- /packages/datagovmy-nextra/src/contexts/menu.ts: -------------------------------------------------------------------------------- 1 | import { Dispatch, SetStateAction } from "react"; 2 | import { createContext, useContext } from "react"; 3 | 4 | interface Menu { 5 | menu: boolean; 6 | setMenu: Dispatch>; 7 | } 8 | 9 | const MenuContext = createContext({ 10 | menu: false, 11 | setMenu: () => false, 12 | }); 13 | 14 | export const useMenu = () => useContext(MenuContext); 15 | 16 | export const MenuProvider = MenuContext.Provider; 17 | -------------------------------------------------------------------------------- /packages/eslint-config-datagovmy/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "eslint-config-datagovmy", 3 | "version": "0.0.0", 4 | "main": "index.js", 5 | "license": "MIT", 6 | "private": true, 7 | "dependencies": { 8 | "eslint": "^8.40.0", 9 | "eslint-config-next": "^13.4.1", 10 | "eslint-config-prettier": "^8.8.0", 11 | "eslint-config-turbo": "^1.9.3", 12 | "eslint-plugin-react": "^7.32.2" 13 | }, 14 | "publishConfig": { 15 | "access": "public" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /packages/datagovmy-nextra/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es2016", 4 | "module": "ESNext", 5 | "declaration": false, 6 | "noEmit": true, 7 | "esModuleInterop": true, 8 | "strict": true, 9 | "skipLibCheck": true, 10 | "allowJs": true, 11 | "jsx": "react-jsx", 12 | "moduleResolution": "node", 13 | "lib": ["ESNext", "DOM", "DOM.Iterable"], 14 | "types": ["vitest/globals"], 15 | "resolveJsonModule": true 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /apps/app/components/Filetree/branch.tsx: -------------------------------------------------------------------------------- 1 | import { FunctionComponent } from "react"; 2 | import { FileNode } from "./utils"; 3 | import { TreeNode } from "."; 4 | 5 | interface BranchProps { 6 | node: FileNode; 7 | onClick?: () => void; 8 | } 9 | 10 | const BranchNode: FunctionComponent = ({ node, onClick }) => ( 11 |
    12 | {node.children.map(child => ( 13 | 14 | ))} 15 |
16 | ); 17 | 18 | export default BranchNode; 19 | -------------------------------------------------------------------------------- /vercel.json: -------------------------------------------------------------------------------- 1 | { 2 | "git": { 3 | "deploymentEnabled": true 4 | }, 5 | "github": { 6 | "silent": false 7 | }, 8 | "functions": { 9 | "apps/opendosm/pages/publications/**/*": { 10 | "maxDuration": 5 11 | }, 12 | "apps/opendosm/pages/data-catalogue/**/*": { 13 | "maxDuration": 5 14 | }, 15 | "apps/app/pages/dashboard/index.tsx": { 16 | "maxDuration": 5 17 | }, 18 | "apps/app/pages/data-catalogue/**/*": { 19 | "maxDuration": 5 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /apps/app/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tsconfig/nextjs.json", 3 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], 4 | "compilerOptions": { 5 | "baseUrl": ".", 6 | "paths": { 7 | "@components/*": ["components/*"], 8 | "@lib/*": ["lib/*"], 9 | "@hooks/*": ["hooks/*"], 10 | "@dashboards/*": ["dashboards/*"], 11 | "@misc/*": ["misc/*"], 12 | "@config/*": ["config/*"] 13 | } 14 | }, 15 | "exclude": ["node_modules", ".next", ".turbo"] 16 | } 17 | -------------------------------------------------------------------------------- /apps/dc-dev/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tsconfig/nextjs.json", 3 | "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"], 4 | "compilerOptions": { 5 | "baseUrl": ".", 6 | "paths": { 7 | "@components/*": ["components/*"], 8 | "@lib/*": ["lib/*"], 9 | "@hooks/*": ["hooks/*"], 10 | "@dashboards/*": ["dashboards/*"], 11 | "@misc/*": ["misc/*"], 12 | "@config/*": ["config/*"] 13 | } 14 | }, 15 | "exclude": ["node_modules", ".next", ".turbo"] 16 | } 17 | -------------------------------------------------------------------------------- /packages/datagovmy-nextra/css/anchor.css: -------------------------------------------------------------------------------- 1 | .subheading-anchor { 2 | @apply opacity-0 transition-opacity ltr:ml-1 rtl:mr-1; 3 | 4 | span:target + &, 5 | :hover > &, 6 | &:focus { 7 | @apply opacity-100; 8 | } 9 | 10 | span + &, 11 | :hover > & { 12 | @apply !no-underline; 13 | } 14 | 15 | &:after { 16 | @apply px-1 content-['#']; 17 | @apply text-gray-300 dark:text-neutral-700; 18 | span:target + & { 19 | @apply text-gray-400; 20 | @apply dark:text-neutral-500; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/datagovmy-nextra/src/components/steps.tsx: -------------------------------------------------------------------------------- 1 | import cn from "clsx"; 2 | import type { ComponentProps, ReactElement } from "react"; 3 | 4 | export function Steps({ children, className, ...props }: ComponentProps<"div">): ReactElement { 5 | return ( 6 |
14 | {children} 15 |
16 | ); 17 | } 18 | -------------------------------------------------------------------------------- /apps/docs/pages/_meta.en.json: -------------------------------------------------------------------------------- 1 | { 2 | "index": "Introduction", 3 | "changelog": "Changelog", 4 | "quickstart": "Quickstart Guide", 5 | "rate-limit": "Rate Limit", 6 | "authentication": "Authentication", 7 | "request-query": "Request Query", 8 | "response-format": "Response Format", 9 | "static-api": "Static APIs", 10 | "realtime-api": "Realtime APIs", 11 | "main-site": { 12 | "title": "Main Site", 13 | "type": "page", 14 | "href": "https://data.gov.my", 15 | "newWindow": true 16 | }, 17 | "faq": "FAQ" 18 | } 19 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/lib/api-edge.ts: -------------------------------------------------------------------------------- 1 | import { NextResponse } from "next/server"; 2 | import { createClient } from "@vercel/edge-config"; 3 | 4 | export const config = { 5 | runtime: "edge", 6 | }; 7 | 8 | export const getRollingToken = async () => { 9 | const edge = createClient(process.env.NEXT_PUBLIC_EDGE_CONFIG); 10 | const rollingToken = await edge.get("ROLLING_TOKEN"); 11 | 12 | if (!Boolean(rollingToken)) { 13 | return false; 14 | } 15 | return NextResponse.json({ 16 | token: rollingToken, 17 | }); 18 | }; 19 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "tsconfig/react-library.json", 3 | "compilerOptions": { 4 | "useDefineForClassFields": true, 5 | "skipLibCheck": true, 6 | /* Bundler mode */ 7 | "declaration": true, 8 | "allowSyntheticDefaultImports": true, 9 | "allowImportingTsExtensions": true, 10 | "declarationMap": true, 11 | "esModuleInterop": true, 12 | "resolveJsonModule": true, 13 | "isolatedModules": true, 14 | "emitDeclarationOnly": true 15 | }, 16 | 17 | "exclude": ["node_modules"] 18 | } 19 | -------------------------------------------------------------------------------- /apps/docs/pages/_meta.ms.json: -------------------------------------------------------------------------------- 1 | { 2 | "index": "Pengenalan", 3 | "changelog": "Log Perubahan", 4 | "quickstart": "Panduan Permulaan", 5 | "rate-limit": "Had Kadar Penggunaan", 6 | "authentication": "Pengesahan", 7 | "request-query": "Pertanyaan Permintaan", 8 | "response-format": "Format Respons", 9 | "static-api": "API Statik", 10 | "realtime-api": "API Masa Nyata", 11 | "main-site": { 12 | "title": "Laman Utama", 13 | "type": "page", 14 | "href": "https://data.gov.my", 15 | "newWindow": true 16 | }, 17 | "faq": "Soalan Lazim" 18 | } 19 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/components/Spinner/index.tsx: -------------------------------------------------------------------------------- 1 | import { FunctionComponent } from "react"; 2 | import { clx } from "../../lib/helpers"; 3 | 4 | interface SpinnerProps { 5 | loading: boolean; 6 | className?: string; 7 | } 8 | 9 | const Spinner: FunctionComponent = ({ loading, className }) => { 10 | return loading ? ( 11 |
17 | ) : ( 18 | <> 19 | ); 20 | }; 21 | 22 | export default Spinner; 23 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/hooks/useLanguage.ts: -------------------------------------------------------------------------------- 1 | import { OptionType } from "../../types"; 2 | import { useRouter } from "next/router"; 3 | /** 4 | * Language switcher hook. 5 | * @returns Page with current language 6 | */ 7 | export const useLanguage = () => { 8 | const { pathname, asPath, query, locale, push } = useRouter(); 9 | 10 | const onLanguageChange = (lang: OptionType) => { 11 | push({ pathname, query }, asPath, { 12 | locale: lang.value, 13 | scroll: false, 14 | }); 15 | }; 16 | 17 | return { 18 | language: locale, 19 | onLanguageChange, 20 | }; 21 | }; 22 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/README.md: -------------------------------------------------------------------------------- 1 | # datagovmy-ui 2 | 3 | The packages is the core package used in the monorepo which components that are being used across applications in this repo. 4 | 5 | ## Contributing 6 | 7 | You are more than welcome to contribute to the documentation, if you find any typos, outdated content or better suggestion for copywriting! For major changes, please raise a GitHub issue or a discussion thread first, to discuss the desired change with the core team. 8 | 9 | ## License 10 | 11 | data.gov.my is licensed under [MIT](/LICENSE.md) 12 | 13 | Copyright © 2023 [Government of Malaysia](#) 14 | -------------------------------------------------------------------------------- /apps/app/script/assets/icons/MERS.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /apps/docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "docs", 3 | "version": "0.0.0", 4 | "private": true, 5 | "description": "Malaysia's official open data portal.", 6 | "license": "MIT", 7 | "scripts": { 8 | "dev": "next dev -p 3001", 9 | "build": "next build", 10 | "postbuild": "next-sitemap", 11 | "start": "next start" 12 | }, 13 | "sideEffects": false, 14 | "dependencies": { 15 | "@vercel/edge-config": "^0.2.1", 16 | "axios": "^1.12.2", 17 | "datagovmy-nextra": "*", 18 | "next": "13", 19 | "nextra": "^2.13.4", 20 | "react": "^18.2.0", 21 | "react-dom": "^18.2.0" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /packages/tsconfig/base.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "display": "Default", 4 | "compilerOptions": { 5 | "composite": false, 6 | "declaration": true, 7 | "declarationMap": true, 8 | "esModuleInterop": true, 9 | "forceConsistentCasingInFileNames": true, 10 | "inlineSources": false, 11 | "isolatedModules": true, 12 | "moduleResolution": "node", 13 | "noUnusedLocals": false, 14 | "noUnusedParameters": false, 15 | "preserveWatchOutput": true, 16 | "skipLibCheck": true, 17 | "strict": true 18 | }, 19 | "exclude": ["node_modules"] 20 | } 21 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/script/assets/icons/MERS.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/hooks/useLocalStorage.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useState } from "react"; 2 | 3 | export const useLocalStorage = (key: string, defaultValue: {}) => { 4 | const [value, setValue] = useState(() => { 5 | let currentValue; 6 | 7 | try { 8 | currentValue = JSON.parse(localStorage.getItem(key) || String(defaultValue)); 9 | } catch (error) { 10 | currentValue = defaultValue; 11 | } 12 | 13 | return currentValue; 14 | }); 15 | 16 | useEffect(() => { 17 | localStorage.setItem(key, JSON.stringify(value)); 18 | }, [value, key]); 19 | 20 | return [value, setValue]; 21 | }; 22 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/components/Label/index.tsx: -------------------------------------------------------------------------------- 1 | import { FunctionComponent } from "react"; 2 | 3 | export interface LabelProps { 4 | name?: string; 5 | label?: string; 6 | className?: string; 7 | required?: boolean; 8 | } 9 | 10 | const Label: FunctionComponent = ({ 11 | name, 12 | label, 13 | required, 14 | className = "text-sm font-medium text-black dark:text-white block", 15 | }) => { 16 | return ( 17 | 21 | ); 22 | }; 23 | 24 | export default Label; 25 | -------------------------------------------------------------------------------- /packages/datagovmy-nextra/css/typesetting-article.css: -------------------------------------------------------------------------------- 1 | article.nextra-body-typesetting-article { 2 | font-size: 17px; 3 | font-feature-settings: "rlig" 1, "calt" 1; 4 | h1 { 5 | @apply mb-4 mt-6 text-center; 6 | font-size: 2.5rem; 7 | } 8 | h2 { 9 | @apply border-none; 10 | } 11 | a { 12 | @apply no-underline hover:underline; 13 | } 14 | p { 15 | @apply leading-8; 16 | } 17 | code { 18 | @apply border-none dark:bg-neutral-700; 19 | } 20 | pre code { 21 | @apply dark:bg-transparent; 22 | } 23 | .subheading-anchor + a { 24 | @apply no-underline after:hidden hover:no-underline; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/hooks/useTranslation.ts: -------------------------------------------------------------------------------- 1 | import { useTranslation as _useTranslation } from "next-i18next"; 2 | import { interpolate } from "../lib/helpers"; 3 | 4 | /** 5 | * Modified translation hook. Supports anchor () tag generation. 6 | * @param namespace i18n Translation file 7 | * @returns t, i18n 8 | */ 9 | export const useTranslation = (namespace?: string[] | string) => { 10 | const { t, i18n } = _useTranslation(namespace ?? "common"); 11 | const _t = (key: string, params?: any): string | any => { 12 | return interpolate(t(key, params)); 13 | }; 14 | 15 | return { 16 | t: _t, 17 | i18n, 18 | }; 19 | }; 20 | -------------------------------------------------------------------------------- /packages/eslint-config-datagovmy/index.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | browser: true, 4 | es2021: true, 5 | node: true, 6 | }, 7 | extends: [ 8 | "next", 9 | "turbo", 10 | "prettier", 11 | // "eslint:recommended", 12 | // "plugin:@typescript-eslint/recommended", 13 | "plugin:react-hooks/recommended", 14 | ], 15 | rules: { 16 | "@next/next/no-html-link-for-pages": "off", 17 | "react-hooks/exhaustive-deps": "off", 18 | "import/no-anonymous-default-export": "off", 19 | }, 20 | parserOptions: { 21 | babelOptions: { 22 | presets: [require.resolve("next/babel")], 23 | }, 24 | }, 25 | }; 26 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/data-catalogue/index.ts: -------------------------------------------------------------------------------- 1 | export { default as CatalogueIndex } from "./Main"; 2 | export { default as CatalogueCard } from "./Card"; 3 | export { default as CataloguePreview } from "./Preview"; 4 | export { default as CatalogueShow } from "./Show"; 5 | export { default as CatalogueMethodology } from "./Show/methodology"; 6 | export { default as CatalogueMetadata } from "./Show/metadata"; 7 | export { default as CatalogueWidget } from "./Widget"; 8 | 9 | // Type export 10 | export type {} from "./Main"; 11 | export type {} from "./Card"; 12 | export type {} from "./Preview"; 13 | export type {} from "./Show"; 14 | export type {} from "./Widget"; 15 | -------------------------------------------------------------------------------- /packages/datagovmy-nextra/src/components/bleed.tsx: -------------------------------------------------------------------------------- 1 | import cn from "clsx"; 2 | import type { ReactElement, ReactNode } from "react"; 3 | 4 | export function Bleed({ full, children }: { full: boolean; children: ReactNode }): ReactElement { 5 | return ( 6 |
16 | {children} 17 |
18 | ); 19 | } 20 | -------------------------------------------------------------------------------- /packages/tsconfig/nextjs.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "display": "Next.js", 4 | "extends": "./base.json", 5 | "compilerOptions": { 6 | "target": "ES6", 7 | "lib": ["dom", "dom.iterable", "esnext"], 8 | "allowJs": true, 9 | "skipLibCheck": true, 10 | "strict": true, 11 | "forceConsistentCasingInFileNames": true, 12 | "noEmit": true, 13 | "incremental": true, 14 | "esModuleInterop": true, 15 | "module": "esnext", 16 | "resolveJsonModule": true, 17 | "isolatedModules": true, 18 | "jsx": "preserve" 19 | }, 20 | "include": ["src", "next-env.d.ts"], 21 | "exclude": ["node_modules"] 22 | } 23 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/lib/dts/leaflet.d.ts: -------------------------------------------------------------------------------- 1 | // Import Leaflet into L in case you want to reference Leaflet types 2 | import * as L from "leaflet"; 3 | 4 | // Declare the leaflet module so we can modify it 5 | declare module "leaflet" { 6 | export interface IEasyPrintConstructorOptions { 7 | title?: string; 8 | position?: string; 9 | exportOnly?: boolean; 10 | hideControlContainer?: boolean; 11 | hidden?: boolean; 12 | sizeModes: string[]; 13 | } 14 | 15 | export interface EasyPrint extends L.Control { 16 | printMap: (size: string, text: string) => void; 17 | } 18 | 19 | export function easyPrint(options?: IEasyPrintConstructorOptions): EasyPrint; 20 | } 21 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/hooks/useWatch.ts: -------------------------------------------------------------------------------- 1 | import { DependencyList, useEffect, useRef } from "react"; 2 | 3 | /** 4 | * Alternative to useEffect. Default: will not run on initial render. 5 | * @param {Function} fn Callback function 6 | * @param {DependencyList} deps useEffect deps 7 | * @param {boolean} [runOnMount=false] Runs on initial render 8 | * @returns 9 | */ 10 | export const useWatch = (fn: Function, deps: DependencyList = [], runOnMount: boolean = false) => { 11 | const firstRender = useRef(true); 12 | 13 | useEffect(() => { 14 | if (!runOnMount && firstRender.current) { 15 | firstRender.current = false; 16 | return; 17 | } 18 | fn(); 19 | }, deps); 20 | }; 21 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/hooks/useSessionStorage.ts: -------------------------------------------------------------------------------- 1 | import { Dispatch, SetStateAction, useEffect, useState } from "react"; 2 | 3 | export const useSessionStorage = ( 4 | key: string, 5 | defaultValue: string = "" 6 | ): [T, Dispatch>] => { 7 | const [value, setValue] = useState(() => { 8 | let currentValue; 9 | 10 | try { 11 | currentValue = JSON.parse(sessionStorage.getItem(key) || String(defaultValue)); 12 | } catch (error) { 13 | currentValue = defaultValue; 14 | } 15 | 16 | return currentValue; 17 | }); 18 | 19 | useEffect(() => { 20 | sessionStorage.setItem(key, JSON.stringify(value)); 21 | }, [value, key]); 22 | 23 | return [value, setValue]; 24 | }; 25 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/types/hooks.d.ts: -------------------------------------------------------------------------------- 1 | export * from "datagovmy-ui/src/hooks"; 2 | 3 | // Import Leaflet into L in case you want to reference Leaflet types 4 | import * as L from "leaflet"; 5 | 6 | // Declare the leaflet module so we can modify it 7 | declare module "leaflet" { 8 | export interface IEasyPrintConstructorOptions { 9 | title?: string; 10 | position?: string; 11 | exportOnly?: boolean; 12 | hideControlContainer?: boolean; 13 | hidden?: boolean; 14 | sizeModes: string[]; 15 | } 16 | 17 | export interface EasyPrint extends L.Control { 18 | printMap: (size: string, text: string) => void; 19 | } 20 | 21 | export function easyPrint(options?: IEasyPrintConstructorOptions): EasyPrint; 22 | } 23 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/components/Card/index.tsx: -------------------------------------------------------------------------------- 1 | import { clx } from "../../lib/helpers"; 2 | import { FunctionComponent, ReactNode } from "react"; 3 | 4 | interface CardProps { 5 | className?: string; 6 | children: ReactNode; 7 | onClick?: () => void; 8 | } 9 | 10 | const Card: FunctionComponent = ({ children, className, onClick }) => { 11 | return ( 12 |
21 | {children} 22 |
23 | ); 24 | }; 25 | 26 | export default Card; 27 | -------------------------------------------------------------------------------- /packages/datagovmy-nextra/src/components/code.tsx: -------------------------------------------------------------------------------- 1 | import cn from "clsx"; 2 | import type { ComponentProps, ReactElement } from "react"; 3 | 4 | export const Code = ({ children, className, ...props }: ComponentProps<"code">): ReactElement => { 5 | const hasLineNumbers = "data-line-numbers" in props; 6 | return ( 7 | 18 | {children} 19 | 20 | ); 21 | }; 22 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/hooks/useSlice.ts: -------------------------------------------------------------------------------- 1 | import { useMemo } from "react"; 2 | 3 | /** 4 | * Slice the the array based on the minmax indices given. To be used with 5 | * @param {Record} state Data to slice 6 | * @param {[number, number]} minmax [min index, max index] 7 | * @returns Sliced state 8 | */ 9 | export const useSlice = (state: Record, minmax?: [number, number]) => { 10 | const sliced = useMemo(() => { 11 | return Object.entries(state).map(([key, data]) => [ 12 | key, 13 | data.slice(minmax ? minmax[0] : 0, minmax ? minmax[1] + 1 : data.length - 1), 14 | ]); 15 | }, [state, minmax]); 16 | 17 | return { 18 | coordinate: Object.fromEntries(sliced), 19 | } as const; 20 | }; 21 | -------------------------------------------------------------------------------- /packages/datagovmy-nextra/src/utils/render.tsx: -------------------------------------------------------------------------------- 1 | import { FC, ReactNode } from "react"; 2 | 3 | export function renderComponent(ComponentOrNode: FC | ReactNode, props?: T) { 4 | if (!ComponentOrNode) return null; 5 | if (typeof ComponentOrNode !== "function") return ComponentOrNode; 6 | // @ts-expect-error TS2322: Type '{}' is not assignable to type 'T' 7 | return ; 8 | } 9 | 10 | export function renderString( 11 | stringOrFunction?: string | ((props: T) => string), 12 | // @ts-expect-error TS2322: Type '{}' is not assignable to type 'T'. 13 | props: T = {} 14 | ): string { 15 | const result = 16 | typeof stringOrFunction === "function" ? stringOrFunction(props) : stringOrFunction; 17 | return result || ""; 18 | } 19 | -------------------------------------------------------------------------------- /apps/app/types/next-auth.d.ts: -------------------------------------------------------------------------------- 1 | import NextAuth from "next-auth"; 2 | import { JWT } from "next-auth/jwt"; 3 | 4 | declare module "next-auth/jwt" { 5 | /** Returned by the `jwt` callback and `getToken`, when using JWT sessions */ 6 | interface JWT { 7 | /** The user's github tokens. */ 8 | github: { 9 | accessToken: string; 10 | accessTokenExpiresAt: number; 11 | refreshToken: string; 12 | }; 13 | } 14 | } 15 | 16 | declare module "next-auth" { 17 | /** 18 | * Returned by `useSession`, `getSession` and received as a prop on the `SessionProvider` React Context 19 | */ 20 | interface Session { 21 | /** The user's github tokens. */ 22 | github: { 23 | accessToken: string; 24 | refreshToken: string; 25 | }; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/components/Container/index.tsx: -------------------------------------------------------------------------------- 1 | import { FunctionComponent, ReactNode } from "react"; 2 | import { clx } from "../../lib/helpers"; 3 | 4 | type ContainerProps = { 5 | background?: string; 6 | className?: string; 7 | children?: ReactNode; 8 | }; 9 | 10 | const Container: FunctionComponent = ({ background, className, children }) => { 11 | return ( 12 |
13 |
19 | {children} 20 |
21 |
22 | ); 23 | }; 24 | 25 | export default Container; 26 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/components/Skeleton/index.tsx: -------------------------------------------------------------------------------- 1 | import { clx } from "../../lib/helpers"; 2 | 3 | function Skeleton({ className, ...props }: React.HTMLAttributes) { 4 | return ( 5 |
18 | ); 19 | } 20 | 21 | export default Skeleton; 22 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/hooks/index.ts: -------------------------------------------------------------------------------- 1 | export { useAnalytics } from "./useAnalytics"; 2 | export { useCache } from "./useCache"; 3 | export { useColor } from "./useColor"; 4 | export type { Color } from "./useColor"; 5 | export { useData } from "./useData"; 6 | export { useExport } from "./useExport"; 7 | export { useFilter } from "./useFilter"; 8 | export { useLanguage } from "./useLanguage"; 9 | export { useLocalStorage } from "./useLocalStorage"; 10 | export { useScrollIntersect } from "./useScrollIntersect"; 11 | export { useSessionStorage } from "./useSessionStorage"; 12 | export { useSlice } from "./useSlice"; 13 | export { useTrace } from "./useTrace"; 14 | export { useTranslation } from "./useTranslation"; 15 | export { useWatch } from "./useWatch"; 16 | export { useZoom } from "./useZoom"; 17 | -------------------------------------------------------------------------------- /packages/datagovmy-nextra/vite.config.ts: -------------------------------------------------------------------------------- 1 | import react from "@vitejs/plugin-react"; 2 | import { defineConfig } from "vitest/config"; 3 | import { resolve } from "path"; 4 | 5 | export default defineConfig({ 6 | plugins: [react()], 7 | test: { 8 | environment: "jsdom", 9 | }, 10 | // build: { 11 | // lib: { 12 | // entry: resolve(__dirname, "src/index.tsx"), 13 | // name: "datagovmy-nextra", 14 | // fileName: "index", 15 | // formats: ["es"], 16 | // }, 17 | // outDir: "dist", 18 | // rollupOptions: { 19 | // treeshake: true, 20 | // external: ["nextra", "react"], 21 | // plugins: [], 22 | // output: { 23 | // format: "esm", 24 | // esModule: true, 25 | // preserveModules: false, 26 | // }, 27 | // }, 28 | // }, 29 | }); 30 | -------------------------------------------------------------------------------- /apps/docs/README.md: -------------------------------------------------------------------------------- 1 | # datagovmy-docs 2 | 3 | [Open API](https://data.gov.my) is the Malaysian government's official API service that aims to provide transparent and reliable access to the nation's wealth of data. This repository is the documentation of the API service aforementioned. 4 | 5 | ## Contributing 6 | 7 | You are more than welcome to contribute to the documentation, if you find any typos, outdated content or better suggestion for copywriting! For major changes, please raise a GitHub issue or a discussion thread first, to discuss the desired change with the core team. 8 | 9 | For more information, refer to our [README.md](../../README.md#contributing) for more information about contribution. 10 | 11 | ## License 12 | 13 | data.gov.my is licensed under [MIT](/LICENSE.md) 14 | 15 | Copyright © 2023 [Government of Malaysia](#) 16 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/contexts/slider.tsx: -------------------------------------------------------------------------------- 1 | import { FunctionComponent, ReactNode, createContext, useState } from "react"; 2 | 3 | interface SliderContextProps { 4 | play: boolean; 5 | setPlaying: React.Dispatch>; 6 | } 7 | 8 | interface SliderProviderProps { 9 | children: (play: boolean) => ReactNode; 10 | } 11 | 12 | export const SliderContext = createContext({ 13 | play: false, 14 | setPlaying: () => {}, 15 | }); 16 | 17 | export const SliderProvider: FunctionComponent = ({ children }) => { 18 | const [play, setPlaying] = useState(false); 19 | 20 | const contextValue: SliderContextProps = { 21 | play, 22 | setPlaying, 23 | }; 24 | 25 | return {children(play)}; 26 | }; 27 | -------------------------------------------------------------------------------- /apps/dc-dev/middleware.ts: -------------------------------------------------------------------------------- 1 | import { NextRequest, NextResponse } from "next/server"; 2 | 3 | // Triggers on relevant pages. Authentication to be removed at launch 4 | export const config = { 5 | matcher: ["/", "/data-catalogue/:path*"], 6 | }; 7 | 8 | export async function middleware(request: NextRequest) { 9 | let response: NextResponse; 10 | const basicAuth = request.headers.get("authorization"); 11 | if (basicAuth) { 12 | const authValue = basicAuth.split(" ")[1]; 13 | const [user, password] = atob(authValue).split(":"); 14 | if (user === "admin" && password === process.env.AUTH_TOKEN) { 15 | response = NextResponse.next(); 16 | return response; 17 | } 18 | } 19 | return new NextResponse("Auth required", { 20 | status: 401, 21 | headers: { "WWW-Authenticate": `Basic realm="Secure Area"` }, 22 | }); 23 | } 24 | -------------------------------------------------------------------------------- /packages/datagovmy-nextra/css/ai.css: -------------------------------------------------------------------------------- 1 | /* AI Helper CSS */ 2 | .ai pre { 3 | @apply bg-outline bg-primary-700/5 dark:bg-primary-300/10 my-3 overflow-x-auto whitespace-pre-wrap break-words rounded-xl border border-black border-opacity-[0.04] px-3 py-3 text-[.9em] font-medium subpixel-antialiased; 4 | } 5 | 6 | .ai code { 7 | @apply bg-outline break-words rounded-md border border-black border-opacity-[0.04] px-[.25em] py-0.5 text-[.9em] dark:bg-white/10 dark:text-white; 8 | } 9 | 10 | .ai ul { 11 | @apply my-5 list-inside list-disc space-y-3; 12 | } 13 | 14 | .ai ol { 15 | @apply ml-5 list-outside list-decimal space-y-6; 16 | } 17 | 18 | .ai li > p { 19 | @apply inline; 20 | } 21 | 22 | .ai p { 23 | @apply leading-7; 24 | } 25 | 26 | .ai a { 27 | @apply text-primary-dgm dark:text-primary-dark [text-underline-position:from-font] hover:underline; 28 | } 29 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/lib/geojson/dun/n.31_batu_lancang.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | type: "Feature", 3 | properties: { 4 | state: "Pulau Pinang", 5 | parlimen: "P.050 Jelutong", 6 | dun: "N.31 Batu Lancang", 7 | code_state: 7, 8 | code_parlimen: "P.050", 9 | code_dun: "N.31", 10 | code_state_dun: "7_N.31", 11 | }, 12 | geometry: { 13 | type: "MultiPolygon", 14 | coordinates: [ 15 | [ 16 | [ 17 | [100.31523, 5.40322], 18 | [100.31491, 5.39936], 19 | [100.3191, 5.39722], 20 | [100.3132, 5.39119], 21 | [100.31241, 5.38657], 22 | [100.30829, 5.38341], 23 | [100.30785, 5.37937], 24 | [100.30245, 5.39114], 25 | [100.30395, 5.40183], 26 | [100.31523, 5.40322], 27 | ], 28 | ], 29 | ], 30 | }, 31 | }; 32 | -------------------------------------------------------------------------------- /apps/app/script/assets/icons/MOH.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /packages/datagovmy-nextra/src/utils/get-git-issue-url.ts: -------------------------------------------------------------------------------- 1 | import gitUrlParse from "git-url-parse"; 2 | 3 | export const getGitIssueUrl = ({ 4 | repository = "", 5 | title, 6 | labels, 7 | }: { 8 | repository?: string; 9 | title: string; 10 | labels?: string; 11 | }): string => { 12 | const repo = gitUrlParse(repository); 13 | if (!repo) throw new Error("Invalid `docsRepositoryBase` URL!"); 14 | 15 | if (repo.resource.includes("gitlab")) { 16 | return `${repo.protocol}://${repo.resource}/${repo.owner}/${ 17 | repo.name 18 | }/-/issues/new?issue[title]=${encodeURIComponent(title)}`; 19 | } 20 | if (repo.resource.includes("github")) { 21 | return `${repo.protocol}://${repo.resource}/${repo.owner}/${ 22 | repo.name 23 | }/issues/new?title=${encodeURIComponent(title)}&labels=${labels || ""}`; 24 | } 25 | return "#"; 26 | }; 27 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/components/Toast/index.tsx: -------------------------------------------------------------------------------- 1 | import { useTheme } from "next-themes"; 2 | import { FunctionComponent, ReactNode } from "react"; 3 | import { Toaster, toast as _toast } from "sonner"; 4 | 5 | const Toast: FunctionComponent[0]> = props => { 6 | const { theme } = useTheme(); 7 | return ; 8 | }; 9 | 10 | const toast = { 11 | success: (title: ReactNode, description?: string) => 12 | _toast.success(title, { icon: <>, description }), 13 | error: (title: ReactNode, description?: string) => 14 | _toast.error(title, { icon: <>, description }), 15 | message: (title: ReactNode, description?: string) => 16 | _toast.message(title, { icon: <>, description }), 17 | }; 18 | 19 | export default Toast; 20 | export { toast }; 21 | -------------------------------------------------------------------------------- /apps/app/.env.example: -------------------------------------------------------------------------------- 1 | APP_URL=http://localhost:3000 2 | APP_ENV=development 3 | REVALIDATE_TOKEN= 4 | EDGE_CONFIG= 5 | 6 | # datagovmy Frontend 7 | NEXT_PUBLIC_APP_URL=$APP_URL 8 | NEXT_PUBLIC_APP_ENV=$APP_ENV 9 | 10 | # datagovmy Backend 11 | NEXT_PUBLIC_AUTHORIZATION_TOKEN= 12 | NEXT_PUBLIC_API_URL= 13 | NEXT_PUBLIC_I18N_URL=https://dlz3uh7rpztx1.cloudfront.net 14 | NEXT_PUBLIC_TINYBIRD_TOKEN= 15 | NEXT_PUBLIC_TINYBIRD_URL= 16 | 17 | # datagovmy AI 18 | NEXT_PUBLIC_AI_URL= 19 | 20 | NEXT_PUBLIC_GA_TAG= 21 | 22 | # datagovmy Tileserver 23 | NEXT_PUBLIC_TILESERVER_URL= 24 | 25 | # Mixpanel 26 | MIXPANEL_TOKEN= 27 | MIXPANEL_PROJECT_ID= 28 | MIXPANEL_SA_USER= 29 | MIXPANEL_SA_SECRET= 30 | NEXT_PUBLIC_MIXPANEL_TOKEN=$MIXPANEL_TOKEN 31 | 32 | # Auth 33 | NEXTAUTH_URL=http://localhost:3000 34 | NEXTAUTH_SECRET= 35 | # GitHub Oauth App 36 | GITHUB_CLIENT_ID= 37 | GITHUB_CLIENT_SECRET= -------------------------------------------------------------------------------- /packages/datagovmy-ui/script/assets/icons/MOH.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/lib/geojson/dun/n.09_kota_lama.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | type: "Feature", 3 | properties: { 4 | state: "Kelantan", 5 | parlimen: "P.021 Kota Bharu", 6 | dun: "N.09 Kota Lama", 7 | code_state: 3, 8 | code_parlimen: "P.021", 9 | code_dun: "N.09", 10 | code_state_dun: "3_N.09", 11 | }, 12 | geometry: { 13 | type: "MultiPolygon", 14 | coordinates: [ 15 | [ 16 | [ 17 | [102.25025, 6.13479], 18 | [102.25151, 6.12915], 19 | [102.25079, 6.1157], 20 | [102.24226, 6.11737], 21 | [102.23468, 6.1154], 22 | [102.22912, 6.11631], 23 | [102.23122, 6.12213], 24 | [102.23248, 6.1349], 25 | [102.23505, 6.13475], 26 | [102.23746, 6.14079], 27 | [102.25025, 6.13479], 28 | ], 29 | ], 30 | ], 31 | }, 32 | }; 33 | -------------------------------------------------------------------------------- /apps/dc-dev/components/Layout/index.tsx: -------------------------------------------------------------------------------- 1 | import Header from "@components/Layout/Header"; 2 | import Footer from "@components/Layout/Footer"; 3 | import { FunctionComponent, ReactNode } from "react"; 4 | import { clx } from "datagovmy-ui/helpers"; 5 | import { useTranslation } from "datagovmy-ui/hooks"; 6 | 7 | interface LayoutProps { 8 | className?: string; 9 | stateSelector?: ReactNode; 10 | children: ReactNode; 11 | useBanner?: boolean; 12 | } 13 | 14 | const Layout: FunctionComponent = ({ className, children, stateSelector }) => { 15 | const { t } = useTranslation(); 16 | return ( 17 |
18 |
19 |
20 |
{children}
21 |
22 |
23 |
24 | ); 25 | }; 26 | 27 | export default Layout; 28 | -------------------------------------------------------------------------------- /packages/datagovmy-nextra/css/hamburger.css: -------------------------------------------------------------------------------- 1 | .nextra-hamburger svg { 2 | g { 3 | @apply origin-center; 4 | transition: transform 0.2s cubic-bezier(0.25, 1, 0.5, 1); 5 | } 6 | path { 7 | opacity: 1; 8 | transition: transform 0.2s cubic-bezier(0.25, 1, 0.5, 1) 0.2s, opacity 0.2s ease 0.2s; 9 | } 10 | 11 | &.open { 12 | path { 13 | transition: transform 0.2s cubic-bezier(0.25, 1, 0.5, 1), opacity 0s ease 0.2s; 14 | } 15 | g { 16 | transition: transform 0.2s cubic-bezier(0.25, 1, 0.5, 1) 0.2s; 17 | } 18 | } 19 | 20 | &.open > { 21 | path { 22 | @apply opacity-0; 23 | } 24 | g:nth-of-type(1) { 25 | @apply rotate-45; 26 | path { 27 | transform: translate3d(0, 6px, 0); 28 | } 29 | } 30 | g:nth-of-type(2) { 31 | @apply -rotate-45; 32 | path { 33 | transform: translate3d(0, -6px, 0); 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/charts/partials/geojson.tsx: -------------------------------------------------------------------------------- 1 | import { CatalogueContext } from "../../contexts/catalogue"; 2 | import { default as dynamic } from "next/dynamic"; 3 | import { FunctionComponent, useContext } from "react"; 4 | 5 | const GeoChoropleth = dynamic(() => import("../geochoropleth"), { 6 | ssr: false, 7 | }); 8 | 9 | interface CatalogueGeojsonProps { 10 | className?: string; 11 | config: any; 12 | } 13 | 14 | const CatalogueGeojson: FunctionComponent = ({ 15 | className = "h-[450px] w-full", 16 | config, 17 | }) => { 18 | const { bind, dataset } = useContext(CatalogueContext); 19 | 20 | return ( 21 | 29 | ); 30 | }; 31 | 32 | export default CatalogueGeojson; 33 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/components/Banner/index.tsx: -------------------------------------------------------------------------------- 1 | import { FunctionComponent, ReactNode } from "react"; 2 | import Container from "../Container"; 3 | import { InformationCircleIcon } from "@heroicons/react/20/solid"; 4 | import { clx } from "../../lib/helpers"; 5 | 6 | interface BannerProps { 7 | text: string; 8 | icon?: ReactNode; 9 | className?: string; 10 | } 11 | 12 | const Banner: FunctionComponent = ({ 13 | text, 14 | className, 15 | icon = , 16 | }) => { 17 | return ( 18 |
19 | 20 |
21 | {icon} 22 |

a]:text-white [&>a]:underline text-sm")}>{text}

23 |
24 |
25 |
26 | ); 27 | }; 28 | 29 | export default Banner; 30 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/lib/mixpanel.ts: -------------------------------------------------------------------------------- 1 | import { EventType } from "../../types"; 2 | 3 | /** 4 | * Mixpanel track events. 5 | * @param event file_download | file_download | page_view | change_language | select_dropdown 6 | * @param prop Object 7 | */ 8 | export const track = (event: EventType, prop?: Record): void => { 9 | if (window.mixpanel?.instance) window.mixpanel.instance.track(event, prop); 10 | }; 11 | 12 | /** 13 | * Mixpanel track session period. 14 | */ 15 | export const init_session = (): void => { 16 | if (window.mixpanel?.instance) window.mixpanel.instance.time_event("page_view"); 17 | }; 18 | 19 | /** 20 | * GoogleAnalytics track - https://developers.google.com/analytics/devguides/collection/gtagjs/pages 21 | * @param url URL path 22 | */ 23 | export const ga_track = (url: string): void => { 24 | if (window.gtag) window.gtag("config", process.env.NEXT_PUBLIC_GA_TAG, { page_path: url }); 25 | }; 26 | -------------------------------------------------------------------------------- /apps/app/dashboards/public-safety/crime/index.tsx: -------------------------------------------------------------------------------- 1 | import { AgencyBadge, Container, Hero } from "datagovmy-ui/components"; 2 | import { useTranslation } from "datagovmy-ui/hooks"; 3 | import { FunctionComponent } from "react"; 4 | 5 | /** 6 | * Crime Dashboard 7 | * @overview Status: In-development 8 | */ 9 | 10 | interface CrimeProps {} 11 | 12 | const Crime: FunctionComponent = ({}) => { 13 | const { t, i18n } = useTranslation(["dashboard-crime", "common"]); 14 | 15 | return ( 16 | <> 17 | } 23 | /> 24 | {/* Rest of page goes here */} 25 | 26 | 27 | ); 28 | }; 29 | 30 | export default Crime; 31 | -------------------------------------------------------------------------------- /apps/app/pages/api/data-catalogue/fetch-category.ts: -------------------------------------------------------------------------------- 1 | import { get } from "datagovmy-ui/api"; 2 | import { NextApiRequest, NextApiResponse } from "next"; 3 | 4 | export default async function handler(req: NextApiRequest, res: NextApiResponse) { 5 | if (req.method !== "GET") { 6 | return res.status(405).json({ error: "Method Not Allowed" }); 7 | } 8 | 9 | const results = await Promise.allSettled([ 10 | get(`${process.env.S3_URL}/metadata/metadata_category_en.json`), 11 | get(`${process.env.S3_URL}/metadata/metadata_category_ms.json`), 12 | get(`${process.env.S3_URL}/metadata/metadata_agencies.json`), 13 | ]); 14 | 15 | const [categoryEn, categoryMs, agencies_source] = results.map(e => { 16 | if (e.status === "rejected") return null; 17 | else return e.value.data; 18 | }); 19 | 20 | return res.status(200).json({ 21 | en: categoryEn, 22 | ms: categoryMs, 23 | agencies_source: agencies_source, 24 | }); 25 | } 26 | -------------------------------------------------------------------------------- /apps/app/script/assets/icons/PHCorp.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /apps/app/public/static/images/github-mark.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/lib/geojson/dun/n.29_datok_keramat.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | type: "Feature", 3 | properties: { 4 | state: "Pulau Pinang", 5 | parlimen: "P.050 Jelutong", 6 | dun: "N.29 Datok Keramat", 7 | code_state: 7, 8 | code_parlimen: "P.050", 9 | code_dun: "N.29", 10 | code_state_dun: "7_N.29", 11 | }, 12 | geometry: { 13 | type: "MultiPolygon", 14 | coordinates: [ 15 | [ 16 | [ 17 | [100.31572, 5.41298], 18 | [100.32387, 5.41249], 19 | [100.32351, 5.40819], 20 | [100.31597, 5.41029], 21 | [100.32214, 5.40355], 22 | [100.32109, 5.40251], 23 | [100.31846, 5.40166], 24 | [100.31539, 5.40375], 25 | [100.30395, 5.40183], 26 | [100.30088, 5.4197], 27 | [100.30334, 5.42158], 28 | [100.3057, 5.41824], 29 | [100.31572, 5.41298], 30 | ], 31 | ], 32 | ], 33 | }, 34 | }; 35 | -------------------------------------------------------------------------------- /apps/app/public/static/images/github-mark-white.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/script/assets/icons/PHCorp.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /apps/app/dashboards/environment/flood-warning/index.tsx: -------------------------------------------------------------------------------- 1 | import { AgencyBadge, Container, Hero } from "datagovmy-ui/components"; 2 | import { useTranslation } from "datagovmy-ui/hooks"; 3 | import { FunctionComponent } from "react"; 4 | 5 | /** 6 | * FloodWarning Dashboard 7 | * @overview Status: In-development 8 | */ 9 | 10 | interface FloodWarningProps {} 11 | 12 | const FloodWarning: FunctionComponent = ({}) => { 13 | const { t, i18n } = useTranslation(["dashboard-flood-warning", "common"]); 14 | 15 | return ( 16 | <> 17 | } 23 | /> 24 | {/* Rest of page goes here */} 25 | 26 | 27 | ); 28 | }; 29 | 30 | export default FloodWarning; 31 | -------------------------------------------------------------------------------- /apps/app/script/assets/icons/PDN.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/script/assets/icons/PDN.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/charts/donut-meter.tsx: -------------------------------------------------------------------------------- 1 | import { FunctionComponent } from "react"; 2 | 3 | interface DonutMeterProps { 4 | value?: number; 5 | } 6 | 7 | const DonutMeter: FunctionComponent = ({ value = 30 }) => { 8 | const color = () => { 9 | if (value >= 90) return "#DC2626"; 10 | if (value >= 75) return "#FB8229"; 11 | if (value >= 50) return "#FBBF24"; 12 | else return "#22C55E"; 13 | }; 14 | return ( 15 |
27 | ); 28 | }; 29 | 30 | export default DonutMeter; 31 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/hooks/useScrollIntersect.ts: -------------------------------------------------------------------------------- 1 | import { useEffect, useRef } from "react"; 2 | /** 3 | * Language switcher hook. 4 | * @returns Page with current language 5 | */ 6 | export const useScrollIntersect = (target: Element | null, className: string) => { 7 | const observer = useRef(null); 8 | 9 | useEffect(() => { 10 | if (observer.current) observer.current.disconnect(); 11 | 12 | const intercepter = document.createElement("div"); 13 | target?.before(intercepter); 14 | 15 | observer.current = new IntersectionObserver(([entry]) => { 16 | if (!entry.isIntersecting) { 17 | target?.classList.add(className); 18 | } else { 19 | target?.classList.remove(className); 20 | } 21 | }); 22 | const { current: currentObserver } = observer; 23 | 24 | if (intercepter) currentObserver.observe(intercepter); 25 | 26 | return () => currentObserver.disconnect(); 27 | }, [target]); 28 | 29 | return; 30 | }; 31 | -------------------------------------------------------------------------------- /apps/app/dashboards/demography/circle-of-life/index.tsx: -------------------------------------------------------------------------------- 1 | import { AgencyBadge, Container, Hero } from "datagovmy-ui/components"; 2 | import { useTranslation } from "datagovmy-ui/hooks"; 3 | import { FunctionComponent } from "react"; 4 | 5 | /** 6 | * Circle of Life Dashboard 7 | * @overview Status: In-development 8 | */ 9 | 10 | interface CircleofLifeProps {} 11 | 12 | const CircleofLife: FunctionComponent = ({}) => { 13 | const { t, i18n } = useTranslation(["dashboard-circle-of-life", "common"]); 14 | 15 | return ( 16 | <> 17 | } 23 | /> 24 | {/* Rest of page goes here */} 25 | 26 | 27 | ); 28 | }; 29 | 30 | export default CircleofLife; 31 | -------------------------------------------------------------------------------- /apps/app/dashboards/economy/public-pension/index.tsx: -------------------------------------------------------------------------------- 1 | import { AgencyBadge, Container, Hero } from "datagovmy-ui/components"; 2 | import { useTranslation } from "datagovmy-ui/hooks"; 3 | import { FunctionComponent } from "react"; 4 | 5 | /** 6 | * PublicPension Dashboard 7 | * @overview Status: In-development 8 | */ 9 | 10 | interface PublicPensionProps {} 11 | 12 | const PublicPension: FunctionComponent = ({}) => { 13 | const { t, i18n } = useTranslation(["dashboard-public-pension", "common"]); 14 | 15 | return ( 16 | <> 17 | } 23 | /> 24 | {/* Rest of page goes here */} 25 | 26 | 27 | ); 28 | }; 29 | 30 | export default PublicPension; 31 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/hooks/useAnalytics.ts: -------------------------------------------------------------------------------- 1 | import { useContext } from "react"; 2 | import { AnalyticsContext, DownloadFileFormat } from "../contexts/analytics"; 3 | import { track as mixpanel_track } from "../lib/mixpanel"; 4 | 5 | /** 6 | * For data-catalogue only. 7 | */ 8 | export const useAnalytics = (dataset: any) => { 9 | const { result, update_download, send_new_analytics } = useContext(AnalyticsContext); 10 | 11 | const track = (ext: DownloadFileFormat) => { 12 | const meta = { 13 | uid: dataset.meta.unique_id.concat(`_${ext}`), 14 | id: dataset.meta.unique_id, 15 | name: dataset.meta.title, 16 | type: ["svg", "png"].includes(ext) ? "image" : "file", 17 | ext, 18 | }; 19 | mixpanel_track(["svg", "png"].includes(ext) ? "file_download" : "image_download", meta); 20 | update_download(dataset.meta.unique_id, ext); 21 | send_new_analytics(dataset.meta.unique_id, "data-catalogue", "file_download", { format: ext }); 22 | }; 23 | return { result, track }; 24 | }; 25 | -------------------------------------------------------------------------------- /apps/app/pages/datagpt.tsx: -------------------------------------------------------------------------------- 1 | import DataGPT from "@misc/datagpt"; 2 | import { Metadata, Progress } from "datagovmy-ui/components"; 3 | import { withi18n } from "datagovmy-ui/decorators"; 4 | import { useTranslation } from "datagovmy-ui/hooks"; 5 | import { Page } from "datagovmy-ui/types"; 6 | import { GetStaticProps, InferGetStaticPropsType } from "next"; 7 | 8 | const AIChat: Page = ({}: InferGetStaticPropsType) => { 9 | const { t } = useTranslation(["datagpt"]); 10 | 11 | return ( 12 | <> 13 | 14 | 15 | 16 | 17 | ); 18 | }; 19 | 20 | export const getStaticProps: GetStaticProps = withi18n("datagpt", async () => { 21 | return { 22 | notFound: true, 23 | props: { 24 | meta: { 25 | id: "datagpt", 26 | type: "misc", 27 | category: null, 28 | agency: null, 29 | }, 30 | }, 31 | }; 32 | }); 33 | 34 | export default AIChat; 35 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/lib/geojson/dun/n.09_bagan_dalam.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | type: "Feature", 3 | properties: { 4 | state: "Pulau Pinang", 5 | parlimen: "P.043 Bagan", 6 | dun: "N.09 Bagan Dalam", 7 | code_state: 7, 8 | code_parlimen: "P.043", 9 | code_dun: "N.09", 10 | code_state_dun: "7_N.09", 11 | }, 12 | geometry: { 13 | type: "MultiPolygon", 14 | coordinates: [ 15 | [ 16 | [ 17 | [100.39009, 5.41405], 18 | [100.39309, 5.41333], 19 | [100.38865, 5.41097], 20 | [100.38653, 5.4067], 21 | [100.39101, 5.39783], 22 | [100.37866, 5.39641], 23 | [100.37531, 5.38794], 24 | [100.36519, 5.38247], 25 | [100.36376, 5.38484], 26 | [100.36771, 5.38708], 27 | [100.36693, 5.38974], 28 | [100.362, 5.39409], 29 | [100.36104, 5.39879], 30 | [100.36844, 5.41339], 31 | [100.39009, 5.41405], 32 | ], 33 | ], 34 | ], 35 | }, 36 | }; 37 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "datagovmy-front", 3 | "version": "0.0.0", 4 | "private": true, 5 | "workspaces": [ 6 | "apps/*", 7 | "packages/*", 8 | "lambda/*", 9 | "tests/*" 10 | ], 11 | "scripts": { 12 | "build": "turbo run build", 13 | "dev": "turbo run dev", 14 | "lint": "turbo run lint", 15 | "e2e:test": "turbo run e2e:test", 16 | "prepare": "husky", 17 | "format": "prettier --write \"**/*.{ts,tsx,md}\"" 18 | }, 19 | "lint-staged": { 20 | "*.{js,ts,tsx,css,md}": "prettier --write" 21 | }, 22 | "devDependencies": { 23 | "autoprefixer": "^10.4.14", 24 | "eslint-config-datagovmy": "*", 25 | "husky": ">=6", 26 | "inquirer-recursive": "^0.0.7", 27 | "lint-staged": ">=10", 28 | "plop": "^3.1.2", 29 | "postcss": "^8.4.31", 30 | "prettier": "^3.2.5", 31 | "tailwindcss": "^3.3.1", 32 | "turbo": "^1.10.2", 33 | "typescript": "^5.1.3" 34 | }, 35 | "engines": { 36 | "node": ">=20.0.0" 37 | }, 38 | "packageManager": "yarn@1.22.19" 39 | } 40 | -------------------------------------------------------------------------------- /packages/datagovmy-nextra/css/scrollbar.css: -------------------------------------------------------------------------------- 1 | .nextra-scrollbar { 2 | scrollbar-width: thin; /* Firefox */ 3 | scrollbar-color: oklch(55.55% 0 0 / 40%) transparent; /* Firefox */ 4 | 5 | scrollbar-gutter: stable; 6 | &::-webkit-scrollbar { 7 | @apply h-3 w-3; 8 | } 9 | &::-webkit-scrollbar-track { 10 | @apply bg-transparent; 11 | } 12 | &::-webkit-scrollbar-thumb { 13 | @apply rounded-[10px]; 14 | } 15 | &:hover::-webkit-scrollbar-thumb { 16 | border: 3px solid transparent; 17 | background-color: var(--tw-shadow-color); 18 | background-clip: content-box; 19 | @apply shadow-neutral-500/20 hover:shadow-neutral-500/40; 20 | } 21 | 22 | @media (max-width: 767px) { 23 | .nextra-container & { 24 | scrollbar-gutter: auto; 25 | } 26 | } 27 | } 28 | 29 | /* Hide scrollbar */ 30 | .no-scrollbar { 31 | scrollbar-width: none; /* Firefox */ 32 | -ms-overflow-style: none; /* IE and Edge */ 33 | 34 | &::-webkit-scrollbar { 35 | @apply hidden; /* Chrome, Safari and Opera */ 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/charts/partials/geochoropleth.tsx: -------------------------------------------------------------------------------- 1 | import { CatalogueContext } from "../../contexts/catalogue"; 2 | import { default as dynamic } from "next/dynamic"; 3 | import { FunctionComponent, useContext } from "react"; 4 | 5 | const GeoChoropleth = dynamic(() => import("../geochoropleth"), { 6 | ssr: false, 7 | }); 8 | 9 | interface CatalogueChoroplethProps { 10 | className?: string; 11 | config: any; 12 | } 13 | 14 | const CatalogueChoropleth: FunctionComponent = ({ 15 | className = "h-[350px] w-full lg:h-[450px]", 16 | config, 17 | }) => { 18 | const { bind, dataset } = useContext(CatalogueContext); 19 | 20 | return ( 21 | 32 | ); 33 | }; 34 | 35 | export default CatalogueChoropleth; 36 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/lib/geojson/dun/n.20_kota_laksamana.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | type: "Feature", 3 | properties: { 4 | state: "Melaka", 5 | parlimen: "P.138 Kota Melaka", 6 | dun: "N.20 Kota Laksamana", 7 | code_state: 4, 8 | code_parlimen: "P.138", 9 | code_dun: "N.20", 10 | code_state_dun: "4_N.20", 11 | }, 12 | geometry: { 13 | type: "MultiPolygon", 14 | coordinates: [ 15 | [ 16 | [ 17 | [102.24066, 2.21774], 18 | [102.24556, 2.21743], 19 | [102.25663, 2.21321], 20 | [102.25286, 2.20764], 21 | [102.25253, 2.19998], 22 | [102.24789, 2.20071], 23 | [102.25055, 2.1961], 24 | [102.24388, 2.18928], 25 | [102.23257, 2.19419], 26 | [102.23747, 2.19893], 27 | [102.23672, 2.20114], 28 | [102.22757, 2.20332], 29 | [102.2276, 2.20825], 30 | [102.23405, 2.22312], 31 | [102.24066, 2.21774], 32 | ], 33 | ], 34 | ], 35 | }, 36 | }; 37 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/lib/geojson/dun/n.25_pulau_tikus.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | type: "Feature", 3 | properties: { 4 | state: "Pulau Pinang", 5 | parlimen: "P.048 Bukit Bendera", 6 | dun: "N.25 Pulau Tikus", 7 | code_state: 7, 8 | code_parlimen: "P.048", 9 | code_dun: "N.25", 10 | code_state_dun: "7_N.25", 11 | }, 12 | geometry: { 13 | type: "MultiPolygon", 14 | coordinates: [ 15 | [ 16 | [ 17 | [100.30648, 5.45164], 18 | [100.30929, 5.4405], 19 | [100.32116, 5.42977], 20 | [100.31679, 5.42442], 21 | [100.31603, 5.41286], 22 | [100.30534, 5.41863], 23 | [100.29769, 5.43295], 24 | [100.2976, 5.43919], 25 | [100.30026, 5.44126], 26 | [100.29959, 5.44516], 27 | [100.30265, 5.44527], 28 | [100.30193, 5.45261], 29 | [100.30558, 5.4512], 30 | [100.30606, 5.45304], 31 | [100.30648, 5.45164], 32 | ], 33 | ], 34 | ], 35 | }, 36 | }; 37 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/lib/geojson/dun/n.27_pengkalan_kota.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | type: "Feature", 3 | properties: { 4 | state: "Pulau Pinang", 5 | parlimen: "P.049 Tanjong", 6 | dun: "N.27 Pengkalan Kota", 7 | code_state: 7, 8 | code_parlimen: "P.049", 9 | code_dun: "N.27", 10 | code_state_dun: "7_N.27", 11 | }, 12 | geometry: { 13 | type: "MultiPolygon", 14 | coordinates: [ 15 | [ 16 | [ 17 | [100.34274, 5.41359], 18 | [100.34326, 5.41231], 19 | [100.34146, 5.41323], 20 | [100.3406, 5.41114], 21 | [100.3392, 5.41241], 22 | [100.33735, 5.4107], 23 | [100.3383, 5.40905], 24 | [100.33505, 5.40287], 25 | [100.32603, 5.40441], 26 | [100.32864, 5.41413], 27 | [100.33172, 5.41261], 28 | [100.33326, 5.41426], 29 | [100.33586, 5.41265], 30 | [100.34128, 5.41669], 31 | [100.34274, 5.41359], 32 | ], 33 | ], 34 | ], 35 | }, 36 | }; 37 | -------------------------------------------------------------------------------- /apps/app/dashboards/public-finances/public-contracting/index.tsx: -------------------------------------------------------------------------------- 1 | import { AgencyBadge, Container, Hero } from "datagovmy-ui/components"; 2 | import { useTranslation } from "datagovmy-ui/hooks"; 3 | import { FunctionComponent } from "react"; 4 | 5 | /** 6 | * PublicContracting Dashboard 7 | * @overview Status: In-development 8 | */ 9 | 10 | interface PublicContractingProps {} 11 | 12 | const PublicContracting: FunctionComponent = ({}) => { 13 | const { t, i18n } = useTranslation(["dashboard-public-contracting", "common"]); 14 | 15 | return ( 16 | <> 17 | } 23 | /> 24 | {/* Rest of page goes here */} 25 | 26 | 27 | ); 28 | }; 29 | 30 | export default PublicContracting; 31 | -------------------------------------------------------------------------------- /apps/app/pages/community/index.tsx: -------------------------------------------------------------------------------- 1 | import CommunityDashboard from "@misc/community"; 2 | import { Metadata } from "datagovmy-ui/components"; 3 | import { withi18n } from "datagovmy-ui/decorators"; 4 | import { useTranslation } from "datagovmy-ui/hooks"; 5 | import { Page } from "datagovmy-ui/types"; 6 | import { GetStaticProps, InferGetStaticPropsType } from "next"; 7 | 8 | const Community: Page = ({}: InferGetStaticPropsType) => { 9 | const { t } = useTranslation(["community", "common"]); 10 | 11 | return ( 12 | <> 13 | 14 | 15 | 16 | ); 17 | }; 18 | 19 | export const getStaticProps: GetStaticProps = withi18n("community", async () => { 20 | return { 21 | notFound: false, 22 | props: { 23 | meta: { 24 | id: "community", 25 | type: "misc", 26 | category: null, 27 | agency: null, 28 | }, 29 | }, 30 | }; 31 | }); 32 | 33 | export default Community; 34 | -------------------------------------------------------------------------------- /apps/app/pages/helpdesk/index.tsx: -------------------------------------------------------------------------------- 1 | import HelpdeskDashboard from "@misc/helpdesk"; 2 | import { Metadata } from "datagovmy-ui/components"; 3 | import { withi18n } from "datagovmy-ui/decorators"; 4 | import { useTranslation } from "datagovmy-ui/hooks"; 5 | import { Page } from "datagovmy-ui/types"; 6 | import { GetStaticProps, InferGetStaticPropsType } from "next"; 7 | 8 | const Helpdesk: Page = ({}: InferGetStaticPropsType) => { 9 | const { t } = useTranslation(["helpdesk", "common"]); 10 | 11 | return ( 12 | <> 13 | 14 | 15 | 16 | ); 17 | }; 18 | 19 | export const getStaticProps: GetStaticProps = withi18n(["helpdesk", "data-request"], async () => { 20 | return { 21 | notFound: false, 22 | props: { 23 | meta: { 24 | id: "helpdesk", 25 | type: "misc", 26 | category: null, 27 | agency: null, 28 | }, 29 | }, 30 | }; 31 | }); 32 | 33 | export default Helpdesk; 34 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/hooks/useExport.ts: -------------------------------------------------------------------------------- 1 | import { useState, useEffect } from "react"; 2 | import domtoimage from "dom-to-image"; 3 | /** 4 | * Exports any HTMLElement to inline-data 'png' or 'svg'. Only used in & 5 | * @param {boolean} mounted Hook to check if the target element is mounted. 6 | * @param id Id of the HTMLElement to export 7 | * @returns { {png: string | undefined, svg: string |undefined}} 8 | */ 9 | export const useExport = ( 10 | mounted: boolean, 11 | id: string 12 | ): { png: string | undefined; svg: string | undefined } => { 13 | const [png, setPNG] = useState(undefined); 14 | const [svg, setSvg] = useState(undefined); 15 | useEffect(() => { 16 | const element = document.getElementById(id); 17 | if (element !== null) { 18 | domtoimage.toPng(element).then(dataURL => setPNG(dataURL)); 19 | domtoimage.toSvg(element).then(dataURL => setSvg(dataURL)); 20 | } 21 | }, [mounted, id]); 22 | 23 | return { 24 | png, 25 | svg, 26 | }; 27 | }; 28 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/lib/geojson/dun/n.04_sekinchan.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | type: "Feature", 3 | properties: { 4 | state: "Selangor", 5 | parlimen: "P.093 Sungai Besar", 6 | dun: "N.04 Sekinchan", 7 | code_state: 10, 8 | code_parlimen: "P.093", 9 | code_dun: "N.04", 10 | code_state_dun: "10_N.04", 11 | }, 12 | geometry: { 13 | type: "MultiPolygon", 14 | coordinates: [ 15 | [ 16 | [ 17 | [101.27249, 3.57135], 18 | [101.17674, 3.53568], 19 | [101.10084, 3.48524], 20 | [101.09156, 3.49812], 21 | [101.08784, 3.50702], 22 | [101.08969, 3.50755], 23 | [101.08954, 3.51001], 24 | [101.08291, 3.53061], 25 | [101.06918, 3.55929], 26 | [101.11557, 3.57485], 27 | [101.09678, 3.61673], 28 | [101.16581, 3.6409], 29 | [101.21235, 3.63558], 30 | [101.30817, 3.62898], 31 | [101.34945, 3.59888], 32 | [101.27249, 3.57135], 33 | ], 34 | ], 35 | ], 36 | }, 37 | }; 38 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/lib/geojson/dun/n.10_bunut_payong.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | type: "Feature", 3 | properties: { 4 | state: "Kelantan", 5 | parlimen: "P.021 Kota Bharu", 6 | dun: "N.10 Bunut Payong", 7 | code_state: 3, 8 | code_parlimen: "P.021", 9 | code_dun: "N.10", 10 | code_state_dun: "3_N.10", 11 | }, 12 | geometry: { 13 | type: "MultiPolygon", 14 | coordinates: [ 15 | [ 16 | [ 17 | [102.24459, 6.11684], 18 | [102.24717, 6.11624], 19 | [102.2666, 6.09959], 20 | [102.26514, 6.09648], 21 | [102.25683, 6.09417], 22 | [102.25185, 6.09001], 23 | [102.24005, 6.08473], 24 | [102.23918, 6.08226], 25 | [102.23844, 6.08486], 26 | [102.22701, 6.08355], 27 | [102.22024, 6.08492], 28 | [102.21853, 6.09729], 29 | [102.22156, 6.10698], 30 | [102.22878, 6.11637], 31 | [102.23448, 6.11539], 32 | [102.24459, 6.11684], 33 | ], 34 | ], 35 | ], 36 | }, 37 | }; 38 | -------------------------------------------------------------------------------- /.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 | test-results/ 11 | playwright-report/ 12 | playwright/.cache/ 13 | tests/playground/ 14 | *-snapshots/ 15 | 16 | # next.js 17 | .next/ 18 | out/ 19 | 20 | # production 21 | /build 22 | 23 | # misc 24 | .DS_Store 25 | *.pem 26 | .vscode 27 | .idea 28 | 29 | # debug 30 | npm-debug.log* 31 | yarn-debug.log* 32 | yarn-error.log* 33 | .pnpm-debug.log* 34 | 35 | # local env files 36 | .env 37 | .env.development 38 | .env.test 39 | .env.production 40 | 41 | # vercel 42 | .vercel 43 | .turbo 44 | 45 | # typescript 46 | *.tsbuildinfo 47 | .env.local 48 | sw.js 49 | sw.js.map 50 | workbox-*.js 51 | workbox-*.js.map 52 | fallback-*.js 53 | index.html 54 | 55 | 56 | # sitemaps 57 | robots.txt 58 | sitemap-0.xml 59 | sitemap.xml 60 | 61 | # bundle-analyzer 62 | analyze 63 | 64 | # app 65 | dist/ 66 | apps/app/public/translations 67 | apps/kkmnow/public/translations 68 | apps/opendosm/public/translations -------------------------------------------------------------------------------- /apps/app/dashboards/digitalisation/government-site-tracker/index.tsx: -------------------------------------------------------------------------------- 1 | import { AgencyBadge, Container, Hero } from "datagovmy-ui/components"; 2 | import { useTranslation } from "datagovmy-ui/hooks"; 3 | import { FunctionComponent } from "react"; 4 | 5 | /** 6 | * Government Site Tracker Dashboard 7 | * @overview Status: In-development 8 | */ 9 | 10 | interface GovernmentSiteTrackerProps {} 11 | 12 | const GovernmentSiteTracker: FunctionComponent = ({}) => { 13 | const { t, i18n } = useTranslation(["dashboard-government-site-tracker", "common"]); 14 | 15 | return ( 16 | <> 17 | } 23 | /> 24 | {/* Rest of page goes here */} 25 | 26 | 27 | ); 28 | }; 29 | 30 | export default GovernmentSiteTracker; 31 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/lib/geojson/dun/n.16_perai.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | type: "Feature", 3 | properties: { 4 | state: "Pulau Pinang", 5 | parlimen: "P.046 Batu Kawan", 6 | dun: "N.16 Perai", 7 | code_state: 7, 8 | code_parlimen: "P.046", 9 | code_dun: "N.16", 10 | code_state_dun: "7_N.16", 11 | }, 12 | geometry: { 13 | type: "MultiPolygon", 14 | coordinates: [ 15 | [ 16 | [ 17 | [100.39351, 5.39727], 18 | [100.39462, 5.39156], 19 | [100.39883, 5.38886], 20 | [100.3949, 5.38071], 21 | [100.40361, 5.37608], 22 | [100.39467, 5.35899], 23 | [100.3917, 5.35463], 24 | [100.38883, 5.35371], 25 | [100.37829, 5.36857], 26 | [100.37661, 5.36812], 27 | [100.37369, 5.3752], 28 | [100.37135, 5.37387], 29 | [100.36671, 5.38222], 30 | [100.36519, 5.38247], 31 | [100.37531, 5.38794], 32 | [100.37866, 5.39641], 33 | [100.39351, 5.39727], 34 | ], 35 | ], 36 | ], 37 | }, 38 | }; 39 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/lib/geojson/dun/n.28_komtar.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | type: "Feature", 3 | properties: { 4 | state: "Pulau Pinang", 5 | parlimen: "P.049 Tanjong", 6 | dun: "N.28 Komtar", 7 | code_state: 7, 8 | code_parlimen: "P.049", 9 | code_dun: "N.28", 10 | code_state_dun: "7_N.28", 11 | }, 12 | geometry: { 13 | type: "MultiPolygon", 14 | coordinates: [ 15 | [ 16 | [ 17 | [100.33369, 5.41804], 18 | [100.33827, 5.4146], 19 | [100.33586, 5.41265], 20 | [100.33326, 5.41426], 21 | [100.33172, 5.41261], 22 | [100.32864, 5.41413], 23 | [100.32563, 5.40428], 24 | [100.32592, 5.40784], 25 | [100.32351, 5.40819], 26 | [100.32387, 5.41249], 27 | [100.31603, 5.41286], 28 | [100.31704, 5.4198], 29 | [100.32479, 5.41594], 30 | [100.32721, 5.41919], 31 | [100.32897, 5.41768], 32 | [100.33022, 5.42007], 33 | [100.33369, 5.41804], 34 | ], 35 | ], 36 | ], 37 | }, 38 | }; 39 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/styles/markdown.css: -------------------------------------------------------------------------------- 1 | /* Markdown generator */ 2 | .markdown { 3 | @apply space-y-6; 4 | } 5 | 6 | .markdown p { 7 | @apply leading-7; 8 | } 9 | 10 | .markdown code:not(pre code) { 11 | @apply bg-outline break-words rounded-md border border-black border-opacity-[0.04] px-[.25em] py-0.5 text-[.9em] dark:bg-white/10 dark:text-white; 12 | } 13 | 14 | .markdown pre { 15 | @apply bg-outline bg-primary/5 dark:bg-primary-dark/10 my-3 overflow-x-auto whitespace-pre-wrap break-words rounded-xl border border-black border-opacity-[0.04] px-3 py-3 text-[.9em] font-medium subpixel-antialiased; 16 | } 17 | 18 | .markdown ul { 19 | @apply my-5 list-inside list-disc space-y-3; 20 | } 21 | 22 | .markdown ol { 23 | @apply ml-5 list-outside list-decimal space-y-6; 24 | } 25 | 26 | .markdown li > p { 27 | @apply inline; 28 | } 29 | 30 | .markdown a { 31 | @apply text-primary dark:text-primary-dark hover:underline; 32 | } 33 | 34 | .tooltip-list ul { 35 | @apply ml-3 list-outside list-disc space-y-0.5; 36 | } 37 | 38 | .banner-markdown a { 39 | @apply text-white underline; 40 | } 41 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/lib/geojson/dun/n.08_bagan_jermal.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | type: "Feature", 3 | properties: { 4 | state: "Pulau Pinang", 5 | parlimen: "P.043 Bagan", 6 | dun: "N.08 Bagan Jermal", 7 | code_state: 7, 8 | code_parlimen: "P.043", 9 | code_dun: "N.08", 10 | code_state_dun: "7_N.08", 11 | }, 12 | geometry: { 13 | type: "MultiPolygon", 14 | coordinates: [ 15 | [ 16 | [ 17 | [100.37803, 5.43535], 18 | [100.38732, 5.43532], 19 | [100.38313, 5.42735], 20 | [100.38616, 5.42588], 21 | [100.38842, 5.4276], 22 | [100.39465, 5.42579], 23 | [100.39448, 5.42189], 24 | [100.39664, 5.41922], 25 | [100.40264, 5.41837], 26 | [100.3985, 5.41257], 27 | [100.40397, 5.41044], 28 | [100.40382, 5.40723], 29 | [100.39795, 5.40598], 30 | [100.39292, 5.41396], 31 | [100.36844, 5.41339], 32 | [100.37635, 5.43578], 33 | [100.37803, 5.43535], 34 | ], 35 | ], 36 | ], 37 | }, 38 | }; 39 | -------------------------------------------------------------------------------- /apps/app/pages/_offline.tsx: -------------------------------------------------------------------------------- 1 | import { Container, ErrorStatus, Metadata } from "datagovmy-ui/components"; 2 | import { withi18n } from "datagovmy-ui/decorators"; 3 | import { Page } from "datagovmy-ui/types"; 4 | import { GetStaticProps, InferGetStaticPropsType } from "next"; 5 | 6 | const Fallback: Page = ({}: InferGetStaticPropsType) => { 7 | return ( 8 | <> 9 | 10 | 11 | 12 | 18 | 19 | 20 | ); 21 | }; 22 | 23 | export default Fallback; 24 | 25 | export const getStaticProps: GetStaticProps = withi18n(null, async () => { 26 | return { 27 | props: { 28 | meta: { 29 | id: "error-offline", 30 | type: "misc", 31 | category: null, 32 | agency: null, 33 | }, 34 | }, 35 | }; 36 | }); 37 | -------------------------------------------------------------------------------- /packages/datagovmy-nextra/src/components/not-found.tsx: -------------------------------------------------------------------------------- 1 | import { useRouter } from "next/router"; 2 | import { useMounted } from "nextra/hooks"; 3 | import type { ReactElement } from "react"; 4 | import { useConfig } from "../contexts"; 5 | import { getGitIssueUrl, renderComponent } from "../utils"; 6 | import { Anchor } from "./anchor"; 7 | 8 | export function NotFoundPage(): ReactElement | null { 9 | const config = useConfig(); 10 | const mounted = useMounted(); 11 | const { asPath } = useRouter(); 12 | const { content, labels } = config.notFound; 13 | if (!content) { 14 | return null; 15 | } 16 | 17 | return ( 18 |

19 | 28 | {renderComponent(content)} 29 | 30 |

31 | ); 32 | } 33 | -------------------------------------------------------------------------------- /apps/dc-dev/pages/_offline.tsx: -------------------------------------------------------------------------------- 1 | import { Container, ErrorStatus, Metadata } from "datagovmy-ui/components"; 2 | import { withi18n } from "datagovmy-ui/decorators"; 3 | import { Page } from "datagovmy-ui/types"; 4 | import { GetStaticProps, InferGetStaticPropsType } from "next"; 5 | 6 | const Fallback: Page = ({}: InferGetStaticPropsType) => { 7 | return ( 8 | <> 9 | 10 | 11 | 12 | 18 | 19 | 20 | ); 21 | }; 22 | 23 | export default Fallback; 24 | 25 | export const getStaticProps: GetStaticProps = withi18n(null, async () => { 26 | return { 27 | props: { 28 | meta: { 29 | id: "error-offline", 30 | type: "misc", 31 | category: null, 32 | agency: null, 33 | }, 34 | }, 35 | }; 36 | }); 37 | -------------------------------------------------------------------------------- /packages/datagovmy-nextra/src/components/index.ts: -------------------------------------------------------------------------------- 1 | export { Anchor } from "./anchor"; 2 | export { Banner } from "./banner"; 3 | export { Bleed } from "./bleed"; 4 | export { Breadcrumb } from "./breadcrumb"; 5 | export { Cards, Card } from "./cards"; 6 | export { Collapse } from "./collapse"; 7 | export { FileTree } from "./file-tree"; 8 | export { Flexsearch } from "./flexsearch"; 9 | export { Footer } from "./footer"; 10 | export { Head } from "./head"; 11 | export { Input } from "./input"; 12 | export { LocaleSwitch } from "./locale-switch"; 13 | export { NavLinks } from "./nav-links"; 14 | export { Navbar } from "./navbar"; 15 | export { NotFoundPage } from "./not-found"; 16 | export { Search } from "./search"; 17 | export { Select } from "./select"; 18 | export { ServerSideErrorPage } from "./server-side-error"; 19 | export { Sidebar } from "./sidebar"; 20 | export { SkipNavContent, SkipNavLink } from "./skip-nav"; 21 | export { Steps } from "./steps"; 22 | export { Tabs, Tab } from "./tabs"; 23 | export { ThemeSwitch } from "./theme-switch"; 24 | export { TOC } from "./toc"; 25 | export { default as AIHelper } from "./ai-helper"; 26 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2023 data-gov-my 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/charts/partials/choropleth.tsx: -------------------------------------------------------------------------------- 1 | import { CatalogueContext } from "../../contexts/catalogue"; 2 | import { default as dynamic } from "next/dynamic"; 3 | import { FunctionComponent, useContext } from "react"; 4 | 5 | const Choropleth = dynamic(() => import("../choropleth"), { 6 | ssr: false, 7 | }); 8 | 9 | interface CatalogueChoroplethProps { 10 | className?: string; 11 | config: any; 12 | isPreview?: boolean; 13 | } 14 | 15 | const CatalogueChoropleth: FunctionComponent = ({ 16 | className = "h-[350px] w-full lg:h-[450px]", 17 | config, 18 | isPreview = false, 19 | }) => { 20 | const { bind, dataset } = useContext(CatalogueContext); 21 | 22 | return ( 23 | bind.chartjs(_ref)} 25 | className={className} 26 | enableTooltip={isPreview ? false : true} 27 | data={{ 28 | labels: dataset.chart.x, 29 | values: dataset.chart.y, 30 | }} 31 | precision={config.precision} 32 | color={config.color} 33 | type={config.geojson} 34 | /> 35 | ); 36 | }; 37 | 38 | export default CatalogueChoropleth; 39 | -------------------------------------------------------------------------------- /packages/datagovmy-nextra/src/components/server-side-error.tsx: -------------------------------------------------------------------------------- 1 | import { useRouter } from "next/router"; 2 | import { useMounted } from "nextra/hooks"; 3 | import type { ReactElement } from "react"; 4 | import { useConfig } from "../contexts"; 5 | import { getGitIssueUrl, renderComponent } from "../utils"; 6 | import { Anchor } from "./anchor"; 7 | 8 | export function ServerSideErrorPage(): ReactElement | null { 9 | const config = useConfig(); 10 | const mounted = useMounted(); 11 | const { asPath } = useRouter(); 12 | const { content, labels } = config.serverSideError; 13 | if (!content) { 14 | return null; 15 | } 16 | 17 | return ( 18 |

19 | 28 | {renderComponent(content)} 29 | 30 |

31 | ); 32 | } 33 | -------------------------------------------------------------------------------- /packages/datagovmy-nextra/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Shu Ding 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /packages/datagovmy-nextra/src/components/highlight-matches.tsx: -------------------------------------------------------------------------------- 1 | import { Fragment, memo } from "react"; 2 | 3 | type MatchArgs = { 4 | value?: string; 5 | match: string; 6 | }; 7 | 8 | export const HighlightMatches = memo(function HighlightMatches({ 9 | value, 10 | match, 11 | }: MatchArgs) { 12 | const splitText = value ? value.split("") : []; 13 | const escapedSearch = match.trim().replace(/[|\\{}()[\]^$+*?.]/g, "\\$&"); 14 | const regexp = RegExp("(" + escapedSearch.replaceAll(" ", "|") + ")", "ig"); 15 | let result; 16 | let id = 0; 17 | let index = 0; 18 | const res = []; 19 | 20 | if (value) { 21 | while ((result = regexp.exec(value)) !== null) { 22 | res.push( 23 | 24 | {splitText.splice(0, result.index - index).join("")} 25 | 26 | {splitText.splice(0, regexp.lastIndex - result.index).join("")} 27 | 28 | 29 | ); 30 | index = regexp.lastIndex; 31 | } 32 | } 33 | 34 | return ( 35 | <> 36 | {res} 37 | {splitText.join("")} 38 | 39 | ); 40 | }); 41 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/charts/chart-header.tsx: -------------------------------------------------------------------------------- 1 | import { clx } from "../lib/helpers"; 2 | import { FunctionComponent, ReactNode } from "react"; 3 | 4 | export interface ChartHeaderProps { 5 | className?: string; 6 | title?: ReactNode; 7 | controls?: ReactNode; 8 | menu?: ReactNode; 9 | } 10 | 11 | const ChartHeader: FunctionComponent = ({ title, menu, controls, className }) => { 12 | return ( 13 | <> 14 | {[title, controls, menu].some(Boolean) && ( 15 |
16 | {title && typeof title === "string" ?
{title}
: title} 17 | {menu &&
{menu}
} 18 | {controls && ( 19 |
{controls}
20 | )} 21 |
22 | {controls} 23 | {menu &&
{menu}
} 24 |
25 |
26 | )} 27 | 28 | ); 29 | }; 30 | 31 | export default ChartHeader; 32 | -------------------------------------------------------------------------------- /turbo.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://turbo.build/schema.json", 3 | "globalDependencies": ["**/.env.*local", "**/.env"], 4 | "pipeline": { 5 | "build": { 6 | "dependsOn": ["^build"], 7 | "env": [ 8 | "ANALYZE", 9 | "AUTH_TOKEN", 10 | "S3_URL", 11 | "NODE_ENV", 12 | "REVALIDATE_TOKEN", 13 | "NEXT_PUBLIC_GA_TAG", 14 | "NEXT_PUBLIC_API_URL", 15 | "NEXT_PUBLIC_AI_URL", 16 | "NEXT_PUBLIC_APP_URL", 17 | "NEXT_PUBLIC_APP_ENV", 18 | "NEXT_PUBLIC_AUTHORIZATION_TOKEN", 19 | "NEXT_PUBLIC_TILESERVER_URL", 20 | "NEXT_PUBLIC_TINYBIRD_TOKEN", 21 | "NEXT_PUBLIC_TINYBIRD_URL", 22 | "GITHUB_CLIENT_ID", 23 | "GITHUB_CLIENT_SECRET" 24 | ], 25 | "outputMode": "new-only", 26 | "outputs": ["dist/**", ".next/**", "!.next/cache/**"] 27 | }, 28 | "e2e:test": { 29 | "dependsOn": ["^build"], 30 | "outputs": ["playwright-report/**", "test-results/**"] 31 | }, 32 | "lint": { 33 | "outputs": [] 34 | }, 35 | "dev": { 36 | "cache": false, 37 | "persistent": true 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /packages/datagovmy-nextra/src/components/input.tsx: -------------------------------------------------------------------------------- 1 | import cn from "clsx"; 2 | import type { ComponentProps, ReactNode } from "react"; 3 | import { forwardRef } from "react"; 4 | 5 | type InputProps = ComponentProps<"input"> & { suffix?: ReactNode }; 6 | 7 | export const Input = forwardRef( 8 | ({ className, suffix, ...props }, forwardedRef) => ( 9 |
10 | 24 | {suffix} 25 |
26 | ) 27 | ); 28 | 29 | Input.displayName = "Input"; 30 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/lib/geojson/dun/n.26_padang_kota.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | type: "Feature", 3 | properties: { 4 | state: "Pulau Pinang", 5 | parlimen: "P.049 Tanjong", 6 | dun: "N.26 Padang Kota", 7 | code_state: 7, 8 | code_parlimen: "P.049", 9 | code_dun: "N.26", 10 | code_state_dun: "7_N.26", 11 | }, 12 | geometry: { 13 | type: "MultiPolygon", 14 | coordinates: [ 15 | [ 16 | [ 17 | [100.3219, 5.42899], 18 | [100.33098, 5.42413], 19 | [100.34476, 5.42159], 20 | [100.34583, 5.42013], 21 | [100.346, 5.41683], 22 | [100.34537, 5.41864], 23 | [100.34309, 5.41423], 24 | [100.34128, 5.41669], 25 | [100.33827, 5.4146], 26 | [100.33748, 5.41639], 27 | [100.33022, 5.42007], 28 | [100.32897, 5.41768], 29 | [100.32721, 5.41919], 30 | [100.32479, 5.41594], 31 | [100.3194, 5.41847], 32 | [100.31704, 5.4198], 33 | [100.31679, 5.42442], 34 | [100.32116, 5.42977], 35 | [100.3219, 5.42899], 36 | ], 37 | ], 38 | ], 39 | }, 40 | }; 41 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/lib/geojson/parlimen/p.049_tanjong.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | type: "Feature", 3 | properties: { 4 | state: "Pulau Pinang", 5 | parlimen: "P.049 Tanjong", 6 | code_state: 7, 7 | code_parlimen: "P.049", 8 | }, 9 | geometry: { 10 | type: "MultiPolygon", 11 | coordinates: [ 12 | [ 13 | [ 14 | [100.3218, 5.42891], 15 | [100.33088, 5.42404], 16 | [100.33991, 5.42332], 17 | [100.34573, 5.42005], 18 | [100.3459, 5.41675], 19 | [100.34528, 5.41856], 20 | [100.34265, 5.41351], 21 | [100.34354, 5.41253], 22 | [100.34036, 5.41285], 23 | [100.3405, 5.41105], 24 | [100.3391, 5.41233], 25 | [100.33725, 5.41061], 26 | [100.3382, 5.40896], 27 | [100.33495, 5.40278], 28 | [100.32528, 5.40429], 29 | [100.32583, 5.40775], 30 | [100.32341, 5.4081], 31 | [100.32377, 5.41241], 32 | [100.31594, 5.41277], 33 | [100.31669, 5.42434], 34 | [100.32106, 5.42968], 35 | [100.3218, 5.42891], 36 | ], 37 | ], 38 | ], 39 | }, 40 | }; 41 | -------------------------------------------------------------------------------- /apps/dc-dev/pages/_app.tsx: -------------------------------------------------------------------------------- 1 | import Nexti18NextConfig from "../next-i18next.config"; 2 | import "datagovmy-ui/styles"; 3 | import Layout from "@components/Layout"; 4 | import { Progress, Toast } from "datagovmy-ui/components"; 5 | import { header, body } from "datagovmy-ui/configs/font"; 6 | import { clx } from "datagovmy-ui/helpers"; 7 | import { AppPropsLayout } from "datagovmy-ui/types"; 8 | import { appWithTranslation } from "next-i18next"; 9 | import { ThemeProvider } from "next-themes"; 10 | import { ReactNode } from "react"; 11 | 12 | // App instance 13 | function App({ Component, pageProps }: AppPropsLayout) { 14 | const layout = 15 | Component.layout || 16 | ((page: ReactNode) => {page}); 17 | 18 | return ( 19 |
20 | 21 | {layout(, pageProps)} 22 | 23 | 24 | 25 |
26 | ); 27 | } 28 | 29 | export default appWithTranslation(App, Nexti18NextConfig); 30 | -------------------------------------------------------------------------------- /apps/docs/next.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next').NextConfig} */ 2 | const config = { 3 | i18n: { 4 | locales: ["en", "ms"], 5 | defaultLocale: "en", 6 | }, 7 | async rewrites() { 8 | return [ 9 | { 10 | source: "/mp/lib.min.js", 11 | destination: "https://cdn.mxpnl.com/libs/mixpanel-2-latest.min.js", 12 | }, 13 | { 14 | source: "/mp/lib.js", 15 | destination: "https://cdn.mxpnl.com/libs/mixpanel-2-latest.js", 16 | }, 17 | { 18 | source: "/mp/decide", 19 | destination: "https://decide.mixpanel.com/decide", 20 | }, 21 | { 22 | source: "/mp/:slug*", 23 | destination: "https://api.mixpanel.com/:slug*", 24 | }, 25 | ]; 26 | }, 27 | }; 28 | 29 | /** @type {import('nextra').NextraConfig} */ 30 | const nextra = require("nextra")({ 31 | theme: "datagovmy-nextra", 32 | themeConfig: "./theme.config.tsx", 33 | staticImage: true, 34 | latex: true, 35 | flexsearch: { 36 | codeblock: false, 37 | }, 38 | }); 39 | 40 | module.exports = () => { 41 | const plugins = [nextra]; // add analyzer here later 42 | return plugins.reduce((acc, next) => next(acc), config); 43 | }; 44 | -------------------------------------------------------------------------------- /apps/docs/pages/authentication.en.mdx: -------------------------------------------------------------------------------- 1 | ## Requesting an API Token 2 | 3 | While accessing the OpenAPI does not require an API token, we provide the option to request a token if you anticipate reaching the rate limits or need increased usage. To request an API token, please follow the steps below: 4 | 5 | 1. Send an email to [dataterbuka@jdn.gov.my](mailto:dataterbuka@jdn.gov.my) with the following details: 6 | 7 | - Your name 8 | - Your email address 9 | - Reason for requesting an increased rate limit 10 | 11 | 2. Our team will review your request and assess it on a case-by-case basis. 12 | 13 | 3. If your request is approved, you will receive an API token via email. 14 | 15 | ## Using Your API Token 16 | 17 | Once you have obtained an API token, you need to include it in your API requests to authenticate and gain access to increased usage limits. Follow the steps below to include your API token in the HTTP requests: 18 | 19 | 1. Add the following header to your request: 20 | 21 | ``` 22 | Authorization: Token 23 | ``` 24 | 25 | Replace `` with the actual token you received. 26 | 27 | 2. Send your HTTP request with the added `Authorization` header. 28 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/script/barrel_geojson.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Script. 3 | 4 | * Arguments: 5 | * - type: "district" | "parlimen" | "dun" | "state" 6 | * - input: Path to GeoJSON object (.json) 7 | */ 8 | 9 | import fs from "fs"; 10 | import path from "path"; 11 | import { fileURLToPath } from "url"; 12 | 13 | const __filename = fileURLToPath(import.meta.url); 14 | const __dirname = path.dirname(__filename); 15 | 16 | function main() { 17 | const ROOT_DIR = path.join(__dirname, ".."); 18 | 19 | const [type, input] = process.argv.slice(2); 20 | const dir = path.join(ROOT_DIR, "./src/lib/geojson", type); 21 | 22 | let barrel = ""; 23 | 24 | fs.readdirSync(dir).forEach(file => { 25 | // Ignore all files prefixed with _ 26 | if (file.at(0) === "_") return; 27 | 28 | // Remove extension 29 | const _file = file.replace(".ts", ""); 30 | 31 | // Add to barrel export 32 | barrel += `"${_file}": import("./${_file}").then(module => module.default),\n`; 33 | }); 34 | 35 | fs.appendFileSync(path.join(dir, "index.ts"), template(barrel), "utf-8"); 36 | } 37 | 38 | const template = feature => { 39 | return `export default {\n${feature}}`; 40 | }; 41 | 42 | /** Execution */ 43 | main(); 44 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/charts/partials/mapplot.tsx: -------------------------------------------------------------------------------- 1 | import { default as dynamic } from "next/dynamic"; 2 | import { FunctionComponent, useContext, useMemo } from "react"; 3 | import { MarkerData } from "../map-plot"; 4 | import { CatalogueContext } from "../../contexts/catalogue"; 5 | 6 | const MapPlot = dynamic(() => import("../map-plot"), { 7 | ssr: false, 8 | }); 9 | interface CatalogueMapPlotProps { 10 | className?: string; 11 | } 12 | 13 | const CatalogueMapPlot: FunctionComponent = ({ 14 | className = "h-[350px] w-full lg:h-[450px]", 15 | }) => { 16 | const { bind, dataset } = useContext(CatalogueContext); 17 | 18 | const markers = useMemo(() => { 19 | const _markers: MarkerData = dataset.chart.map((e: any) => { 20 | const { position, ...tooltip } = e; 21 | return { 22 | position: position, 23 | tooltip: tooltip, 24 | }; 25 | }); 26 | return _markers; 27 | }, [dataset.chart]); 28 | 29 | return ( 30 | 36 | ); 37 | }; 38 | 39 | export default CatalogueMapPlot; 40 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/charts/partials/heatmap.tsx: -------------------------------------------------------------------------------- 1 | import { CatalogueContext } from "../../contexts/catalogue"; 2 | import { HeatmapData, HeatmapDatum } from "../heatmap"; 3 | import { default as dynamic } from "next/dynamic"; 4 | import { FunctionComponent, useContext, useMemo } from "react"; 5 | 6 | const Heatmap = dynamic(() => import("../heatmap"), { 7 | ssr: false, 8 | }); 9 | 10 | interface CatalogueHeatmapProps { 11 | className?: string; 12 | config: any; 13 | translations: any; 14 | } 15 | 16 | const CatalogueHeatmap: FunctionComponent = ({ 17 | className, 18 | config, 19 | translations, 20 | }) => { 21 | const { bind, dataset } = useContext(CatalogueContext); 22 | 23 | const _datasets = useMemo(() => { 24 | return dataset.chart.map((item: HeatmapDatum) => ({ 25 | x: translations[item.x] ?? item.x, 26 | y: translations[item.y] ?? item.y, 27 | z: item.z, 28 | })); 29 | }, [dataset.chart]); 30 | 31 | return ( 32 | bind.chartjs(ref)} 34 | className={className} 35 | data={_datasets} 36 | color={config.color} 37 | /> 38 | ); 39 | }; 40 | 41 | export default CatalogueHeatmap; 42 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/components/LeftRightCard/index.tsx: -------------------------------------------------------------------------------- 1 | import { FunctionComponent, ReactNode } from "react"; 2 | import { clx } from "../../lib/helpers"; 3 | 4 | interface CardProps { 5 | left: ReactNode; 6 | right: ReactNode; 7 | leftBg?: string; 8 | rightBg?: string; 9 | } 10 | 11 | /** 12 | * Left = description 13 | * Right = interactive area 14 | * @param left 15 | * @param right 16 | * @returns 17 | */ 18 | 19 | const LeftRightCard: FunctionComponent = ({ 20 | left, 21 | right, 22 | leftBg = "dark:bg-washed-dark/50", 23 | rightBg = "bg-background dark:bg-black", 24 | }) => { 25 | return ( 26 | <> 27 |
28 |
34 | {left} 35 |
36 |
{right}
37 |
38 | 39 | ); 40 | }; 41 | 42 | export default LeftRightCard; 43 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/lib/geojson/dun/n.09_padungan.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | type: "Feature", 3 | properties: { 4 | state: "Sarawak", 5 | parlimen: "P.195 Bandar Kuching", 6 | dun: "N.09 Padungan", 7 | code_state: 13, 8 | code_parlimen: "P.195", 9 | code_dun: "N.09", 10 | code_state_dun: "13_N.09", 11 | }, 12 | geometry: { 13 | type: "MultiPolygon", 14 | coordinates: [ 15 | [ 16 | [ 17 | [110.34284, 1.55894], 18 | [110.35201, 1.55949], 19 | [110.36305, 1.55636], 20 | [110.36188, 1.55258], 21 | [110.35903, 1.55233], 22 | [110.36111, 1.54858], 23 | [110.34883, 1.5425], 24 | [110.34042, 1.53431], 25 | [110.33034, 1.53833], 26 | [110.33088, 1.54912], 27 | [110.33217, 1.55019], 28 | [110.33841, 1.54864], 29 | [110.33859, 1.55046], 30 | [110.34204, 1.55214], 31 | [110.34088, 1.55562], 32 | [110.33723, 1.55703], 33 | [110.33653, 1.55593], 34 | [110.33254, 1.56025], 35 | [110.33767, 1.56168], 36 | [110.34284, 1.55894], 37 | ], 38 | ], 39 | ], 40 | }, 41 | }; 42 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/lib/geojson/dun/n.33_air_itam.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | type: "Feature", 3 | properties: { 4 | state: "Pulau Pinang", 5 | parlimen: "P.051 Bukit Gelugor", 6 | dun: "N.33 Air Itam", 7 | code_state: 7, 8 | code_parlimen: "P.051", 9 | code_dun: "N.33", 10 | code_state_dun: "7_N.33", 11 | }, 12 | geometry: { 13 | type: "MultiPolygon", 14 | coordinates: [ 15 | [ 16 | [ 17 | [100.30276, 5.40758], 18 | [100.30368, 5.39867], 19 | [100.29705, 5.4006], 20 | [100.29488, 5.39778], 21 | [100.29194, 5.39749], 22 | [100.29099, 5.39523], 23 | [100.28961, 5.39622], 24 | [100.28818, 5.3937], 25 | [100.28361, 5.39372], 26 | [100.28011, 5.39565], 27 | [100.27803, 5.39487], 28 | [100.27675, 5.39626], 29 | [100.27558, 5.39418], 30 | [100.27253, 5.3952], 31 | [100.27502, 5.40054], 32 | [100.28304, 5.40572], 33 | [100.28527, 5.40444], 34 | [100.29136, 5.40479], 35 | [100.29816, 5.40771], 36 | [100.30276, 5.40758], 37 | ], 38 | ], 39 | ], 40 | }, 41 | }; 42 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/lib/geojson/state/index.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | "johor": import("./johor").then(module => module.default), 3 | "kedah": import("./kedah").then(module => module.default), 4 | "kelantan": import("./kelantan").then(module => module.default), 5 | "melaka": import("./melaka").then(module => module.default), 6 | "negeri_sembilan": import("./negeri_sembilan").then(module => module.default), 7 | "pahang": import("./pahang").then(module => module.default), 8 | "perak": import("./perak").then(module => module.default), 9 | "perlis": import("./perlis").then(module => module.default), 10 | "pulau_pinang": import("./pulau_pinang").then(module => module.default), 11 | "sabah": import("./sabah").then(module => module.default), 12 | "sarawak": import("./sarawak").then(module => module.default), 13 | "selangor": import("./selangor").then(module => module.default), 14 | "terengganu": import("./terengganu").then(module => module.default), 15 | "w.p._kuala_lumpur": import("./w.p._kuala_lumpur").then(module => module.default), 16 | "w.p._labuan": import("./w.p._labuan").then(module => module.default), 17 | "w.p._putrajaya": import("./w.p._putrajaya").then(module => module.default), 18 | }; 19 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/i18n/index.cjs: -------------------------------------------------------------------------------- 1 | const I18NextHttpBackend = require("i18next-http-backend/cjs"); 2 | // const path = require("path"); 3 | 4 | /** @type {import('next-i18next').UserConfig} */ 5 | const defineConfig = (namespace, autoloadNs) => { 6 | return { 7 | i18n: { 8 | defaultLocale: "en-GB", 9 | locales: ["en-GB", "ms-MY"], 10 | // USE THIS for local translation file 11 | // localePath: 12 | // typeof window === "undefined" 13 | // ? require("path").resolve("./public/translations") 14 | // : "./public/translations", 15 | }, 16 | backend: { 17 | loadPath: `${process.env.NEXT_PUBLIC_I18N_URL}/${ 18 | process.env.NEXT_PUBLIC_APP_ENV === "production" ? "production" : "staging" 19 | }/{{lng}}/{{ns}}.json`, 20 | crossDomain: true, 21 | allowMultiLoading: true, 22 | }, 23 | debug: false, 24 | ns: namespace, 25 | autoloadNs: autoloadNs, 26 | load: "currentOnly", 27 | preload: ["en-GB", "ms-MY"], 28 | serializeConfig: false, 29 | reloadOnPrerender: true, 30 | // COMMENT this line to use local translation 31 | use: [I18NextHttpBackend], 32 | }; 33 | }; 34 | 35 | module.exports = defineConfig; 36 | -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/lib/geojson/dun/n.47_kempas.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | type: "Feature", 3 | properties: { 4 | state: "Johor", 5 | parlimen: "P.161 Pulai", 6 | dun: "N.47 Kempas", 7 | code_state: 1, 8 | code_parlimen: "P.161", 9 | code_dun: "N.47", 10 | code_state_dun: "1_N.47", 11 | }, 12 | geometry: { 13 | type: "MultiPolygon", 14 | coordinates: [ 15 | [ 16 | [ 17 | [103.70673, 1.53983], 18 | [103.71295, 1.54018], 19 | [103.72627, 1.53274], 20 | [103.73233, 1.53144], 21 | [103.74209, 1.51546], 22 | [103.73632, 1.51419], 23 | [103.73037, 1.50987], 24 | [103.71977, 1.50953], 25 | [103.71503, 1.50768], 26 | [103.71295, 1.50344], 27 | [103.70854, 1.50078], 28 | [103.70938, 1.49538], 29 | [103.70731, 1.49244], 30 | [103.69145, 1.50436], 31 | [103.6888, 1.50897], 32 | [103.68255, 1.5138], 33 | [103.68008, 1.52121], 34 | [103.68756, 1.53383], 35 | [103.69587, 1.54274], 36 | [103.70047, 1.54437], 37 | [103.70673, 1.53983], 38 | ], 39 | ], 40 | ], 41 | }, 42 | }; 43 | -------------------------------------------------------------------------------- /apps/app/pages/api/embed.ts: -------------------------------------------------------------------------------- 1 | import { AxiosResponse } from "axios"; 2 | import { get } from "datagovmy-ui/api"; 3 | import { SHORT_LANG } from "datagovmy-ui/constants"; 4 | import { DCFilter, DCVariable } from "datagovmy-ui/data-catalogue"; 5 | import { NextApiRequest, NextApiResponse } from "next"; 6 | 7 | /** 8 | * GET endpoint for embed preview 9 | * @param req Request 10 | * @param res Response 11 | * @returns {RevalidateData} Result 12 | */ 13 | export default async function handler(req: NextApiRequest, res: NextApiResponse) { 14 | try { 15 | const { id, lang, ...query } = req.query; 16 | const { data } = (await get(`/data-catalogue/${id}`, { 17 | language: SHORT_LANG[lang as keyof typeof SHORT_LANG], 18 | ...query, 19 | })) as AxiosResponse; 20 | 21 | return res 22 | .setHeader("Cache-Control", "public, s-maxage=21600, stale-while-revalidate=21600") // 30 min 23 | .json({ 24 | params: { 25 | id: id ?? null, 26 | }, 27 | options: data.dropdown.filter((item: DCFilter) => item.name !== "date_slider") ?? null, 28 | }); 29 | } catch (err: any) { 30 | return res.status(400).json({ error: "Bad request", authorized: false }); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /packages/datagovmy-nextra/src/components/text-area.tsx: -------------------------------------------------------------------------------- 1 | import cn from "clsx"; 2 | import type { ComponentProps, ReactNode } from "react"; 3 | import { forwardRef } from "react"; 4 | 5 | type TextareaProps = ComponentProps<"textarea"> & { suffix?: ReactNode }; 6 | 7 | export const Textarea = forwardRef( 8 | ({ className, suffix, ...props }, forwardedRef) => ( 9 |
10 |
8 | ); 9 | -------------------------------------------------------------------------------- /packages/datagovmy-nextra/postcss.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('postcss').Postcss} */ 2 | module.exports = { 3 | plugins: { 4 | "postcss-import": {}, 5 | "tailwindcss/nesting": {}, 6 | "tailwindcss": {}, 7 | "postcss-lightningcss": { 8 | browsers: ">= .25%", 9 | }, 10 | }, 11 | }; 12 | -------------------------------------------------------------------------------- /packages/tsconfig/react-library.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "https://json.schemastore.org/tsconfig", 3 | "display": "React Library", 4 | "extends": "./base.json", 5 | "compilerOptions": { 6 | "jsx": "react-jsx", 7 | "lib": ["ES2015"], 8 | "module": "ESNext", 9 | "target": "es6" 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /apps/docs/.env.example: -------------------------------------------------------------------------------- 1 | APP_URL=http://localhost:3001 2 | APP_ENV=development 3 | AUTHORIZATION_TOKEN= 4 | EDGE_CONFIG= 5 | 6 | NEXT_PUBLIC_APP_URL=$APP_URL 7 | NEXT_PUBLIC_APP_ENV=$APP_ENV 8 | NEXT_PUBLIC_AUTHORIZATION_TOKEN=$AUTHORIZATION_TOKEN 9 | 10 | #MIXPANEL 11 | MIXPANEL_TOKEN= 12 | NEXT_PUBLIC_MIXPANEL_TOKEN=$MIXPANEL_TOKEN -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/configs/mixpanel.ts: -------------------------------------------------------------------------------- 1 | export default { 2 | name: "instance", 3 | id: process.env.MIXPANEL_PROJECT_ID, 4 | token: process.env.NEXT_PUBLIC_MIXPANEL_TOKEN, 5 | host: process.env.NEXT_PUBLIC_APP_URL.concat("/mp"), 6 | user: process.env.MIXPANEL_SA_USER, 7 | secret: process.env.MIXPANEL_SA_SECRET, 8 | } as const; 9 | -------------------------------------------------------------------------------- /packages/datagovmy-nextra/src/components/th.tsx: -------------------------------------------------------------------------------- 1 | import type { ComponentProps } from "react"; 2 | 3 | export const Th = ({ className = "", ...props }: ComponentProps<"th">) => ( 4 | 10 | ); 11 | -------------------------------------------------------------------------------- /apps/app/next-sitemap.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next-sitemap').IConfig} */ 2 | module.exports = { 3 | siteUrl: process.env.APP_URL || "https://data.gov.my", 4 | generateIndexSitemap: true, 5 | generateRobotsTxt: true, 6 | priority: 0.7, 7 | autoLastmod: true, 8 | outDir: "public", 9 | exclude: ["/404", "/ms-MY/404", "500", "/ms-MY/500"], 10 | }; 11 | -------------------------------------------------------------------------------- /apps/docs/next-sitemap.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next-sitemap').IConfig} */ 2 | module.exports = { 3 | siteUrl: process.env.APP_URL || "https://developer.data.gov.my", 4 | generateIndexSitemap: true, 5 | generateRobotsTxt: true, 6 | priority: 0.7, 7 | autoLastmod: true, 8 | outDir: "public", 9 | exclude: ["/404", "/ms/404", "500", "/ms/500"], 10 | }; 11 | -------------------------------------------------------------------------------- /packages/datagovmy-nextra/src/contexts/details.ts: -------------------------------------------------------------------------------- 1 | import { Dispatch, SetStateAction } from "react"; 2 | import { createContext, useContext } from "react"; 3 | 4 | const DetailsContext = createContext>>(v => v); 5 | 6 | export const useDetails = () => useContext(DetailsContext); 7 | 8 | export const DetailsProvider = DetailsContext.Provider; 9 | -------------------------------------------------------------------------------- /apps/dc-dev/next-sitemap.config.js: -------------------------------------------------------------------------------- 1 | /** @type {import('next-sitemap').IConfig} */ 2 | module.exports = { 3 | siteUrl: process.env.APP_URL || "https://dev.data.gov.my", 4 | generateIndexSitemap: true, 5 | generateRobotsTxt: true, 6 | priority: 0.7, 7 | autoLastmod: true, 8 | outDir: "public", 9 | exclude: ["/404", "/ms-MY/404", "500", "/ms-MY/500"], 10 | }; 11 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # dependencies 2 | node_modules 3 | /.pnp 4 | .pnp.js 5 | 6 | # next.js 7 | .next/ 8 | /out/ 9 | 10 | # production 11 | /build 12 | 13 | # misc 14 | .DS_Store 15 | *.pem 16 | 17 | # debug 18 | npm-debug.log* 19 | yarn-debug.log* 20 | yarn-error.log* 21 | 22 | # local env files 23 | .env 24 | .env.development 25 | .env.production 26 | 27 | # vercel 28 | .vercel -------------------------------------------------------------------------------- /packages/datagovmy-ui/src/configs/font.ts: -------------------------------------------------------------------------------- 1 | import { Poppins, Inter } from "next/font/google"; 2 | 3 | const header = Poppins({ 4 | weight: ["700"], 5 | subsets: ["latin"], 6 | variable: "--font-header", 7 | }); 8 | 9 | const body = Inter({ 10 | weight: ["400", "500", "600", "700"], 11 | subsets: ["latin"], 12 | variable: "--font-body", 13 | }); 14 | 15 | export { header, body }; 16 | -------------------------------------------------------------------------------- /apps/app/pages/gui/index.tsx: -------------------------------------------------------------------------------- 1 | import { GetServerSideProps } from "next"; 2 | import { routes } from "@lib/routes"; 3 | 4 | export const getServerSideProps: GetServerSideProps = async () => { 5 | return { 6 | redirect: { 7 | destination: routes.GUI_CATALOGUE, 8 | permanent: false, 9 | }, 10 | }; 11 | }; 12 | 13 | export default function GUIPage() { 14 | return null; 15 | } 16 | -------------------------------------------------------------------------------- /packages/datagovmy-nextra/src/components/tr.tsx: -------------------------------------------------------------------------------- 1 | import type { ComponentProps } from "react"; 2 | 3 | export const Tr = ({ className = "", ...props }: ComponentProps<"tr">) => ( 4 |