diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..35a1677 --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,30 @@ +stages: + - build + - deploy + +build-dev: + stage: build + when: on_success + only: + - main + image: + name: docker:25.0.3-cli + services: + - name: docker:25.0.3-dind + command: ["--insecure-registry=103.82.242.92:8900"] + script: + - docker logout + - docker login -u $DEPLOY_USERNAME -p $DEPLOY_TOKEN 103.82.242.92:8900 + - docker build -t 103.82.242.92:8900/medols/web-mikul-news:dev . + - docker push 103.82.242.92:8900/medols/web-mikul-news:dev + +auto-deploy: + stage: deploy + when: on_success + only: + - main + image: curlimages/curl:latest + services: + - docker:dind + script: + - curl --user admin:$JENKINS_PWD http://103.31.38.120:8080/job/auto-deploy-mikul-news/build?token=autodeploymedols diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..2b874db --- /dev/null +++ b/Dockerfile @@ -0,0 +1,36 @@ +# Menggunakan image Node.js yang lebih ringan +FROM node:23.5.0-alpine + +# Mengatur port +ENV PORT 3000 + +# Install pnpm secara global +RUN npm install -g pnpm + +# Membuat direktori aplikasi dan mengatur sebagai working directory +WORKDIR /usr/src/app + +# Menyalin file penting terlebih dahulu untuk caching +COPY package.json ./ + +# Menyalin direktori ckeditor5 jika diperlukan +COPY vendor/ckeditor5 ./vendor/ckeditor5 + +# Menyalin env +COPY .env .env + +# Install dependencies +RUN pnpm install +# RUN pnpm install --frozen-lockfile + +# Menyalin source code aplikasi +COPY . . + +# Build aplikasi +RUN NODE_OPTIONS="--max-old-space-size=4096" pnpm next build + +# Expose port untuk server +EXPOSE 3000 + +# Perintah untuk menjalankan aplikasi +CMD ["pnpm", "run", "start"] \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 7157ca5..7c010b1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,7 @@ "@radix-ui/react-slot": "^1.2.4", "@radix-ui/react-tabs": "^1.1.13", "@types/js-cookie": "^3.0.6", + "axios": "^1.10.0", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "date-fns": "^4.1.0", @@ -1875,6 +1876,33 @@ "node": ">=10" } }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + }, + "node_modules/axios": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.10.0.tgz", + "integrity": "sha512-/1xYAC4MP/HEG+3duIhFr4ZQXR4sQXOIe+o6sdqzeykGLx6Upp/1p8MHqhINOvGeP7xyNHe7tsiJByc4SSVUxw==", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/caniuse-lite": { "version": "1.0.30001753", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001753.tgz", @@ -1918,6 +1946,17 @@ "node": ">=6" } }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/csstype": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", @@ -1938,6 +1977,14 @@ "resolved": "https://registry.npmjs.org/date-fns-jalali/-/date-fns-jalali-4.1.0-0.tgz", "integrity": "sha512-hTIP/z+t+qKwBDcmmsnmjWTduxCg+5KfdqWQvb2X/8C9+knYY6epN/pfxdDuyVlSVeFz0sM5eEfwIUQ70U4ckg==" }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/detect-libc": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", @@ -1952,6 +1999,19 @@ "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/enhanced-resolve": { "version": "5.18.3", "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.18.3.tgz", @@ -1965,6 +2025,112 @@ "node": ">=10.13.0" } }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/follow-redirects": { + "version": "1.15.11", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.11.tgz", + "integrity": "sha512-deG2P0JfjrTxl50XGCDyfI97ZGVCxIpfKYmfyrQ54n5FO/0gfIES8C/Psl6kWVDolizcaaxZJnTS0QSMxvnsBQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/form-data": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.4.tgz", + "integrity": "sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "hasown": "^2.0.2", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", + "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", + "dependencies": { + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.1", + "function-bind": "^1.1.2", + "get-proto": "^1.0.1", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/get-nonce": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", @@ -1973,12 +2139,71 @@ "node": ">=6" } }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/jiti": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz", @@ -2278,6 +2503,33 @@ "@jridgewell/sourcemap-codec": "^1.5.5" } }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/nanoid": { "version": "3.3.11", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", @@ -2424,6 +2676,11 @@ "react-is": "^16.13.1" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/react": { "version": "19.2.0", "resolved": "https://registry.npmjs.org/react/-/react-19.2.0.tgz", diff --git a/package.json b/package.json index dfd5cce..59fcce6 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "@radix-ui/react-slot": "^1.2.4", "@radix-ui/react-tabs": "^1.1.13", "@types/js-cookie": "^3.0.6", + "axios": "^1.10.0", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "date-fns": "^4.1.0", diff --git a/service/activity-log.ts b/service/activity-log.ts new file mode 100644 index 0000000..98634ee --- /dev/null +++ b/service/activity-log.ts @@ -0,0 +1,19 @@ +import { httpGet, httpPost } from "./http-config/http-base-services"; + +export async function saveActivity(data: any, token?: string) { + const headers = token + ? { + "content-type": "application/json", + Authorization: `Bearer ${token}`, + } + : { + "content-type": "application/json", + }; + const pathUrl = `/activity-logs`; + return await httpPost(pathUrl, data, headers); +} + +export async function getActivity() { + const pathUrl = `/activity-logs/statistics`; + return await httpGet(pathUrl); +} diff --git a/service/advertisement.ts b/service/advertisement.ts new file mode 100644 index 0000000..02399ac --- /dev/null +++ b/service/advertisement.ts @@ -0,0 +1,49 @@ +import Cookies from "js-cookie"; +import { + httpDeleteInterceptor, + httpPostInterceptor, + httpPutInterceptor, +} from "./http-config/http-interceptor-services"; +import { httpGet } from "./http-config/http-base-services"; + +const token = Cookies.get("access_token"); + +export async function createAdvertise(data: any) { + const pathUrl = `/advertisement`; + return await httpPostInterceptor(pathUrl, data); +} + +export async function createMediaFileAdvertise(id: string | number, data: any) { + const headers = { + "Content-Type": "multipart/form-data", + }; + const pathUrl = `/advertisement/upload/${id}`; + return await httpPostInterceptor(pathUrl, data, headers); +} + +export async function getAdvertise(data: any) { + const pathUrl = `/advertisement?page=${data?.page || 1}&limit=${ + data?.limit || "" + }&placement=${data?.placement || ""}&isPublish=${data.isPublish || ""}`; + return await httpGet(pathUrl); +} + +export async function getAdvertiseById(id: number) { + const pathUrl = `/advertisement/${id}`; + return await httpGet(pathUrl); +} + +export async function editAdvertise(data: any) { + const pathUrl = `/advertisement/${data?.id}`; + return await httpPutInterceptor(pathUrl, data); +} + +export async function editAdvertiseIsActive(data: any) { + const pathUrl = `/advertisement/publish/${data?.id}?isPublish=${data?.isActive}`; + return await httpPutInterceptor(pathUrl, data); +} + +export async function deleteAdvertise(id: number) { + const pathUrl = `/advertisement/${id}`; + return await httpDeleteInterceptor(pathUrl); +} diff --git a/service/article.ts b/service/article.ts new file mode 100644 index 0000000..4f338cd --- /dev/null +++ b/service/article.ts @@ -0,0 +1,182 @@ +import { PaginationRequest } from "@/types/globals"; +import { httpGet } from "./http-config/http-base-services"; +import { + httpDeleteInterceptor, + httpGetInterceptor, + httpPostInterceptor, + httpPutInterceptor, +} from "./http-config/http-interceptor-services"; + +export async function getListArticle(props: PaginationRequest) { + const { + page, + limit, + search, + startDate, + endDate, + isPublish, + category, + sortBy, + sort, + categorySlug, + isBanner, + } = props; + + return await httpGet( + `/articles?limit=${limit}&page=${page}&isPublish=${ + isPublish === undefined ? "" : isPublish + }&title=${search}&startDate=${startDate || ""}&endDate=${ + endDate || "" + }&categoryId=${category || ""}&sortBy=${sortBy || "created_at"}&sort=${ + sort || "desc" + }&category=${categorySlug || ""}&isBanner=${isBanner || ""}`, + null + ); +} + +export async function getArticlePagination(props: PaginationRequest) { + const { + page, + limit, + search, + startDate, + endDate, + category, + sortBy, + sort, + categorySlug, + isBanner, + isPublish, + source, + } = props; + + return await httpGetInterceptor( + `/articles?limit=${limit}&page=${page}&title=${search}&startDate=${ + startDate || "" + }&endDate=${endDate || ""}&categoryId=${category || ""}&source=${ + source || "" + }&isPublish=${isPublish !== undefined ? isPublish : ""}&sortBy=${ + sortBy || "created_at" + }&sort=${sort || "asc"}&category=${categorySlug || ""}&isBanner=${ + isBanner || "" + }` + ); +} + +export async function getTopArticles(props: PaginationRequest) { + const { page, limit, search, startDate, endDate, isPublish, category } = + props; + const headers = { + "content-type": "application/json", + }; + return await httpGet( + `/articles?limit=${limit}&page=${page}&isPublish=${ + isPublish === undefined ? "" : isPublish + }&title=${search}&startDate=${startDate || ""}&endDate=${ + endDate || "" + }&category=${category || ""}&sortBy=view_count&sort=desc`, + headers + ); +} + +export async function createArticle(data: any) { + const pathUrl = `/articles`; + return await httpPostInterceptor(pathUrl, data); +} + +export async function createArticleSchedule(data: any) { + const pathUrl = `/articles/publish-scheduling?id=${data.id}&date=${data.date}`; + return await httpPostInterceptor(pathUrl, data); +} + +export async function updateArticle(id: string, data: any) { + const pathUrl = `/articles/${id}`; + return await httpPutInterceptor(pathUrl, data); +} + +export async function unPublishArticle(id: string, data: any) { + const pathUrl = `/articles/${id}/unpublish`; + return await httpPutInterceptor(pathUrl, data); +} + +export async function getArticleById(id: any) { + const headers = { + "content-type": "application/json", + }; + return await httpGet(`/articles/${id}`, headers); +} + +export async function getArticleBySlug(slug: any) { + const headers = { + "content-type": "application/json", + }; + return await httpGet(`/articles/slug/${slug}`, headers); +} + +export async function deleteArticle(id: string) { + const headers = { + "content-type": "application/json", + }; + return await httpDeleteInterceptor(`articles/${id}`, headers); +} + +export async function getArticleByCategory() { + return await httpGetInterceptor(`/article-categories?limit=1000`); +} +export async function getCategoryPagination(data: any) { + return await httpGet( + `/article-categories?limit=${data?.limit}&page=${data?.page}&title=${data?.search}` + ); +} + +export async function uploadArticleFile(id: string, data: any) { + const headers = { + "content-type": "multipart/form-data", + }; + return await httpPostInterceptor(`/article-files/${id}`, data, headers); +} + +export async function uploadArticleThumbnail(id: string, data: any) { + const headers = { + "content-type": "multipart/form-data", + }; + return await httpPostInterceptor(`/articles/thumbnail/${id}`, data, headers); +} + +export async function deleteArticleFiles(id: number) { + const headers = { + "content-type": "multipart/form-data", + }; + return await httpDeleteInterceptor(`article-files/${id}`, headers); +} + +export async function getUserLevelDataStat(startDate: string, endDate: string) { + return await httpGet( + `/articles/statistic/user-levels?startDate=${startDate}&endDate=${endDate}` + ); +} +export async function getStatisticMonthly(year: string) { + return await httpGet(`/articles/statistic/monthly?year=${year}`); +} +export async function getStatisticMonthlyFeedback(year: string) { + return await httpGet(`/feedbacks/statistic/monthly?year=${year}`); +} +export async function getStatisticSummary() { + return await httpGet(`/articles/statistic/summary`); +} + +export async function submitApproval(data: { + articleId: number; + message: string; + statusId: number; +}) { + return await httpPostInterceptor(`/article-approvals`, data); +} + +export async function updateIsBannerArticle(id: number, status: boolean) { + const headers = { + "content-type": "application/json", + }; + const pathUrl = `/articles/banner/${id}?isBanner=${status}`; + return await httpPutInterceptor(pathUrl, headers); +} diff --git a/service/generate-article.ts b/service/generate-article.ts new file mode 100644 index 0000000..c17f666 --- /dev/null +++ b/service/generate-article.ts @@ -0,0 +1,264 @@ +import { httpGet, httpPost, httpPost2 } from "./http-config/disestages-services"; + + +interface GenerateKeywordsAndTitleRequestData { + keyword: string; + style: string; + website: string; + connectToWeb: boolean; + lang: string; + pointOfView: string; + clientId: string; +} + +interface GenerateArticleRequest { + advConfig: string; + style: string; + website: string; + connectToWeb: boolean; + lang: string; + pointOfView: string; + title: string; + imageSource: string; + mainKeyword: string; + additionalKeywords: string; + targetCountry: null; + articleSize: string; + projectId: number; + createdBy: string; + clientId: string; +} + +type BulkArticleRequest = { + style: string; + website: string; + connectToWeb: boolean; + lang: string; + pointOfView: string; + imageSource: string; + targetCountry: null; + articleSize: string; + projectId: number; + data: { title: string; mainKeyword: string; additionalKeywords: string }[]; + createdBy: string; + clientId: string; +}; + +interface ContentRewriteRequest { + advConfig: string; + context: string | null; + style: string; + sentiment: string; + clientId: string; + createdBy: string; + contextType: string; + urlContext: string | null; + lang: string; +} + +export type ContentBankRequest = { + query: string; + page: number; + userId: string; + limit: number; + status: number[]; + isSingle: boolean; + createdBy: string; + sort: { column: string; sort: string }[]; +}; + +export async function getGenerateTitle( + data: GenerateKeywordsAndTitleRequestData +) { + const headers = { + "content-type": "application/json", + Authorization: + "Basic bmdETFBQaW9ycGx6bncyalRxVmUzWUZDejV4cUtmVUo6UHJEaERXUmNvdkJSNlc1Sg==", + }; + return await httpPost("ai-writer/generate-title", headers, data); +} + +export async function getGenerateKeywords( + data: GenerateKeywordsAndTitleRequestData +) { + const headers = { + "content-type": "application/json", + Authorization: + "Basic bmdETFBQaW9ycGx6bncyalRxVmUzWUZDejV4cUtmVUo6UHJEaERXUmNvdkJSNlc1Sg==", + }; + return await httpPost("ai-writer/generate-keywords", headers, data); +} + +export async function generateDataArticle(data: GenerateArticleRequest) { + const headers = { + "content-type": "application/json", + Authorization: + "Basic bmdETFBQaW9ycGx6bncyalRxVmUzWUZDejV4cUtmVUo6UHJEaERXUmNvdkJSNlc1Sg==", + }; + return await httpPost("ai-writer/save-article", headers, data); +} + +export async function approveArticle(props: { id: number[] }) { + const headers = { + "content-type": "application/json", + Authorization: + "Basic bmdETFBQaW9ycGx6bncyalRxVmUzWUZDejV4cUtmVUo6UHJEaERXUmNvdkJSNlc1Sg==", + }; + return await httpPost("ai-writer/approve-article", headers, props); +} +export async function rejectArticle(props: { id: number[] }) { + const headers = { + "content-type": "application/json", + Authorization: + "Basic bmdETFBQaW9ycGx6bncyalRxVmUzWUZDejV4cUtmVUo6UHJEaERXUmNvdkJSNlc1Sg==", + }; + return await httpPost("ai-writer/reject-article", headers, props); +} + +export async function getGenerateTopicKeywords(data: { + keyword: string; + count: number; +}) { + const headers = { + "content-type": "application/json", + Authorization: + "Basic bmdETFBQaW9ycGx6bncyalRxVmUzWUZDejV4cUtmVUo6UHJEaERXUmNvdkJSNlc1Sg==", + }; + return await httpPost("ai-writer/generate-topic-keywords", headers, data); +} + +export async function saveBulkArticle(data: BulkArticleRequest) { + const headers = { + "content-type": "application/json", + Authorization: + "Basic bmdETFBQaW9ycGx6bncyalRxVmUzWUZDejV4cUtmVUo6UHJEaERXUmNvdkJSNlc1Sg==", + }; + return await httpPost("ai-writer/save-bulk-article", headers, data); +} + +export async function getDetailArticle(id: number) { + const headers = { + "content-type": "application/json", + Authorization: + "Basic bmdETFBQaW9ycGx6bncyalRxVmUzWUZDejV4cUtmVUo6UHJEaERXUmNvdkJSNlc1Sg==", + }; + return await httpGet(`ai-writer/article/findArticleById/${id}`, headers); +} + +export async function generateSpeechToText(data: any) { + const headers = { + "content-type": "multipart/form-data", + Authorization: + "Basic bmdETFBQaW9ycGx6bncyalRxVmUzWUZDejV4cUtmVUo6UHJEaERXUmNvdkJSNlc1Sg==", + }; + return await httpPost("ai-writer/speech-to-text", headers, data); +} + +export async function getTranscriptById(id: number) { + const headers = { + "content-type": "application/json", + Authorization: + "Basic bmdETFBQaW9ycGx6bncyalRxVmUzWUZDejV4cUtmVUo6UHJEaERXUmNvdkJSNlc1Sg==", + }; + return await httpGet(`ai-writer/speech-to-text/findById/${id}`, headers); +} + +export async function getGenerateRewriter(data: ContentRewriteRequest) { + const headers = { + "content-type": "application/json", + Authorization: + "Basic bmdETFBQaW9ycGx6bncyalRxVmUzWUZDejV4cUtmVUo6UHJEaERXUmNvdkJSNlc1Sg==", + }; + return await httpPost("ai-writer/create-rewriter", headers, data); +} + +export async function getListTranscript(data: any) { + const headers = { + "content-type": "application/json", + Authorization: + "Basic bmdETFBQaW9ycGx6bncyalRxVmUzWUZDejV4cUtmVUo6UHJEaERXUmNvdkJSNlc1Sg==", + }; + return await httpPost("ai-writer/speech-to-text/datatable", headers, data); +} + +export async function getListArticleDraft(data: ContentBankRequest) { + const headers = { + "content-type": "application/json", + Authorization: + "Basic bmdETFBQaW9ycGx6bncyalRxVmUzWUZDejV4cUtmVUo6UHJEaERXUmNvdkJSNlc1Sg==", + }; + return await httpPost("ai-writer/article/datatable", headers, data); +} + +export async function updateManualArticle(data: any) { + const headers = { + "content-type": "application/json", + Authorization: + "Basic bmdETFBQaW9ycGx6bncyalRxVmUzWUZDejV4cUtmVUo6UHJEaERXUmNvdkJSNlc1Sg==", + }; + return await httpPost("ai-writer/update-article", headers, data); +} + +export async function getSeoScore(id: string) { + const headers = { + "content-type": "application/json", + Authorization: + "Basic bmdETFBQaW9ycGx6bncyalRxVmUzWUZDejV4cUtmVUo6UHJEaERXUmNvdkJSNlc1Sg==", + }; + return await httpGet(`ai-writer/article/checkSEOScore/${id}`, headers); +} + +export async function regenerateArticle(id: number | string) { + const headers = { + "content-type": "application/json", + Authorization: + "Basic bmdETFBQaW9ycGx6bncyalRxVmUzWUZDejV4cUtmVUo6UHJEaERXUmNvdkJSNlc1Sg==", + }; + return await httpGet(`ai-writer/re-create-article/${id}`, headers); +} + +export async function saveManualContext(data: any) { + const headers = { + "content-type": "application/json", + Authorization: + "Basic bmdETFBQaW9ycGx6bncyalRxVmUzWUZDejV4cUtmVUo6UHJEaERXUmNvdkJSNlc1Sg==", + }; + return await httpPost("ai-writer/create-article", headers, data); +} + +export async function facebookHumasData() { + const data = { + monitoringId: "f33b666c-ac07-4cd6-a64e-200465919e8c", + page: 133, + limit: 10, + userId: "0qrwedt9EcuLyOiBUbqhzjd0BwGRjDBd", + }; + const headers = { + "content-type": "application/json", + Authorization: + "Basic bmdETFBQaW9ycGx6bncyalRxVmUzWUZDejV4cUtmVUo6UHJEaERXUmNvdkJSNlc1Sg==", + }; + return await httpPost2( + "monitoring-media-social/datatable/facebook", + headers, + data + ); +} +export async function tiktokHumasData() { + const data = { + monitoringId: "1e301867-9599-4d82-ab57-9f7931f96903", + page: 1, + limit: 10, + userId: "0qrwedt9EcuLyOiBUbqhzjd0BwGRjDBd", + }; + const headers = { + "content-type": "application/json", + Authorization: + "Basic bmdETFBQaW9ycGx6bncyalRxVmUzWUZDejV4cUtmVUo6UHJEaERXUmNvdkJSNlc1Sg==", + }; + return await httpPost2( + "monitoring-media-social/datatable/tiktok", + headers, + data + ); +} diff --git a/service/http-config/axios-base-instance.ts b/service/http-config/axios-base-instance.ts new file mode 100644 index 0000000..8f0f0e1 --- /dev/null +++ b/service/http-config/axios-base-instance.ts @@ -0,0 +1,13 @@ +import axios from "axios"; + +const baseURL = "https://campaignpool.id/api"; + +const axiosBaseInstance = axios.create({ + baseURL, + headers: { + "Content-Type": "application/json", + "X-Client-Key": "bb65b1ad-e954-4a1a-b4d0-74df5bb0b640", + }, +}); + +export default axiosBaseInstance; diff --git a/service/http-config/axios-interceptor-instance.ts b/service/http-config/axios-interceptor-instance.ts new file mode 100644 index 0000000..349fd9b --- /dev/null +++ b/service/http-config/axios-interceptor-instance.ts @@ -0,0 +1,72 @@ +import axios from "axios"; +import { postSignIn } from "../master-user"; +import Cookies from "js-cookie"; + +const baseURL = "https://campaignpool.id/api"; + +const refreshToken = Cookies.get("refresh_token"); + +const axiosInterceptorInstance = axios.create({ + baseURL, + headers: { + "Content-Type": "application/json", + "X-Client-Key": "bb65b1ad-e954-4a1a-b4d0-74df5bb0b640", + }, + withCredentials: true, +}); + +// Request interceptor +axiosInterceptorInstance.interceptors.request.use( + (config) => { + console.log("Config interceptor : ", config); + const accessToken = Cookies.get("access_token"); + if (accessToken) { + if (config.headers) + config.headers.Authorization = "Bearer " + accessToken; + } + return config; + }, + (error) => { + return Promise.reject(error); + } +); + +// Response interceptor +axiosInterceptorInstance.interceptors.response.use( + (response) => { + console.log("Response interceptor : ", response); + return response; + }, + async function (error) { + console.log("Error interceptor : ", error.response.status); + const originalRequest = error.config; + if (error.response.status === 401 && !originalRequest._retry) { + originalRequest._retry = true; + const data = { + grantType: "refresh_token", + refreshToken: refreshToken, + clientId: "mediahub-app", + }; + console.log("refresh token ", data); + const res = await postSignIn(data); + if (res?.error) { + Object.keys(Cookies.get()).forEach((cookieName) => { + Cookies.remove(cookieName); + }); + } else { + const { access_token } = res?.data; + const { refresh_token } = res?.data; + if (access_token) { + Cookies.set("access_token", access_token); + Cookies.set("refresh_token", refresh_token); + } + } + + return axiosInterceptorInstance(originalRequest); + } + + return Promise.reject(error); + } +); + +export default axiosInterceptorInstance; diff --git a/service/http-config/disestages-instance.ts b/service/http-config/disestages-instance.ts new file mode 100644 index 0000000..ffbac6f --- /dev/null +++ b/service/http-config/disestages-instance.ts @@ -0,0 +1,12 @@ +import axios from "axios"; + +const baseURL = "https://disestages.com/api"; + +const axiosDisestagesInstance = axios.create({ + baseURL, + headers: { + "content-type": "application/json", + }, +}); + +export default axiosDisestagesInstance; diff --git a/service/http-config/disestages-services.ts b/service/http-config/disestages-services.ts new file mode 100644 index 0000000..e6fef0d --- /dev/null +++ b/service/http-config/disestages-services.ts @@ -0,0 +1,78 @@ +import axiosDisestagesInstance from "./disestages-instance"; +import axios from "axios"; +const baseURL = "https://staging.disestages.com/api"; + +export async function httpPost(pathUrl: any, headers: any, data?: any) { + const response = await axiosDisestagesInstance + .post(pathUrl, data, { headers }) + .catch(function (error) { + console.log(error); + return error.response; + }); + console.log("Response base svc : ", response); + if (response?.status == 200 || response?.status == 201) { + return { + error: false, + message: "success", + data: response?.data, + }; + } else { + return { + error: true, + message: response?.data?.message || response?.data || null, + data: null, + }; + } +} + +export async function httpGet(pathUrl: any, headers: any) { + const response = await axiosDisestagesInstance + .get(pathUrl, { headers }) + .catch(function (error) { + console.log(error); + return error.response; + }); + console.log("Response base svc : ", response); + if (response?.status == 200 || response?.status == 201) { + return { + error: false, + message: "success", + data: response?.data, + }; + } else { + return { + error: true, + message: response?.data?.message || response?.data || null, + data: null, + }; + } +} + +export async function httpPost2(pathUrl: any, headers: any, data?: any) { + const response = await axios + .create({ + baseURL, + headers: { + "content-type": "application/json", + }, + }) + .post(pathUrl, data, { headers }) + .catch(function (error) { + console.log(error); + return error.response; + }); + console.log("Response base svc : ", response); + if (response?.status == 200 || response?.status == 201) { + return { + error: false, + message: "success", + data: response?.data, + }; + } else { + return { + error: true, + message: response?.data?.message || response?.data || null, + data: null, + }; + } +} diff --git a/service/http-config/http-base-services.ts b/service/http-config/http-base-services.ts new file mode 100644 index 0000000..755d158 --- /dev/null +++ b/service/http-config/http-base-services.ts @@ -0,0 +1,61 @@ +import axiosBaseInstance from "./axios-base-instance"; + +const defaultHeaders = { + "Content-Type": "application/json", + "X-Client-Key": "bb65b1ad-e954-4a1a-b4d0-74df5bb0b640" +}; + +export async function httpGet(pathUrl: any, headers?: any) { + console.log("X-HEADERS : ", defaultHeaders) + const mergedHeaders = { + ...defaultHeaders, + ...headers, + }; + + console.log("Merged Headers : ", mergedHeaders); + + const response = await axiosBaseInstance + .get(pathUrl, { headers: mergedHeaders }) + .catch((error) => error.response); + console.log("Response base svc : ", response); + if (response?.data.success) { + return { + error: false, + message: "success", + data: response?.data, + }; + } else { + return { + error: true, + message: response?.data?.message || null, + data: null, + }; + } +} + +export async function httpPost(pathUrl: any, data: any, headers?: any) { + const mergedHeaders = { + ...defaultHeaders, + ...headers, + }; + const response = await axiosBaseInstance + .post(pathUrl, data, { headers: mergedHeaders }) + .catch(function (error) { + console.log(error); + return error.response; + }); + console.log("Response base svc : ", response); + if (response?.status == 200 || response?.status == 201) { + return { + error: false, + message: "success", + data: response?.data, + }; + } else { + return { + error: true, + message: response?.data?.message || response?.data || null, + data: null, + }; + } +} diff --git a/service/http-config/http-interceptor-services.ts b/service/http-config/http-interceptor-services.ts new file mode 100644 index 0000000..4d33d96 --- /dev/null +++ b/service/http-config/http-interceptor-services.ts @@ -0,0 +1,131 @@ +import { useRouter } from "next/navigation"; +import Cookies from "js-cookie"; +import axiosInterceptorInstance from "./axios-interceptor-instance"; +import { getCsrfToken } from "../master-user"; + +const defaultHeaders = { + "Content-Type": "application/json", + "X-Client-Key": "bb65b1ad-e954-4a1a-b4d0-74df5bb0b640" +}; + +export async function httpGetInterceptor(pathUrl: any) { + console.log("X-HEADERS : ", defaultHeaders) + const response = await axiosInterceptorInstance + .get(pathUrl, { headers: defaultHeaders }) + .catch((error) => error.response); + console.log("Response interceptor : ", response); + if (response?.status == 200 || response?.status == 201) { + return { + error: false, + message: "success", + data: response?.data, + }; + } else if (response?.status == 401) { + Cookies.set("is_logout", "true"); + window.location.href = "/"; + return { + error: true, + }; + } else { + return { + error: true, + message: response?.data?.message || response?.data || null, + data: null, + }; + } +} + +export async function httpPostInterceptor(pathUrl: any, data: any, headers?: any) { + const resCsrf = await getCsrfToken(); + const csrfToken = resCsrf?.data?.csrf_token; + + const mergedHeaders = { + ...defaultHeaders, + ...headers, + ...(csrfToken ? { "X-CSRF-TOKEN": csrfToken } : {}), + }; + + const response = await axiosInterceptorInstance + .post(pathUrl, data, { headers: mergedHeaders }) + .catch((error) => error.response); + console.log("Response interceptor : ", response); + if (response?.status == 200 || response?.status == 201) { + return { + error: false, + message: "success", + data: response?.data, + }; + } else if (response?.status == 401) { + Cookies.set("is_logout", "true"); + window.location.href = "/"; + } else { + return { + error: true, + message: response?.data?.message || response?.data || null, + data: null, + }; + } +} + +export async function httpPutInterceptor(pathUrl: any, data: any, headers?: any) { + const resCsrf = await getCsrfToken(); + const csrfToken = resCsrf?.data?.csrf_token; + + const mergedHeaders = { + ...defaultHeaders, + ...headers, + ...(csrfToken ? { "X-CSRF-TOKEN": csrfToken } : {}), + }; + const response = await axiosInterceptorInstance + .put(pathUrl, data, { headers: mergedHeaders }) + .catch((error) => error.response); + console.log("Response interceptor : ", response); + if (response?.status == 200 || response?.status == 201) { + return { + error: false, + message: "success", + data: response?.data, + }; + } else if (response?.status == 401) { + Cookies.set("is_logout", "true"); + window.location.href = "/"; + } else { + return { + error: true, + message: response?.data?.message || response?.data || null, + data: null, + }; + } +} + +export async function httpDeleteInterceptor(pathUrl: any, headers?: any) { + const resCsrf = await getCsrfToken(); + const csrfToken = resCsrf?.data?.csrf_token; + + const mergedHeaders = { + ...defaultHeaders, + ...headers, + ...(csrfToken ? { "X-CSRF-TOKEN": csrfToken } : {}), + }; + + const response = await axiosInterceptorInstance + .delete(pathUrl, { headers: mergedHeaders }) + .catch((error) => error.response); + console.log("Response interceptor : ", response); + if (response?.status == 200 || response?.status == 201) { + return { + error: false, + message: "success", + data: response?.data, + }; + } else if (response?.status == 401) { + Cookies.set("is_logout", "true"); + window.location.href = "/"; + } else { + return { + error: true, + message: response?.data?.message || response?.data || null, + data: null, + }; + } +} diff --git a/service/magazine.tsx b/service/magazine.tsx new file mode 100644 index 0000000..d711c8d --- /dev/null +++ b/service/magazine.tsx @@ -0,0 +1,50 @@ +import { PaginationRequest } from "@/types/globals"; +import Cookies from "js-cookie"; +import { httpDeleteInterceptor, httpGetInterceptor, httpPostInterceptor, httpPutInterceptor } from "./http-config/http-interceptor-services"; + +const token = Cookies.get("access_token"); + +export async function createMagazine(data: any) { + const pathUrl = `/magazines`; + return await httpPostInterceptor(pathUrl, data); +} + +export async function getListMagazine(props: PaginationRequest) { + const { page, limit, search, startDate, endDate } = props; + return await httpGetInterceptor( + `/magazines?limit=${limit}&page=${page}&title=${search}&startDate=${ + startDate || "" + }&endDate=${endDate || ""}` + ); +} + +export async function updateMagazine(id: string, data: any) { + const pathUrl = `/magazines/${id}`; + return await httpPutInterceptor(pathUrl, data); +} + +export async function getMagazineById(id: string) { + return await httpGetInterceptor(`/magazines/${id}`); +} + +export async function deleteMagazine(id: string) { + return await httpDeleteInterceptor(`magazines/${id}`); +} + +export async function uploadMagazineFile(id: string, data: any) { + const headers = { + "content-type": "multipart/form-data", + }; + return await httpPostInterceptor(`/magazine-files/${id}`, data, headers); +} + +export async function uploadMagazineThumbnail(id: string, data: any) { + const headers = { + "content-type": "multipart/form-data", + }; + return await httpPostInterceptor(`/magazines/thumbnail/${id}`, data, headers); +} + +export async function deleteMagazineFiles(id: number) { + return await httpDeleteInterceptor(`magazine-files/${id}`); +} diff --git a/service/master-categories.tsx b/service/master-categories.tsx new file mode 100644 index 0000000..44276b5 --- /dev/null +++ b/service/master-categories.tsx @@ -0,0 +1,29 @@ +import Cookies from "js-cookie"; +import { httpDeleteInterceptor, httpGetInterceptor, httpPostInterceptor, httpPutInterceptor } from "./http-config/http-interceptor-services"; + +const token = Cookies.get("access_token"); + +export async function createCategory(data: any) { + const pathUrl = `/article-categories`; + return await httpPostInterceptor(pathUrl, data); +} + +export async function updateCategory(id: string, data: any) { + const pathUrl = `/article-categories/${id}`; + return await httpPutInterceptor(pathUrl, data); +} + +export async function getCategoryById(id: number) { + return await httpGetInterceptor(`/article-categories/${id}`); +} + +export async function deleteCategory(id: number) { + return await httpDeleteInterceptor(`article-categories/${id}`); +} + +export async function uploadCategoryThumbnail(id: string, data: any) { + const headers = { + "content-type": "multipart/form-data", + }; + return await httpPostInterceptor(`/article-categories/thumbnail/${id}`, data, headers); +} diff --git a/service/master-user-role.ts b/service/master-user-role.ts new file mode 100644 index 0000000..567045b --- /dev/null +++ b/service/master-user-role.ts @@ -0,0 +1,29 @@ +import Cookies from "js-cookie"; +import { httpDeleteInterceptor, httpGetInterceptor, httpPostInterceptor } from "./http-config/http-interceptor-services"; + +const token = Cookies.get("access_token"); + +export async function listUserRole(data: any) { + return await httpGetInterceptor( + `/user-roles?limit=${data.limit}&page=${data.page}` + ); +} + +export async function createMasterUserRole(data: any) { + const pathUrl = `/user-roles`; + return await httpPostInterceptor(pathUrl, data); +} + +export async function getMasterUserRoleById(id: any) { + const headers = { + "content-type": "application/json", + }; + return await httpGetInterceptor(`/user-roles/${id}`); +} + +export async function deleteMasterUserRole(id: string) { + const headers = { + "content-type": "application/json", + }; + return await httpDeleteInterceptor(`/user-roles/${id}`); +} diff --git a/service/master-user.ts b/service/master-user.ts new file mode 100644 index 0000000..2fb012e --- /dev/null +++ b/service/master-user.ts @@ -0,0 +1,135 @@ +import Cookies from "js-cookie"; +import { httpGet, httpPost } from "./http-config/http-base-services"; +import { + httpDeleteInterceptor, + httpGetInterceptor, + httpPostInterceptor, + httpPutInterceptor, +} from "./http-config/http-interceptor-services"; +import { hex } from "framer-motion"; + +const token = Cookies.get("access_token"); +const id = Cookies.get("uie"); + +export async function listMasterUsers(data: any) { + const headers = { + "content-type": "application/json", + }; + return await httpGet(`/users?page=${data.page}&limit=${data.limit}`, headers); +} + +export async function createMasterUser(data: any) { + const pathUrl = `/users`; + return await httpPostInterceptor(pathUrl, data); +} + +export async function emailValidation(data: any) { + const pathUrl = `/users/email-validation`; + return await httpPost(pathUrl, data); +} +export async function setupEmail(data: any) { + const pathUrl = `/users/setup-email`; + return await httpPost(pathUrl, data); +} + +export async function getDetailMasterUsers(id: string) { + const pathUrl = `/users/detail/${id}`; + return await httpGetInterceptor(pathUrl); +} + +export async function editMasterUsers(data: any, id: string) { + const pathUrl = `/users/${id}`; + return await httpPutInterceptor(pathUrl, data); +} + +export async function deleteMasterUser(id: string) { + const pathUrl = `/users/${id}`; + return await httpDeleteInterceptor(pathUrl); +} + +export async function postSignIn(data: any) { + const pathUrl = `/users/login`; + return await httpPost(pathUrl, data); +} + +export async function getProfile(token?: string) { + const headers = { + "content-type": "application/json", + Authorization: `Bearer ${token}`, + }; + const pathUrl = `/users/info`; + return await httpGet(pathUrl, headers); +} + +export async function updateProfile(data: any) { + const pathUrl = `/users/${id}`; + return await httpPutInterceptor(pathUrl, data); +} +export async function savePassword(data: any) { + const pathUrl = `/users/save-password`; + return await httpPostInterceptor(pathUrl, data); +} + +export async function resetPassword(data: any) { + const headers = { + "content-type": "application/json", + }; + return await httpPost(`/users/reset-password`, headers, data); +} + +export async function checkUsernames(username: string) { + const headers = { + "content-type": "application/json", + }; + return await httpPost(`/users/forgot-password`, headers, { username }); +} + +export async function otpRequest(email: string, name: string) { + const pathUrl = `/users/otp-request`; + return await httpPost(pathUrl, { email, name }); +} + +export async function otpValidation(email: string, otpCode: string) { + const pathUrl = `/users/otp-validation`; + return await httpPost(pathUrl, { email, otpCode }); +} + +// export async function postArticleComment(data: any) { +// const headers = token +// ? { +// "content-type": "application/json", +// Authorization: `${token}`, +// } +// : { +// "content-type": "application/json", +// }; +// return await httpPost(`/article-comments`, headers, data); +// } + +export async function postArticleComment(data: any) { + const pathUrl = `/article-comments`; + return await httpPostInterceptor(pathUrl, data); +} + +export async function editArticleComment(data: any, id: number) { + const pathUrl = `/article-comments/${id}`; + return await httpPutInterceptor(pathUrl, data); +} + +export async function getArticleComment(id: string) { + const pathUrl = `/article-comments?isPublic=false&articleId=${id}`; + return await httpGet(pathUrl); +} + +export async function deleteArticleComment(id: number) { + const pathUrl = `/article-comments/${id}`; + return await httpDeleteInterceptor(pathUrl); +} + +export async function getCsrfToken() { + const pathUrl = "csrf-token"; + const headers = { + "content-type": "application/json", + }; + return httpGet(pathUrl, headers); +} diff --git a/service/static-page-service.ts b/service/static-page-service.ts new file mode 100644 index 0000000..41631ec --- /dev/null +++ b/service/static-page-service.ts @@ -0,0 +1,28 @@ +import { PaginationRequest } from "@/types/globals"; +import { httpGetInterceptor, httpPostInterceptor, httpPutInterceptor } from "./http-config/http-interceptor-services"; +import { httpGet } from "./http-config/http-base-services"; + +export async function createCustomStaticPage(data: any) { + const pathUrl = `/custom-static-pages`; + return await httpPostInterceptor(pathUrl, data); +} + +export async function editCustomStaticPage(data: any) { + const pathUrl = `/custom-static-pages/${data.id}`; + return await httpPutInterceptor(pathUrl, data); +} + +export async function getCustomStaticPage(props: PaginationRequest) { + const { page, limit, search } = props; + const pathUrl = `/custom-static-pages?limit=${limit}&page=${page}&title=${search}`; + return await httpGetInterceptor(pathUrl); +} + +export async function getCustomStaticDetail(id: string) { + return await httpGetInterceptor(`/custom-static-pages/${id}`); +} + +export async function getCustomStaticDetailBySlug(slug: string) { + const pathUrl = `/custom-static-pages/slug/${slug}`; + return await httpGet(pathUrl); +} diff --git a/service/user-levels-service.ts b/service/user-levels-service.ts new file mode 100644 index 0000000..3a2ca3e --- /dev/null +++ b/service/user-levels-service.ts @@ -0,0 +1,30 @@ + +import Cookies from "js-cookie"; +import { httpGetInterceptor, httpPostInterceptor, httpPutInterceptor } from "./http-config/http-interceptor-services"; +const token = Cookies.get("access_token"); + +export async function getAllUserLevels(data?: any) { + const pathUrl = `user-levels?limit=${data?.limit || ""}&levelNumber=${ + data?.levelNumber || "" + }&name=${data?.search || ""}&page=${data?.page || "1"}` + return await httpGetInterceptor(pathUrl); +} +export async function getUserLevels(id: string) { + return await httpGetInterceptor(`user-levels/${id}`); +} + +export async function getAccountById(id: string) { + return await httpGetInterceptor(`user-account/findById/${id}`); +} + +export async function createUserLevels(data: any) { + return await httpPostInterceptor(`user-levels`, data); +} + +export async function editUserLevels(id: string, data: any) { + return await httpPutInterceptor(`user-levels/${id}`, data); +} + +export async function changeIsApproval(data: any) { + return await httpPutInterceptor(`user-levels/enable-approval`, data); +} diff --git a/types/globals.tsx b/types/globals.tsx new file mode 100644 index 0000000..42a9bdc --- /dev/null +++ b/types/globals.tsx @@ -0,0 +1,316 @@ +import { SVGProps } from "react"; + +export type IconSvgProps = SVGProps & { + size?: number; +}; + +export type SidebarMenuTask = { + childMenu: any[]; + name: string; + id: number; + parentId: number; + position: number; + statusId: number; + statusName: string; +}; + +export type MasterUser = { + id: number; + address: string; + dateOfBirth: string; + email: string; + fullname: string; + genderType: string; + identityNumber: string; + identityType: string; + lastEducation: string; + phoneNumber: string; + userLevelsId: number; + userRoleId: number; + username: string; + workType: string; +}; + +export type Article = { + id: any; + title: string; + articleCategory: string; + tags: string; + updated_at: string; + creator: string; + source: string; + description: string; + htmlDescription: string; + status: string; + actions: string; +}; + +export type RequestInformation = { + no: number; + id: number; + ticketNumber: string; + createdByUserName: string; + createdByUserPhone: string; + createdByUserId: number; + reason: string; + createdAt: string; + title: string; + reqNumber: any; + statusId: any; + description: string; +}; + +export type RequestObjection = { + id: number; + dateTime: string; + title: string; + reqNumber: any; + status: string; + description: string; +}; + +export type UserObject = { + id: number; + name: string; + levelNumber: string; + aliasName: string; + parentLevelId: string; + provinceId: string; + is_active: string; +}; + +export type UserObjectTable = { + id: number; + name: string; + level_number: string; + aliasName: string; + parent_level_id: string; + province_id: string; + is_active: string; +}; + +export type UserObjectDetail = { + id: number; + name: string; + levelNumber: string; + alias_name: string; + parentLevelId: string; + provinceId: string; + is_active: string; +}; + +export type ModuleObject = { + id: number; + name: string; + is_active: string; + description: string; + pathUrl: string; +}; + +export type ModuleObjectDetail = { + id: number; + name: string; + is_active: string; + description: string; + path_url: string; +}; + +export type MenuObject = { + id: number; + name: string; + is_active: string; + description: string; + moduleName: string; + pathUrl: string; +}; + +export type MenuObjectDetail = { + id: number; + name: string; + status: string; + description: string; + moduleName: string; + pathUrl: string; +}; + +export type DataMasterMenu = { + id: number; + description: string; + icon: string; + moduleId: number; + name: string; + parentMenuId: number; + position: number; + statusId: number; +}; + +export type DataCategory = { + id: number; + title: string; +}; + +export type DataMasterMenuById = { + id: number; + description: string; + icon: string; + module_id: number; + name: string; + parent_menu_id: number; + position: number; + status_id: number; +}; +export type MasterUserRole = { + id: number; + name: string; + description: string; + code: string; + level_number: number; + status_id: number; + created_by_id: string | number; + is_active: true; + created_at: string; + updated_at: string; +}; + +export type PublicInformation = { + id: number; + no: number; + title: string; + description: string; + slug: string; + categoryId: number; + categoryName: string; + createdById: number; + createdByName: string; + position: any; + statusId: number; + statusName: number; + isPublish: boolean; + publishedAt: any; + isActive: boolean; + createdAt: any; + updatedAt: any; + files: any | []; + ppidDatas: any; +}; + +export type PPIDFiles = { + id: number; + title: string; + type: any; + ppidDataId: number; + fileName: string; + fileType: string; + downloadCount: any; +}; + +export type AllData = { + id: number; + ticketNumber: string; + createdAt: string; + nextAction: string; + fileUrl: string; + howToGetFiles: string; + howToGetInfo: string; +}; + +export type DataReplies = { + id: number; + requestForInformationItemId: number; + fileUrl: string; + response: string; + statusId: number; + createdById: string; + isActive: true; + createdAt: string; + updatedAt: string; +}; + +export type ObjectionData = { + id: number; + no: number; + created_by_id: number; + status: string; + statusId: number; + documentName: string; + main_reason: string; + secondary_reason: string; + createdAt: string; + updatedAt: string; + request_for_information_id: number; +}; + +export type CategoryData = { + id: number; + no: number; + title: string; + description: string; + parentId: string | null; + thumbnailUrl: string; +}; + +export type RequestData = { + id: number; + no: number; + title: string; + description: string; + parentId: string | null; + thumbnailUrl: string; +}; + +export type DataArticleCategory = { + id: number; + description: string; + title: string; + status_id: number; +}; + +export type DataPublicCategory = { + id: number; + description: string; + title: string; + parentId: string; + slug: string; + status_id: number; +}; + +export type RegisterUser = { + id: number; + address: string; + dateOfBirth: string; + email: string; + fullName: string; + genderType: string; + identityGroup: string; + identityGroupNumber: string; + identityNumber: string; + identityType: string; + lastEducation: string; + password: string; + confirmPassword: string; + phoneNumber: string; + userLevelId: number; + userRoleId: number; + username: string; + workType: string; +}; + +export type RequestInformationResponse = { + response: string; + fileUrl: string; +}; + +export type PaginationRequest = { + limit: string; + page: number; + search: string; + startDate?: string; + endDate?: string; + isPublish?: boolean; + category?: string; + sortBy?: string; + sort?: string; + source?: string; + categorySlug?: string; + isBanner?: boolean; +}; diff --git a/types/index.ts b/types/index.ts new file mode 100644 index 0000000..1a73f1b --- /dev/null +++ b/types/index.ts @@ -0,0 +1,5 @@ +import {SVGProps} from "react"; + +export type IconSvgProps = SVGProps & { + size?: number; +};