merge
This commit is contained in:
commit
6b10fedabf
|
|
@ -30,9 +30,6 @@ yarn-debug.log*
|
||||||
yarn-error.log*
|
yarn-error.log*
|
||||||
.pnpm-debug.log*
|
.pnpm-debug.log*
|
||||||
|
|
||||||
# env files (can opt-in for committing if needed)
|
|
||||||
.env*
|
|
||||||
|
|
||||||
# vercel
|
# vercel
|
||||||
.vercel
|
.vercel
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,9 @@ COPY package.json ./
|
||||||
# Menyalin direktori ckeditor5 jika diperlukan
|
# Menyalin direktori ckeditor5 jika diperlukan
|
||||||
COPY vendor/ckeditor5 ./vendor/ckeditor5
|
COPY vendor/ckeditor5 ./vendor/ckeditor5
|
||||||
|
|
||||||
|
# Menyalin env
|
||||||
|
COPY .env .env
|
||||||
|
|
||||||
# Install dependencies
|
# Install dependencies
|
||||||
RUN pnpm install
|
RUN pnpm install
|
||||||
# RUN pnpm install --frozen-lockfile
|
# RUN pnpm install --frozen-lockfile
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,6 @@
|
||||||
import Author from "@/components/landing-page/author";
|
|
||||||
import Footer from "@/components/landing-page/footer";
|
import Footer from "@/components/landing-page/footer";
|
||||||
import Header from "@/components/landing-page/header";
|
import Header from "@/components/landing-page/header";
|
||||||
import Latest from "@/components/landing-page/latest";
|
|
||||||
import LatestandPopular from "@/components/landing-page/latest-and-popular";
|
|
||||||
import Navbar from "@/components/landing-page/navbar";
|
import Navbar from "@/components/landing-page/navbar";
|
||||||
import News from "@/components/landing-page/news";
|
|
||||||
import Image from "next/image";
|
import Image from "next/image";
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
import type { Metadata } from "next";
|
import type { Metadata } from "next";
|
||||||
import { Geist, Geist_Mono } from "next/font/google";
|
import { Geist, Geist_Mono } from "next/font/google";
|
||||||
import "./globals.css";
|
import "./globals.css";
|
||||||
|
import ChunkErrorBoundary from "@/components/layout/chunk-error-boundary";
|
||||||
|
import "@/utils/chunk-error-handler";
|
||||||
|
|
||||||
const geistSans = Geist({
|
const geistSans = Geist({
|
||||||
variable: "--font-geist-sans",
|
variable: "--font-geist-sans",
|
||||||
|
|
@ -25,7 +27,9 @@ export default function RootLayout({
|
||||||
return (
|
return (
|
||||||
<html lang="en" suppressHydrationWarning>
|
<html lang="en" suppressHydrationWarning>
|
||||||
<body className={`${geistSans.variable} ${geistMono.variable} antialiased`} suppressHydrationWarning>
|
<body className={`${geistSans.variable} ${geistMono.variable} antialiased`} suppressHydrationWarning>
|
||||||
|
<ChunkErrorBoundary>
|
||||||
{children}
|
{children}
|
||||||
|
</ChunkErrorBoundary>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ import {
|
||||||
saveManualContext,
|
saveManualContext,
|
||||||
updateManualArticle,
|
updateManualArticle,
|
||||||
} from "@/service/generate-article";
|
} from "@/service/generate-article";
|
||||||
import { getUserLevels } from "@/service/user-levels/user-levels-service";
|
import { getUserLevels } from "@/service/user-levels-service";
|
||||||
import { Checkbox } from "@/components/ui/checkbox";
|
import { Checkbox } from "@/components/ui/checkbox";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { getCategoryById } from "@/service/master-categories";
|
import { getCategoryById } from "@/service/master-categories";
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ import { z } from "zod";
|
||||||
import ReactSelect from "react-select";
|
import ReactSelect from "react-select";
|
||||||
import makeAnimated from "react-select/animated";
|
import makeAnimated from "react-select/animated";
|
||||||
import { editMasterUsers, getDetailMasterUsers } from "@/service/master-user";
|
import { editMasterUsers, getDetailMasterUsers } from "@/service/master-user";
|
||||||
import { getAllUserLevels } from "@/service/user-levels/user-levels-service";
|
import { getAllUserLevels } from "@/service/user-levels-service";
|
||||||
import { listUserRole } from "@/service/master-user-role";
|
import { listUserRole } from "@/service/master-user-role";
|
||||||
import { Card } from "../ui/card";
|
import { Card } from "../ui/card";
|
||||||
import { Label } from "../ui/label";
|
import { Label } from "../ui/label";
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ import ReactSelect from "react-select";
|
||||||
import makeAnimated from "react-select/animated";
|
import makeAnimated from "react-select/animated";
|
||||||
import { zodResolver } from "@hookform/resolvers/zod";
|
import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
import { createMasterUser } from "@/service/master-user";
|
import { createMasterUser } from "@/service/master-user";
|
||||||
import { getAllUserLevels } from "@/service/user-levels/user-levels-service";
|
import { getAllUserLevels } from "@/service/user-levels-service";
|
||||||
import { listUserRole } from "@/service/master-user-role";
|
import { listUserRole } from "@/service/master-user-role";
|
||||||
import { Card } from "../ui/card";
|
import { Card } from "../ui/card";
|
||||||
import { Input } from "../ui/input";
|
import { Input } from "../ui/input";
|
||||||
|
|
|
||||||
|
|
@ -78,13 +78,13 @@ export default function Login() {
|
||||||
secure: true,
|
secure: true,
|
||||||
sameSite: "strict",
|
sameSite: "strict",
|
||||||
});
|
});
|
||||||
const resActivity = await saveActivity(
|
await saveActivity(
|
||||||
{
|
{
|
||||||
activityTypeId: 1,
|
activityTypeId: 1,
|
||||||
url: "https://dev.mikulnews.com/auth",
|
url: "https://dev.mikulnews.com/auth",
|
||||||
userId: profile?.data?.data?.id,
|
userId: profile?.data?.data?.id,
|
||||||
},
|
},
|
||||||
accessData?.id_token
|
response?.data?.data?.access_token
|
||||||
);
|
);
|
||||||
Cookies.set("profile_picture", profile?.data?.data?.profilePictureUrl, {
|
Cookies.set("profile_picture", profile?.data?.data?.profilePictureUrl, {
|
||||||
expires: 1,
|
expires: 1,
|
||||||
|
|
|
||||||
|
|
@ -250,7 +250,11 @@ export default function LatestandPopular() {
|
||||||
<div key={index}>
|
<div key={index}>
|
||||||
<div className="relative w-full aspect-video mb-3">
|
<div className="relative w-full aspect-video mb-3">
|
||||||
<Image
|
<Image
|
||||||
src={article.thumbnailUrl}
|
src={
|
||||||
|
articles[0]?.thumbnailUrl ||
|
||||||
|
articles[0]?.files?.[0]?.file_url ||
|
||||||
|
"/default-image.jpg"
|
||||||
|
}
|
||||||
alt={"article.title"}
|
alt={"article.title"}
|
||||||
fill
|
fill
|
||||||
sizes="(max-width: 1024px) 100vw, 33vw"
|
sizes="(max-width: 1024px) 100vw, 33vw"
|
||||||
|
|
@ -407,7 +411,11 @@ export default function LatestandPopular() {
|
||||||
<div key={index} className="flex gap-3">
|
<div key={index} className="flex gap-3">
|
||||||
<div className="relative w-[120px] h-[86px] shrink-0">
|
<div className="relative w-[120px] h-[86px] shrink-0">
|
||||||
<Image
|
<Image
|
||||||
src={article?.thumbnailUrl}
|
src={
|
||||||
|
articles[0]?.thumbnailUrl ||
|
||||||
|
articles[0]?.files?.[0]?.file_url ||
|
||||||
|
"/default-image.jpg"
|
||||||
|
}
|
||||||
alt={"article?.title"}
|
alt={"article?.title"}
|
||||||
fill
|
fill
|
||||||
className="object-cover"
|
className="object-cover"
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,104 @@
|
||||||
|
"use client";
|
||||||
|
|
||||||
|
import React, { Component, ErrorInfo, ReactNode } from 'react';
|
||||||
|
import { Button } from '@/components/ui/button';
|
||||||
|
import { RefreshCw } from 'lucide-react';
|
||||||
|
|
||||||
|
interface Props {
|
||||||
|
children: ReactNode;
|
||||||
|
fallback?: ReactNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface State {
|
||||||
|
hasError: boolean;
|
||||||
|
error?: Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
class ChunkErrorBoundary extends Component<Props, State> {
|
||||||
|
constructor(props: Props) {
|
||||||
|
super(props);
|
||||||
|
this.state = { hasError: false };
|
||||||
|
}
|
||||||
|
|
||||||
|
static getDerivedStateFromError(error: Error): State {
|
||||||
|
// Check if it's a chunk loading error
|
||||||
|
if (error.name === 'ChunkLoadError' || error.message.includes('Loading chunk')) {
|
||||||
|
return { hasError: true, error };
|
||||||
|
}
|
||||||
|
return { hasError: false };
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidCatch(error: Error, errorInfo: ErrorInfo) {
|
||||||
|
console.error('Chunk loading error:', error, errorInfo);
|
||||||
|
|
||||||
|
// If it's a chunk loading error, try to reload the page
|
||||||
|
if (error.name === 'ChunkLoadError' || error.message.includes('Loading chunk')) {
|
||||||
|
this.setState({ hasError: true, error });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleRetry = () => {
|
||||||
|
// Clear the error state and reload the page
|
||||||
|
this.setState({ hasError: false, error: undefined });
|
||||||
|
window.location.reload();
|
||||||
|
};
|
||||||
|
|
||||||
|
render() {
|
||||||
|
if (this.state.hasError) {
|
||||||
|
if (this.props.fallback) {
|
||||||
|
return this.props.fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="min-h-screen flex items-center justify-center bg-gradient-to-br from-slate-50 via-white to-slate-50">
|
||||||
|
<div className="text-center p-8 max-w-md">
|
||||||
|
<div className="mb-6">
|
||||||
|
<div className="w-16 h-16 bg-red-100 rounded-full flex items-center justify-center mx-auto mb-4">
|
||||||
|
<RefreshCw className="w-8 h-8 text-red-600" />
|
||||||
|
</div>
|
||||||
|
<h2 className="text-xl font-semibold text-gray-900 mb-2">
|
||||||
|
Chunk Loading Error
|
||||||
|
</h2>
|
||||||
|
<p className="text-gray-600 mb-6">
|
||||||
|
There was an issue loading a part of the application. This usually happens when the application has been updated.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="space-y-3">
|
||||||
|
<Button
|
||||||
|
onClick={this.handleRetry}
|
||||||
|
className="w-full bg-blue-600 hover:bg-blue-700 text-white"
|
||||||
|
>
|
||||||
|
<RefreshCw className="w-4 h-4 mr-2" />
|
||||||
|
Reload Application
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Button
|
||||||
|
onClick={() => window.location.href = '/'}
|
||||||
|
variant="outline"
|
||||||
|
className="w-full"
|
||||||
|
>
|
||||||
|
Go to Homepage
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{process.env.NODE_ENV === 'development' && this.state.error && (
|
||||||
|
<details className="mt-6 text-left">
|
||||||
|
<summary className="cursor-pointer text-sm text-gray-500 hover:text-gray-700">
|
||||||
|
Error Details (Development)
|
||||||
|
</summary>
|
||||||
|
<pre className="mt-2 p-3 bg-gray-100 rounded text-xs overflow-auto">
|
||||||
|
{this.state.error.message}
|
||||||
|
</pre>
|
||||||
|
</details>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.props.children;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ChunkErrorBoundary;
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
"use client";
|
"use client";
|
||||||
import { getStatisticMonthly } from "@/service/article";
|
import { getStatisticMonthly } from "@/service/article";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import dynamic from "next/dynamic";
|
import { SafeReactApexChart } from "@/utils/dynamic-import";
|
||||||
|
|
||||||
type WeekData = {
|
type WeekData = {
|
||||||
week: number;
|
week: number;
|
||||||
|
|
@ -53,9 +53,6 @@ const ApexChartColumn = (props: {
|
||||||
const [seriesComment, setSeriesComment] = useState<number[]>([]);
|
const [seriesComment, setSeriesComment] = useState<number[]>([]);
|
||||||
const [seriesView, setSeriesView] = useState<number[]>([]);
|
const [seriesView, setSeriesView] = useState<number[]>([]);
|
||||||
const [seriesShare, setSeriesShare] = useState<number[]>([]);
|
const [seriesShare, setSeriesShare] = useState<number[]>([]);
|
||||||
const ReactApexChart = dynamic(() => import("react-apexcharts"), {
|
|
||||||
ssr: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
initFetch();
|
initFetch();
|
||||||
|
|
@ -132,7 +129,7 @@ const ApexChartColumn = (props: {
|
||||||
return (
|
return (
|
||||||
<div className="h-full">
|
<div className="h-full">
|
||||||
<div id="chart" className="h-full">
|
<div id="chart" className="h-full">
|
||||||
<ReactApexChart
|
<SafeReactApexChart
|
||||||
options={{
|
options={{
|
||||||
chart: {
|
chart: {
|
||||||
height: "100%",
|
height: "100%",
|
||||||
|
|
|
||||||
|
|
@ -27,12 +27,12 @@ import Image from "next/image";
|
||||||
import { Switch } from "@/components/ui/switch";
|
import { Switch } from "@/components/ui/switch";
|
||||||
import useDisclosure from "@/components/useDisclosure";
|
import useDisclosure from "@/components/useDisclosure";
|
||||||
import {
|
import {
|
||||||
createAdvertiseById,
|
|
||||||
createMediaFileAdvertise,
|
createMediaFileAdvertise,
|
||||||
deleteAdvertise,
|
deleteAdvertise,
|
||||||
editAdvertise,
|
editAdvertise,
|
||||||
editAdvertiseIsActive,
|
editAdvertiseIsActive,
|
||||||
getAdvertise,
|
getAdvertise,
|
||||||
|
getAdvertiseById,
|
||||||
} from "@/service/advertisement";
|
} from "@/service/advertisement";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { Input } from "@/components/ui/input";
|
import { Input } from "@/components/ui/input";
|
||||||
|
|
@ -226,7 +226,7 @@ export default function AdvertiseTable(props: { triggerRefresh: boolean }) {
|
||||||
};
|
};
|
||||||
|
|
||||||
const openModal = async (id: number) => {
|
const openModal = async (id: number) => {
|
||||||
const res = await createAdvertiseById(Number(id));
|
const res = await getAdvertiseById(Number(id));
|
||||||
const data = res?.data?.data;
|
const data = res?.data?.data;
|
||||||
setValue("id", String(data?.id));
|
setValue("id", String(data?.id));
|
||||||
setValue("title", data?.title);
|
setValue("title", data?.title);
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ import Cookies from "js-cookie";
|
||||||
import {
|
import {
|
||||||
deleteArticle,
|
deleteArticle,
|
||||||
getArticleByCategory,
|
getArticleByCategory,
|
||||||
getListArticle,
|
getArticlePagination,
|
||||||
updateIsBannerArticle,
|
updateIsBannerArticle,
|
||||||
} from "@/service/article";
|
} from "@/service/article";
|
||||||
import {
|
import {
|
||||||
|
|
@ -91,9 +91,6 @@ export default function ArticleTable() {
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
initState();
|
initState();
|
||||||
}, [page, showData, startDateValue, selectedCategories]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
getCategories();
|
getCategories();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
|
@ -103,7 +100,7 @@ export default function ArticleTable() {
|
||||||
setCategories(data);
|
setCategories(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function initState() {
|
const initState = useCallback(async () => {
|
||||||
loading();
|
loading();
|
||||||
const req = {
|
const req = {
|
||||||
limit: showData,
|
limit: showData,
|
||||||
|
|
@ -116,11 +113,11 @@ export default function ArticleTable() {
|
||||||
sort: "desc",
|
sort: "desc",
|
||||||
sortBy: "created_at",
|
sortBy: "created_at",
|
||||||
};
|
};
|
||||||
const res = await getListArticle(req);
|
const res = await getArticlePagination(req);
|
||||||
await getTableNumber(parseInt(showData), res.data?.data);
|
await getTableNumber(parseInt(showData), res.data?.data);
|
||||||
setTotalPage(res?.data?.meta?.totalPage);
|
setTotalPage(res?.data?.meta?.totalPage);
|
||||||
close();
|
close();
|
||||||
}
|
}, [page]);
|
||||||
|
|
||||||
const getTableNumber = async (limit: number, data: Article[]) => {
|
const getTableNumber = async (limit: number, data: Article[]) => {
|
||||||
if (data) {
|
if (data) {
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,16 @@
|
||||||
import type { NextConfig } from "next";
|
import type { NextConfig } from "next";
|
||||||
|
|
||||||
const nextConfig: NextConfig = {
|
const nextConfig: NextConfig = {
|
||||||
env: {
|
|
||||||
MEDOLS_CLIENT_KEY: process.env.MEDOLS_CLIENT_KEY,
|
|
||||||
},
|
|
||||||
images: {
|
images: {
|
||||||
domains: ["mikulnews.com", "dev.mikulnews.com"],
|
domains: ["mikulnews.com", "dev.mikulnews.com"],
|
||||||
},
|
},
|
||||||
eslint: {
|
eslint: {
|
||||||
ignoreDuringBuilds: true,
|
ignoreDuringBuilds: true,
|
||||||
},
|
},
|
||||||
|
// Add experimental features for better chunk handling
|
||||||
|
experimental: {
|
||||||
|
optimizePackageImports: ['@ckeditor/ckeditor5-react', 'react-apexcharts'],
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default nextConfig;
|
export default nextConfig;
|
||||||
|
|
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 154 KiB |
|
|
@ -1,5 +1,4 @@
|
||||||
import { PaginationRequest } from "@/types/globals";
|
import { httpGet, httpPost } from "./http-config/http-base-services";
|
||||||
import { httpGet, httpPost, httpPut } from "./http-config/axios-base-service";
|
|
||||||
|
|
||||||
export async function saveActivity(data: any, token?: string) {
|
export async function saveActivity(data: any, token?: string) {
|
||||||
const headers = token
|
const headers = token
|
||||||
|
|
@ -11,11 +10,10 @@ export async function saveActivity(data: any, token?: string) {
|
||||||
"content-type": "application/json",
|
"content-type": "application/json",
|
||||||
};
|
};
|
||||||
const pathUrl = `/activity-logs`;
|
const pathUrl = `/activity-logs`;
|
||||||
return await httpPost(pathUrl, headers, data);
|
return await httpPost(pathUrl, data, headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getActivity() {
|
export async function getActivity() {
|
||||||
const headers = { "content-type": "application/json" };
|
|
||||||
const pathUrl = `/activity-logs/statistics`;
|
const pathUrl = `/activity-logs/statistics`;
|
||||||
return await httpGet(pathUrl, headers);
|
return await httpGet(pathUrl);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,68 +1,42 @@
|
||||||
import {
|
|
||||||
httpDeleteInterceptor,
|
|
||||||
httpGet,
|
|
||||||
httpPost,
|
|
||||||
httpPut,
|
|
||||||
} from "./http-config/axios-base-service";
|
|
||||||
import Cookies from "js-cookie";
|
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");
|
const token = Cookies.get("access_token");
|
||||||
|
|
||||||
export async function createAdvertise(data: any) {
|
export async function createAdvertise(data: any) {
|
||||||
const headers = {
|
|
||||||
"content-type": "application/json",
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
};
|
|
||||||
const pathUrl = `/advertisement`;
|
const pathUrl = `/advertisement`;
|
||||||
return await httpPost(pathUrl, headers, data);
|
return await httpPostInterceptor(pathUrl, data);
|
||||||
}
|
}
|
||||||
export async function createMediaFileAdvertise(id: string | number, data: any) {
|
export async function createMediaFileAdvertise(id: string | number, data: any) {
|
||||||
const headers = {
|
const headers = {
|
||||||
"content-type": "multipart/form-data",
|
"content-type": "multipart/form-data",
|
||||||
};
|
};
|
||||||
const pathUrl = `/advertisement/upload/${id}`;
|
const pathUrl = `/advertisement/upload/${id}`;
|
||||||
return await httpPost(pathUrl, headers, data);
|
return await httpPostInterceptor(pathUrl, data, headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getAdvertise(data: any) {
|
export async function getAdvertise(data: any) {
|
||||||
const headers = {
|
const pathUrl = `/advertisement?page=${data?.page || 1}&limit=${data?.limit || ""}&placement=${data?.placement || ""}&isPublish=${data.isPublish || ""}`;
|
||||||
"content-type": "application/json",
|
return await httpGet(pathUrl);
|
||||||
};
|
|
||||||
const pathUrl = `/advertisement?page=${data?.page || 1}&limit=${
|
|
||||||
data?.limit || ""
|
|
||||||
}&placement=${data?.placement || ""}&isPublish=${data.isPublish || ""}`;
|
|
||||||
return await httpGet(pathUrl, headers);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createAdvertiseById(id: number) {
|
export async function getAdvertiseById(id: number) {
|
||||||
const headers = {
|
|
||||||
"content-type": "application/json",
|
|
||||||
};
|
|
||||||
const pathUrl = `/advertisement/${id}`;
|
const pathUrl = `/advertisement/${id}`;
|
||||||
return await httpGet(pathUrl, headers);
|
return await httpGet(pathUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function editAdvertise(data: any) {
|
export async function editAdvertise(data: any) {
|
||||||
const headers = {
|
|
||||||
"content-type": "application/json",
|
|
||||||
};
|
|
||||||
const pathUrl = `/advertisement/${data?.id}`;
|
const pathUrl = `/advertisement/${data?.id}`;
|
||||||
return await httpPut(pathUrl, headers, data);
|
return await httpPutInterceptor(pathUrl, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function editAdvertiseIsActive(data: any) {
|
export async function editAdvertiseIsActive(data: any) {
|
||||||
const headers = {
|
|
||||||
"content-type": "application/json",
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
};
|
|
||||||
const pathUrl = `/advertisement/publish/${data?.id}?isPublish=${data?.isActive}`;
|
const pathUrl = `/advertisement/publish/${data?.id}?isPublish=${data?.isActive}`;
|
||||||
return await httpPut(pathUrl, headers);
|
return await httpPutInterceptor(pathUrl, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteAdvertise(id: number) {
|
export async function deleteAdvertise(id: number) {
|
||||||
const headers = {
|
|
||||||
"content-type": "application/json",
|
|
||||||
};
|
|
||||||
const pathUrl = `/advertisement/${id}`;
|
const pathUrl = `/advertisement/${id}`;
|
||||||
return await httpDeleteInterceptor(pathUrl, headers);
|
return await httpDeleteInterceptor(pathUrl);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import { PaginationRequest } from "@/types/globals";
|
import { PaginationRequest } from "@/types/globals";
|
||||||
import Cookies from "js-cookie";
|
|
||||||
import { httpGet } from "./http-config/http-base-services";
|
import { httpGet } from "./http-config/http-base-services";
|
||||||
import { httpDeleteInterceptor, httpPostInterceptor, httpPutInterceptor } from "./http-config/http-interceptor-services";
|
import { httpDeleteInterceptor, httpGetInterceptor, httpPostInterceptor, httpPutInterceptor } from "./http-config/http-interceptor-services";
|
||||||
|
|
||||||
export async function getListArticle(props: PaginationRequest) {
|
export async function getListArticle(props: PaginationRequest) {
|
||||||
const {
|
const {
|
||||||
|
|
@ -29,6 +28,28 @@ export async function getListArticle(props: PaginationRequest) {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getArticlePagination(props: PaginationRequest) {
|
||||||
|
const {
|
||||||
|
page,
|
||||||
|
limit,
|
||||||
|
search,
|
||||||
|
startDate,
|
||||||
|
endDate,
|
||||||
|
category,
|
||||||
|
sortBy,
|
||||||
|
sort,
|
||||||
|
categorySlug,
|
||||||
|
isBanner,
|
||||||
|
} = props;
|
||||||
|
return await httpGetInterceptor(
|
||||||
|
`/articles?limit=${limit}&page=${page}&title=${search}&startDate=${startDate || ""}&endDate=${
|
||||||
|
endDate || ""
|
||||||
|
}&categoryId=${category || ""}&sortBy=${sortBy || "created_at"}&sort=${
|
||||||
|
sort || "asc"
|
||||||
|
}&category=${categorySlug || ""}&isBanner=${isBanner || ""}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
export async function getTopArticles(props: PaginationRequest) {
|
export async function getTopArticles(props: PaginationRequest) {
|
||||||
const { page, limit, search, startDate, endDate, isPublish, category } =
|
const { page, limit, search, startDate, endDate, isPublish, category } =
|
||||||
props;
|
props;
|
||||||
|
|
@ -75,7 +96,7 @@ export async function deleteArticle(id: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getArticleByCategory() {
|
export async function getArticleByCategory() {
|
||||||
return await httpGet(`/article-categories?limit=1000`);
|
return await httpGetInterceptor(`/article-categories?limit=1000`);
|
||||||
}
|
}
|
||||||
export async function getCategoryPagination(data: any) {
|
export async function getCategoryPagination(data: any) {
|
||||||
return await httpGet(
|
return await httpGet(
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,8 @@ const baseURL = "https://dev.mikulnews.com/api";
|
||||||
const axiosBaseInstance = axios.create({
|
const axiosBaseInstance = axios.create({
|
||||||
baseURL,
|
baseURL,
|
||||||
headers: {
|
headers: {
|
||||||
"content-type": "application/json",
|
"Content-Type": "application/json",
|
||||||
|
"X-Client-Key": "bb65b1ad-e954-4a1a-b4d0-74df5bb0b640"
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,154 +0,0 @@
|
||||||
import { getCsrfToken } from "../master-user";
|
|
||||||
import axiosInterceptorInstance from "./axios-interceptor-instance";
|
|
||||||
import axiosBaseInstance from "./http-base-instance";
|
|
||||||
import mediahubBaseInstance from "./mediahub-base-service";
|
|
||||||
import Cookies from "js-cookie";
|
|
||||||
|
|
||||||
const defaultHeaders = {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
};
|
|
||||||
|
|
||||||
export async function httpPost(pathUrl: any, headers: any, data?: any) {
|
|
||||||
const resCsrf = await getCsrfToken();
|
|
||||||
const csrfToken = resCsrf?.data?.csrf_token;
|
|
||||||
|
|
||||||
const mergedHeaders = {
|
|
||||||
...defaultHeaders,
|
|
||||||
...headers,
|
|
||||||
...(csrfToken ? { "X-CSRF-TOKEN": csrfToken } : {}),
|
|
||||||
};
|
|
||||||
|
|
||||||
const response = await axiosBaseInstance
|
|
||||||
.post(pathUrl, data, { headers: mergedHeaders })
|
|
||||||
.catch(function (error: any) {
|
|
||||||
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 axiosInterceptorInstance
|
|
||||||
.get(pathUrl, { headers })
|
|
||||||
.catch(function (error: any) {
|
|
||||||
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 httpPut(pathUrl: any, headers: any, data?: any) {
|
|
||||||
const resCsrf = await getCsrfToken();
|
|
||||||
const csrfToken = resCsrf?.data?.csrf_token;
|
|
||||||
|
|
||||||
const defaultHeaders = {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
};
|
|
||||||
const mergedHeaders = {
|
|
||||||
...defaultHeaders,
|
|
||||||
...headers,
|
|
||||||
...(csrfToken ? { "X-CSRF-TOKEN": csrfToken } : {}),
|
|
||||||
};
|
|
||||||
|
|
||||||
const response = await axiosBaseInstance
|
|
||||||
.put(pathUrl, data, { headers: mergedHeaders })
|
|
||||||
.catch(function (error: any) {
|
|
||||||
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 httpDeleteInterceptor(pathUrl: any, headers: any) {
|
|
||||||
const resCsrf = await getCsrfToken();
|
|
||||||
const csrfToken = resCsrf?.data?.csrf_token;
|
|
||||||
|
|
||||||
const defaultHeaders = {
|
|
||||||
"Content-Type": "application/json",
|
|
||||||
};
|
|
||||||
const mergedHeaders = {
|
|
||||||
...defaultHeaders,
|
|
||||||
...headers,
|
|
||||||
...(csrfToken ? { "X-CSRF-TOKEN": csrfToken } : {}),
|
|
||||||
};
|
|
||||||
|
|
||||||
const response = await axiosBaseInstance
|
|
||||||
.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 {
|
|
||||||
return {
|
|
||||||
error: true,
|
|
||||||
message: response?.data?.message || response?.data || null,
|
|
||||||
data: null,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function mediahubGet(pathUrl: any, headers: any) {
|
|
||||||
const response = await mediahubBaseInstance
|
|
||||||
.get(pathUrl, { headers })
|
|
||||||
.catch(function (error: any) {
|
|
||||||
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,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -10,7 +10,7 @@ const axiosInterceptorInstance = axios.create({
|
||||||
baseURL,
|
baseURL,
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
"X-Client-Key": process.env.MEDOLS_CLIENT_KEY
|
"X-Client-Key": "bb65b1ad-e954-4a1a-b4d0-74df5bb0b640"
|
||||||
},
|
},
|
||||||
withCredentials: true,
|
withCredentials: true,
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,14 +0,0 @@
|
||||||
import axios from "axios";
|
|
||||||
|
|
||||||
const baseURL = "https://dev.mikulnews.com/api";
|
|
||||||
|
|
||||||
const axiosBaseInstance = axios.create({
|
|
||||||
baseURL,
|
|
||||||
headers: {
|
|
||||||
"content-type": "application/json",
|
|
||||||
"X-Client-Key": process.env.MEDOLS_CLIENT_KEY
|
|
||||||
},
|
|
||||||
withCredentials: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
export default axiosBaseInstance;
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
import axiosBaseInstance from "./http-base-instance";
|
import axiosBaseInstance from "./axios-base-instance";
|
||||||
|
|
||||||
const defaultHeaders = {
|
const defaultHeaders = {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
"X-Client-Key": process.env.MEDOLS_CLIENT_KEY
|
"X-Client-Key": "bb65b1ad-e954-4a1a-b4d0-74df5bb0b640"
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function httpGet(pathUrl: any, headers?: any) {
|
export async function httpGet(pathUrl: any, headers?: any) {
|
||||||
|
console.log("X-HEADERS : ", defaultHeaders)
|
||||||
const mergedHeaders = {
|
const mergedHeaders = {
|
||||||
...defaultHeaders,
|
...defaultHeaders,
|
||||||
...headers,
|
...headers,
|
||||||
|
|
@ -33,9 +33,13 @@ export async function httpGet(pathUrl: any, headers?: any) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function httpPost(pathUrl: any, headers: any, data: any) {
|
export async function httpPost(pathUrl: any, data: any, headers?: any) {
|
||||||
|
const mergedHeaders = {
|
||||||
|
...defaultHeaders,
|
||||||
|
...headers,
|
||||||
|
};
|
||||||
const response = await axiosBaseInstance
|
const response = await axiosBaseInstance
|
||||||
.post(pathUrl, data, { headers })
|
.post(pathUrl, data, { headers: mergedHeaders })
|
||||||
.catch(function (error) {
|
.catch(function (error) {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
return error.response;
|
return error.response;
|
||||||
|
|
|
||||||
|
|
@ -5,12 +5,13 @@ import { getCsrfToken } from "../master-user";
|
||||||
|
|
||||||
const defaultHeaders = {
|
const defaultHeaders = {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
"X-Client-Key": process.env.MEDOLS_CLIENT_KEY
|
"X-Client-Key": "bb65b1ad-e954-4a1a-b4d0-74df5bb0b640"
|
||||||
};
|
};
|
||||||
|
|
||||||
export async function httpGetInterceptor(pathUrl: any) {
|
export async function httpGetInterceptor(pathUrl: any) {
|
||||||
|
console.log("X-HEADERS : ", defaultHeaders)
|
||||||
const response = await axiosInterceptorInstance
|
const response = await axiosInterceptorInstance
|
||||||
.get(pathUrl)
|
.get(pathUrl, { headers: defaultHeaders })
|
||||||
.catch((error) => error.response);
|
.catch((error) => error.response);
|
||||||
console.log("Response interceptor : ", response);
|
console.log("Response interceptor : ", response);
|
||||||
if (response?.status == 200 || response?.status == 201) {
|
if (response?.status == 200 || response?.status == 201) {
|
||||||
|
|
@ -97,7 +98,7 @@ export async function httpPutInterceptor(pathUrl: any, data: any, headers?: any)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function httpDeleteInterceptor(pathUrl: any, headers: any) {
|
export async function httpDeleteInterceptor(pathUrl: any, headers?: any) {
|
||||||
const resCsrf = await getCsrfToken();
|
const resCsrf = await getCsrfToken();
|
||||||
const csrfToken = resCsrf?.data?.csrf_token;
|
const csrfToken = resCsrf?.data?.csrf_token;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,12 +0,0 @@
|
||||||
import axios from "axios";
|
|
||||||
|
|
||||||
const baseURL = "https://mediahub.polri.go.id/api";
|
|
||||||
|
|
||||||
const mediahubBaseInstance = axios.create({
|
|
||||||
baseURL,
|
|
||||||
headers: {
|
|
||||||
"content-type": "application/json",
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
export default mediahubBaseInstance;
|
|
||||||
|
|
@ -1,75 +1,50 @@
|
||||||
import { PaginationRequest } from "@/types/globals";
|
import { PaginationRequest } from "@/types/globals";
|
||||||
import {
|
|
||||||
httpDeleteInterceptor,
|
|
||||||
httpGet,
|
|
||||||
httpPost,
|
|
||||||
httpPut,
|
|
||||||
} from "./http-config/axios-base-service";
|
|
||||||
import Cookies from "js-cookie";
|
import Cookies from "js-cookie";
|
||||||
|
import { httpDeleteInterceptor, httpGetInterceptor, httpPostInterceptor, httpPutInterceptor } from "./http-config/http-interceptor-services";
|
||||||
|
|
||||||
const token = Cookies.get("access_token");
|
const token = Cookies.get("access_token");
|
||||||
|
|
||||||
export async function createMagazine(data: any) {
|
export async function createMagazine(data: any) {
|
||||||
const headers = {
|
|
||||||
"content-type": "application/json",
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
};
|
|
||||||
const pathUrl = `/magazines`;
|
const pathUrl = `/magazines`;
|
||||||
return await httpPost(pathUrl, headers, data);
|
return await httpPostInterceptor(pathUrl, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getListMagazine(props: PaginationRequest) {
|
export async function getListMagazine(props: PaginationRequest) {
|
||||||
const { page, limit, search, startDate, endDate } = props;
|
const { page, limit, search, startDate, endDate } = props;
|
||||||
const headers = {
|
return await httpGetInterceptor(
|
||||||
"content-type": "application/json",
|
|
||||||
};
|
|
||||||
return await httpGet(
|
|
||||||
`/magazines?limit=${limit}&page=${page}&title=${search}&startDate=${
|
`/magazines?limit=${limit}&page=${page}&title=${search}&startDate=${
|
||||||
startDate || ""
|
startDate || ""
|
||||||
}&endDate=${endDate || ""}`,
|
}&endDate=${endDate || ""}`
|
||||||
headers
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function updateMagazine(id: string, data: any) {
|
export async function updateMagazine(id: string, data: any) {
|
||||||
const headers = {
|
|
||||||
"content-type": "application/json",
|
|
||||||
};
|
|
||||||
const pathUrl = `/magazines/${id}`;
|
const pathUrl = `/magazines/${id}`;
|
||||||
return await httpPut(pathUrl, headers, data);
|
return await httpPutInterceptor(pathUrl, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getMagazineById(id: string) {
|
export async function getMagazineById(id: string) {
|
||||||
const headers = {
|
return await httpGetInterceptor(`/magazines/${id}`);
|
||||||
"content-type": "application/json",
|
|
||||||
};
|
|
||||||
return await httpGet(`/magazines/${id}`, headers);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteMagazine(id: string) {
|
export async function deleteMagazine(id: string) {
|
||||||
const headers = {
|
return await httpDeleteInterceptor(`magazines/${id}`);
|
||||||
"content-type": "application/json",
|
|
||||||
};
|
|
||||||
return await httpDeleteInterceptor(`magazines/${id}`, headers);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function uploadMagazineFile(id: string, data: any) {
|
export async function uploadMagazineFile(id: string, data: any) {
|
||||||
const headers = {
|
const headers = {
|
||||||
"content-type": "multipart/form-data",
|
"content-type": "multipart/form-data",
|
||||||
};
|
};
|
||||||
return await httpPost(`/magazine-files/${id}`, headers, data);
|
return await httpPostInterceptor(`/magazine-files/${id}`, data, headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function uploadMagazineThumbnail(id: string, data: any) {
|
export async function uploadMagazineThumbnail(id: string, data: any) {
|
||||||
const headers = {
|
const headers = {
|
||||||
"content-type": "multipart/form-data",
|
"content-type": "multipart/form-data",
|
||||||
};
|
};
|
||||||
return await httpPost(`/magazines/thumbnail/${id}`, headers, data);
|
return await httpPostInterceptor(`/magazines/thumbnail/${id}`, data, headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteMagazineFiles(id: number) {
|
export async function deleteMagazineFiles(id: number) {
|
||||||
const headers = {
|
return await httpDeleteInterceptor(`magazine-files/${id}`);
|
||||||
"content-type": "multipart/form-data",
|
|
||||||
};
|
|
||||||
return await httpDeleteInterceptor(`magazine-files/${id}`, headers);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,47 +1,29 @@
|
||||||
import {
|
|
||||||
httpDeleteInterceptor,
|
|
||||||
httpGet,
|
|
||||||
httpPost,
|
|
||||||
httpPut,
|
|
||||||
} from "./http-config/axios-base-service";
|
|
||||||
import Cookies from "js-cookie";
|
import Cookies from "js-cookie";
|
||||||
|
import { httpDeleteInterceptor, httpGetInterceptor, httpPostInterceptor, httpPutInterceptor } from "./http-config/http-interceptor-services";
|
||||||
|
|
||||||
const token = Cookies.get("access_token");
|
const token = Cookies.get("access_token");
|
||||||
|
|
||||||
export async function createCategory(data: any) {
|
export async function createCategory(data: any) {
|
||||||
const headers = {
|
|
||||||
"content-type": "application/json",
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
};
|
|
||||||
const pathUrl = `/article-categories`;
|
const pathUrl = `/article-categories`;
|
||||||
return await httpPost(pathUrl, headers, data);
|
return await httpPostInterceptor(pathUrl, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function updateCategory(id: string, data: any) {
|
export async function updateCategory(id: string, data: any) {
|
||||||
const headers = {
|
|
||||||
"content-type": "application/json",
|
|
||||||
};
|
|
||||||
const pathUrl = `/article-categories/${id}`;
|
const pathUrl = `/article-categories/${id}`;
|
||||||
return await httpPut(pathUrl, headers, data);
|
return await httpPutInterceptor(pathUrl, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getCategoryById(id: number) {
|
export async function getCategoryById(id: number) {
|
||||||
const headers = {
|
return await httpGetInterceptor(`/article-categories/${id}`);
|
||||||
"content-type": "application/json",
|
|
||||||
};
|
|
||||||
return await httpGet(`/article-categories/${id}`, headers);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteCategory(id: number) {
|
export async function deleteCategory(id: number) {
|
||||||
const headers = {
|
return await httpDeleteInterceptor(`article-categories/${id}`);
|
||||||
"content-type": "application/json",
|
|
||||||
};
|
|
||||||
return await httpDeleteInterceptor(`article-categories/${id}`, headers);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function uploadCategoryThumbnail(id: string, data: any) {
|
export async function uploadCategoryThumbnail(id: string, data: any) {
|
||||||
const headers = {
|
const headers = {
|
||||||
"content-type": "multipart/form-data",
|
"content-type": "multipart/form-data",
|
||||||
};
|
};
|
||||||
return await httpPost(`/article-categories/thumbnail/${id}`, headers, data);
|
return await httpPostInterceptor(`/article-categories/thumbnail/${id}`, data, headers);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,42 +1,29 @@
|
||||||
import {
|
|
||||||
httpDeleteInterceptor,
|
|
||||||
httpGet,
|
|
||||||
httpPost,
|
|
||||||
} from "./http-config/axios-base-service";
|
|
||||||
|
|
||||||
import Cookies from "js-cookie";
|
import Cookies from "js-cookie";
|
||||||
|
import { httpDeleteInterceptor, httpGetInterceptor, httpPostInterceptor } from "./http-config/http-interceptor-services";
|
||||||
|
|
||||||
const token = Cookies.get("access_token");
|
const token = Cookies.get("access_token");
|
||||||
|
|
||||||
export async function listUserRole(data: any) {
|
export async function listUserRole(data: any) {
|
||||||
const headers = {
|
return await httpGetInterceptor(
|
||||||
"content-type": "application/json",
|
`/user-roles?limit=${data.limit}&page=${data.page}`
|
||||||
};
|
|
||||||
return await httpGet(
|
|
||||||
`/user-roles?limit=${data.limit}&page=${data.page}`,
|
|
||||||
headers
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createMasterUserRole(data: any) {
|
export async function createMasterUserRole(data: any) {
|
||||||
const headers = {
|
|
||||||
"content-type": "application/json",
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
};
|
|
||||||
const pathUrl = `/user-roles`;
|
const pathUrl = `/user-roles`;
|
||||||
return await httpPost(pathUrl, headers, data);
|
return await httpPostInterceptor(pathUrl, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getMasterUserRoleById(id: any) {
|
export async function getMasterUserRoleById(id: any) {
|
||||||
const headers = {
|
const headers = {
|
||||||
"content-type": "application/json",
|
"content-type": "application/json",
|
||||||
};
|
};
|
||||||
return await httpGet(`/user-roles/${id}`, headers);
|
return await httpGetInterceptor(`/user-roles/${id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteMasterUserRole(id: string) {
|
export async function deleteMasterUserRole(id: string) {
|
||||||
const headers = {
|
const headers = {
|
||||||
"content-type": "application/json",
|
"content-type": "application/json",
|
||||||
};
|
};
|
||||||
return await httpDeleteInterceptor(`/user-roles/${id}`, headers);
|
return await httpDeleteInterceptor(`/user-roles/${id}`);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { httpDeleteInterceptor, httpGet, httpPost, httpPut } from "./http-config/axios-base-service";
|
|
||||||
import Cookies from "js-cookie";
|
import Cookies from "js-cookie";
|
||||||
import axiosBaseInstance from "./http-config/http-base-instance";
|
import { httpGet, httpPost } from "./http-config/http-base-services";
|
||||||
|
import { httpDeleteInterceptor, httpGetInterceptor, httpPostInterceptor, httpPutInterceptor } from "./http-config/http-interceptor-services";
|
||||||
|
|
||||||
const token = Cookies.get("access_token");
|
const token = Cookies.get("access_token");
|
||||||
const id = Cookies.get("uie");
|
const id = Cookies.get("uie");
|
||||||
|
|
@ -13,78 +13,55 @@ export async function listMasterUsers(data: any) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function createMasterUser(data: any) {
|
export async function createMasterUser(data: any) {
|
||||||
const headers = {
|
|
||||||
"content-type": "application/json",
|
|
||||||
};
|
|
||||||
const pathUrl = `/users`;
|
const pathUrl = `/users`;
|
||||||
return await httpPost(pathUrl, headers, data);
|
return await httpPostInterceptor(pathUrl, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function emailValidation(data: any) {
|
export async function emailValidation(data: any) {
|
||||||
const headers = {
|
|
||||||
"content-type": "application/json",
|
|
||||||
};
|
|
||||||
const pathUrl = `/users/email-validation`;
|
const pathUrl = `/users/email-validation`;
|
||||||
return await httpPost(pathUrl, headers, data);
|
return await httpPost(pathUrl, data);
|
||||||
}
|
}
|
||||||
export async function setupEmail(data: any) {
|
export async function setupEmail(data: any) {
|
||||||
const headers = {
|
|
||||||
"content-type": "application/json",
|
|
||||||
};
|
|
||||||
const pathUrl = `/users/setup-email`;
|
const pathUrl = `/users/setup-email`;
|
||||||
return await httpPost(pathUrl, headers, data);
|
return await httpPost(pathUrl, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getDetailMasterUsers(id: string) {
|
export async function getDetailMasterUsers(id: string) {
|
||||||
const headers = {
|
const pathUrl = `/users/detail/${id}`;
|
||||||
"content-type": "application/json",
|
return await httpGetInterceptor(pathUrl);
|
||||||
};
|
|
||||||
return await httpGet(`/users/detail/${id}`, headers);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function editMasterUsers(data: any, id: string) {
|
export async function editMasterUsers(data: any, id: string) {
|
||||||
const headers = {
|
const pathUrl = `/users/${id}`
|
||||||
"content-type": "application/json",
|
return await httpPutInterceptor(pathUrl, data);
|
||||||
};
|
|
||||||
return await httpPut(`/users/${id}`, headers, data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteMasterUser(id: string) {
|
export async function deleteMasterUser(id: string) {
|
||||||
const headers = {
|
const pathUrl = `/users/${id}`
|
||||||
"content-type": "application/json",
|
return await httpDeleteInterceptor(pathUrl);
|
||||||
};
|
|
||||||
return await httpDeleteInterceptor(`/users/${id}`, headers);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function postSignIn(data: any) {
|
export async function postSignIn(data: any) {
|
||||||
const headers = {
|
|
||||||
accept: "application/json",
|
|
||||||
"content-type": "application/json",
|
|
||||||
};
|
|
||||||
const pathUrl = `/users/login`;
|
const pathUrl = `/users/login`;
|
||||||
return await httpPost(pathUrl, headers, data);
|
return await httpPost(pathUrl, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getProfile(code?: string) {
|
export async function getProfile(token?: string) {
|
||||||
const headers = {
|
const headers = {
|
||||||
"content-type": "application/json",
|
"content-type": "application/json",
|
||||||
Authorization: `Bearer ${code || token}`,
|
"Authorization": `Bearer ${token}`,
|
||||||
};
|
};
|
||||||
return await httpGet(`/users/info`, headers);
|
const pathUrl = `/users/info`;
|
||||||
|
return await httpGet(pathUrl, headers);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function updateProfile(data: any) {
|
export async function updateProfile(data: any) {
|
||||||
const headers = {
|
const pathUrl = `/users/${id}`;
|
||||||
"content-type": "application/json",
|
return await httpPutInterceptor(pathUrl, data);
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
};
|
|
||||||
return await httpPut(`/users/${id}`, headers, data);
|
|
||||||
}
|
}
|
||||||
export async function savePassword(data: any) {
|
export async function savePassword(data: any) {
|
||||||
const headers = {
|
const pathUrl = `/users/save-password`
|
||||||
"content-type": "application/json",
|
return await httpPostInterceptor(pathUrl, data);
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
};
|
|
||||||
return await httpPost(`/users/save-password`, headers, data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function resetPassword(data: any) {
|
export async function resetPassword(data: any) {
|
||||||
|
|
@ -102,23 +79,13 @@ export async function checkUsernames(username: string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function otpRequest(email: string, name: string) {
|
export async function otpRequest(email: string, name: string) {
|
||||||
const headers = {
|
const pathUrl = `/users/otp-request`;
|
||||||
"content-type": "application/json",
|
return await httpPost(pathUrl, { email, name });
|
||||||
};
|
|
||||||
return await httpPost(`/users/otp-request`, headers, { email, name });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function otpValidation(email: string, otpCode: string) {
|
export async function otpValidation(email: string, otpCode: string) {
|
||||||
const headers = {
|
const pathUrl = `/users/otp-validation`
|
||||||
"content-type": "application/json",
|
return await httpPost(pathUrl, { email, otpCode });
|
||||||
};
|
|
||||||
return await httpPost(`/users/otp-validation`, headers, { email, otpCode });
|
|
||||||
}
|
|
||||||
export async function otpValidationLogin(data: any) {
|
|
||||||
const headers = {
|
|
||||||
"content-type": "application/json",
|
|
||||||
};
|
|
||||||
return await httpPost(`/users/otp-validation`, headers, data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function postArticleComment(data: any) {
|
export async function postArticleComment(data: any) {
|
||||||
|
|
@ -134,31 +101,21 @@ export async function postArticleComment(data: any) {
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function editArticleComment(data: any, id: number) {
|
export async function editArticleComment(data: any, id: number) {
|
||||||
const headers = {
|
const pathUrl = `/article-comments/${id}`;
|
||||||
"content-type": "application/json",
|
return await httpPutInterceptor(pathUrl, data);
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
};
|
|
||||||
return await httpPut(`/article-comments/${id}`, headers, data);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getArticleComment(id: string) {
|
export async function getArticleComment(id: string) {
|
||||||
const headers = {
|
const pathUrl = `/article-comments?isPublic=true&articleId=${id}`;
|
||||||
"content-type": "application/json",
|
return await httpGet(pathUrl);
|
||||||
};
|
|
||||||
return await httpGet(`/article-comments?isPublic=true&articleId=${id}`, headers);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function deleteArticleComment(id: number) {
|
export async function deleteArticleComment(id: number) {
|
||||||
const headers = {
|
const pathUrl = `/article-comments/${id}`
|
||||||
"content-type": "application/json",
|
return await httpDeleteInterceptor(pathUrl);
|
||||||
};
|
|
||||||
return await httpDeleteInterceptor(`/article-comments/${id}`, headers);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getCsrfToken() {
|
export async function getCsrfToken() {
|
||||||
const pathUrl = "csrf-token";
|
const pathUrl = "csrf-token";
|
||||||
const headers = {
|
return httpGet(pathUrl);
|
||||||
"content-type": "application/json",
|
|
||||||
};
|
|
||||||
return httpGet(pathUrl, headers);
|
|
||||||
}
|
}
|
||||||
|
|
@ -1,47 +1,28 @@
|
||||||
import { PaginationRequest } from "@/types/globals";
|
import { PaginationRequest } from "@/types/globals";
|
||||||
import {
|
import { httpGetInterceptor, httpPostInterceptor, httpPutInterceptor } from "./http-config/http-interceptor-services";
|
||||||
httpDeleteInterceptor,
|
import { httpGet } from "./http-config/http-base-services";
|
||||||
httpGet,
|
|
||||||
httpPost,
|
|
||||||
httpPut,
|
|
||||||
} from "./http-config/axios-base-service";
|
|
||||||
|
|
||||||
export async function createCustomStaticPage(data: any) {
|
export async function createCustomStaticPage(data: any) {
|
||||||
const headers = {
|
|
||||||
"content-type": "application/json",
|
|
||||||
};
|
|
||||||
const pathUrl = `/custom-static-pages`;
|
const pathUrl = `/custom-static-pages`;
|
||||||
return await httpPost(pathUrl, headers, data);
|
return await httpPostInterceptor(pathUrl, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function editCustomStaticPage(data: any) {
|
export async function editCustomStaticPage(data: any) {
|
||||||
const headers = {
|
|
||||||
"content-type": "application/json",
|
|
||||||
};
|
|
||||||
const pathUrl = `/custom-static-pages/${data.id}`;
|
const pathUrl = `/custom-static-pages/${data.id}`;
|
||||||
return await httpPut(pathUrl, headers, data);
|
return await httpPutInterceptor(pathUrl, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getCustomStaticPage(props: PaginationRequest) {
|
export async function getCustomStaticPage(props: PaginationRequest) {
|
||||||
const { page, limit, search } = props;
|
const { page, limit, search } = props;
|
||||||
const headers = {
|
const pathUrl = `/custom-static-pages?limit=${limit}&page=${page}&title=${search}`;
|
||||||
"content-type": "application/json",
|
return await httpGetInterceptor(pathUrl);
|
||||||
};
|
|
||||||
return await httpGet(
|
|
||||||
`/custom-static-pages?limit=${limit}&page=${page}&title=${search}`,
|
|
||||||
headers
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getCustomStaticDetail(id: string) {
|
export async function getCustomStaticDetail(id: string) {
|
||||||
const headers = {
|
return await httpGetInterceptor(`/custom-static-pages/${id}`);
|
||||||
"content-type": "application/json",
|
|
||||||
};
|
|
||||||
return await httpGet(`/custom-static-pages/${id}`, headers);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getCustomStaticDetailBySlug(slug: string) {
|
export async function getCustomStaticDetailBySlug(slug: string) {
|
||||||
const headers = {
|
const pathUrl = `/custom-static-pages/slug/${slug}`;
|
||||||
"content-type": "application/json",
|
return await httpGet(pathUrl);
|
||||||
};
|
|
||||||
return await httpGet(`/custom-static-pages/slug/${slug}`, headers);
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
}
|
||||||
|
|
@ -1,52 +0,0 @@
|
||||||
|
|
||||||
import Cookies from "js-cookie";
|
|
||||||
import { httpGet, httpPost, httpPut } from "../http-config/axios-base-service";
|
|
||||||
|
|
||||||
const token = Cookies.get("access_token");
|
|
||||||
|
|
||||||
export async function getAllUserLevels(data?: any) {
|
|
||||||
const headers = {
|
|
||||||
"content-type": "application/json",
|
|
||||||
};
|
|
||||||
return await httpGet(
|
|
||||||
`user-levels?limit=${data?.limit || ""}&levelNumber=${
|
|
||||||
data?.levelNumber || ""
|
|
||||||
}&name=${data?.search || ""}&page=${data?.page || "1"}`,
|
|
||||||
headers
|
|
||||||
);
|
|
||||||
}
|
|
||||||
export async function getUserLevels(id: string) {
|
|
||||||
const headers = {
|
|
||||||
"content-type": "application/json",
|
|
||||||
};
|
|
||||||
return await httpGet(`user-levels/${id}`, headers);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getAccountById(id: string) {
|
|
||||||
const headers = {
|
|
||||||
"content-type": "application/json",
|
|
||||||
};
|
|
||||||
return await httpGet(`user-account/findById/${id}`, headers);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function createUserLevels(request: any) {
|
|
||||||
const headers = {
|
|
||||||
"content-type": "application/json",
|
|
||||||
};
|
|
||||||
return await httpPost(`user-levels`, headers, request);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function editUserLevels(id: string, request: any) {
|
|
||||||
const headers = {
|
|
||||||
"content-type": "application/json",
|
|
||||||
};
|
|
||||||
return await httpPut(`user-levels/${id}`, headers, request);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function changeIsApproval(request: any) {
|
|
||||||
const headers = {
|
|
||||||
"content-type": "application/json",
|
|
||||||
Authorization: `Bearer ${token}`,
|
|
||||||
};
|
|
||||||
return await httpPut(`user-levels/enable-approval`, headers, request);
|
|
||||||
}
|
|
||||||
|
|
@ -0,0 +1,87 @@
|
||||||
|
// Global chunk loading error handler
|
||||||
|
export function setupChunkErrorHandler() {
|
||||||
|
if (typeof window === 'undefined') return;
|
||||||
|
|
||||||
|
// Handle chunk loading errors
|
||||||
|
window.addEventListener('error', (event) => {
|
||||||
|
const error = event.error;
|
||||||
|
|
||||||
|
// Check if it's a chunk loading error
|
||||||
|
if (
|
||||||
|
error?.name === 'ChunkLoadError' ||
|
||||||
|
error?.message?.includes('Loading chunk') ||
|
||||||
|
error?.message?.includes('Failed to fetch')
|
||||||
|
) {
|
||||||
|
console.warn('Chunk loading error detected:', error);
|
||||||
|
|
||||||
|
// Prevent the error from being logged to console
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
// Show a user-friendly message
|
||||||
|
const message = document.createElement('div');
|
||||||
|
message.style.cssText = `
|
||||||
|
position: fixed;
|
||||||
|
top: 20px;
|
||||||
|
right: 20px;
|
||||||
|
background: #fef2f2;
|
||||||
|
border: 1px solid #fecaca;
|
||||||
|
color: #dc2626;
|
||||||
|
padding: 12px 16px;
|
||||||
|
border-radius: 8px;
|
||||||
|
font-size: 14px;
|
||||||
|
z-index: 9999;
|
||||||
|
max-width: 300px;
|
||||||
|
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
|
||||||
|
`;
|
||||||
|
message.innerHTML = `
|
||||||
|
<div style="display: flex; align-items: center; gap: 8px;">
|
||||||
|
<span>⚠️</span>
|
||||||
|
<span>Application update detected. Please refresh the page.</span>
|
||||||
|
</div>
|
||||||
|
<button onclick="window.location.reload()" style="
|
||||||
|
margin-top: 8px;
|
||||||
|
background: #dc2626;
|
||||||
|
color: white;
|
||||||
|
border: none;
|
||||||
|
padding: 4px 8px;
|
||||||
|
border-radius: 4px;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 12px;
|
||||||
|
">Refresh</button>
|
||||||
|
`;
|
||||||
|
|
||||||
|
document.body.appendChild(message);
|
||||||
|
|
||||||
|
// Auto-remove after 10 seconds
|
||||||
|
setTimeout(() => {
|
||||||
|
if (message.parentNode) {
|
||||||
|
message.parentNode.removeChild(message);
|
||||||
|
}
|
||||||
|
}, 10000);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Handle unhandled promise rejections (which might include chunk loading errors)
|
||||||
|
window.addEventListener('unhandledrejection', (event) => {
|
||||||
|
const error = event.reason;
|
||||||
|
|
||||||
|
if (
|
||||||
|
error?.name === 'ChunkLoadError' ||
|
||||||
|
error?.message?.includes('Loading chunk') ||
|
||||||
|
error?.message?.includes('Failed to fetch')
|
||||||
|
) {
|
||||||
|
console.warn('Unhandled chunk loading rejection:', error);
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
// Reload the page after a short delay
|
||||||
|
setTimeout(() => {
|
||||||
|
window.location.reload();
|
||||||
|
}, 1000);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Auto-setup when this module is imported
|
||||||
|
if (typeof window !== 'undefined') {
|
||||||
|
setupChunkErrorHandler();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,70 @@
|
||||||
|
import dynamic from 'next/dynamic';
|
||||||
|
import { ComponentType } from 'react';
|
||||||
|
|
||||||
|
interface DynamicImportOptions {
|
||||||
|
ssr?: boolean;
|
||||||
|
loading?: () => React.ReactElement;
|
||||||
|
retries?: number;
|
||||||
|
retryDelay?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createSafeDynamicImport<T extends ComponentType<any>>(
|
||||||
|
importFn: () => Promise<{ default: T }>,
|
||||||
|
options: DynamicImportOptions = {}
|
||||||
|
) {
|
||||||
|
const { ssr = false, loading, retries = 3, retryDelay = 1000 } = options;
|
||||||
|
|
||||||
|
return dynamic(
|
||||||
|
() => {
|
||||||
|
return new Promise<T>((resolve, reject) => {
|
||||||
|
let attempts = 0;
|
||||||
|
|
||||||
|
const attemptImport = async () => {
|
||||||
|
try {
|
||||||
|
const module = await importFn();
|
||||||
|
resolve(module.default);
|
||||||
|
} catch (error) {
|
||||||
|
attempts++;
|
||||||
|
|
||||||
|
// Check if it's a chunk loading error
|
||||||
|
if (
|
||||||
|
(error as any)?.name === 'ChunkLoadError' ||
|
||||||
|
(error as any)?.message?.includes('Loading chunk') ||
|
||||||
|
(error as any)?.message?.includes('Failed to fetch')
|
||||||
|
) {
|
||||||
|
if (attempts < retries) {
|
||||||
|
console.warn(`Chunk loading failed, retrying... (${attempts}/${retries})`);
|
||||||
|
setTimeout(attemptImport, retryDelay);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
reject(error);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
attemptImport();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ssr,
|
||||||
|
loading,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Predefined safe dynamic imports for common components
|
||||||
|
export const SafeCustomEditor = createSafeDynamicImport(
|
||||||
|
() => import('@/components/editor/custom-editor'),
|
||||||
|
{ ssr: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
export const SafeViewEditor = createSafeDynamicImport(
|
||||||
|
() => import('@/components/editor/view-editor'),
|
||||||
|
{ ssr: false }
|
||||||
|
);
|
||||||
|
|
||||||
|
export const SafeReactApexChart = createSafeDynamicImport(
|
||||||
|
() => import('react-apexcharts'),
|
||||||
|
{ ssr: false }
|
||||||
|
);
|
||||||
Loading…
Reference in New Issue