@@ -31,4 +35,4 @@ export default function Admin({cache}) {
);
}
-export const getServerSideProps = getSessionCache();
\ No newline at end of file
+export const getServerSideProps = getSessionCache();
diff --git a/pages/admin/content-manager/[entity_type_slug]/[id].js b/pages/admin/content-manager/[entity_type_slug]/[id].js
index 5029980a..27c6f0a7 100644
--- a/pages/admin/content-manager/[entity_type_slug]/[id].js
+++ b/pages/admin/content-manager/[entity_type_slug]/[id].js
@@ -154,7 +154,7 @@ export default function Type({ cache }) {
body: JSON.stringify(entry),
});
- const { message, presignedUrls } = await response.json();
+ const { presignedUrls } = await response.json();
if (files.length > 0) await uploadFilesToUrl(files, presignedUrls);
diff --git a/pages/admin/content-manager/[entity_type_slug]/index.js b/pages/admin/content-manager/[entity_type_slug]/index.js
index 24aedd80..2e07daba 100644
--- a/pages/admin/content-manager/[entity_type_slug]/index.js
+++ b/pages/admin/content-manager/[entity_type_slug]/index.js
@@ -41,7 +41,8 @@ import {
SET_FIRST_FETCH,
SET_PAGE,
PAGE_SETS_RENDERER,
- TOGGLE_VIEW
+ TOGGLE_VIEW,
+ SET_VIEW
} from "@/lib/actions";
import AppContentPagination from "components/klaudsolcms/pagination/AppContentPagination";
import { defaultPageRender, maximumNumberOfPage, EntryValues, writeContents} from "lib/Constants"
@@ -52,7 +53,7 @@ export default function ContentManager({ cache }) {
const capabilities = cache?.capabilities;
const { entity_type_slug } = router.query;
const controllerRef = useRef();
- const { state: {currentContentType} } = useContext(RootContext);
+ const { state: {settings, currentContentType} } = useContext(RootContext);
const [state, dispatch] = useReducer(contentManagerReducer, initialState);
@@ -102,12 +103,15 @@ export default function ContentManager({ cache }) {
})();
}, [entity_type_slug, state.page, state.entry, state.setsRenderer]);
-
useEffect(() => {
dispatch({type: SET_PAGE,payload: defaultPageRender});
dispatch({type: PAGE_SETS_RENDERER,payload: defaultPageRender});
}, [entity_type_slug]);
+ useEffect(() => {
+ dispatch({ type: SET_VIEW, payload: settings.default_view });
+ }, [state.firstFetch])
+
const handleView = () => {
dispatch({ type: TOGGLE_VIEW })
}
diff --git a/pages/admin/settings.js b/pages/admin/settings.js
index 0fbc82b6..af9dfe13 100644
--- a/pages/admin/settings.js
+++ b/pages/admin/settings.js
@@ -1,8 +1,16 @@
import InnerSingleLayout from "@/components/layouts/InnerSingleLayout";
import CacheContext from "@/components/contexts/CacheContext";
+import RootContext from "@/components/contexts/RootContext";
import { getSessionCache } from "@klaudsol/commons/lib/Session";
-import { Formik, Form } from "formik";
-import { useRef, useReducer, useEffect, useState, useCallback } from "react";
+import { Formik, Form, Field } from "formik";
+import {
+ useRef,
+ useReducer,
+ useContext,
+ useEffect,
+ useState,
+ useCallback,
+} from "react";
import AppButtonLg from "@/components/klaudsolcms/buttons/AppButtonLg";
import AppButtonSpinner from "@/components/klaudsolcms/AppButtonSpinner";
@@ -16,103 +24,73 @@ import {
settingReducer,
initialState,
} from "@/components/reducers/settingReducer";
-import { SAVING, LOADING, DELETING, CLEANUP, SET_VALUES, SET_CHANGED, SET_ERROR } from "@/lib/actions";
+import {
+ SAVING,
+ LOADING,
+ DELETING,
+ CLEANUP,
+ SET_VALUES,
+ SET_CHANGED,
+ SET_ERROR,
+} from "@/lib/actions";
import { defaultLogo } from "@/constants/index";
-import { convertToFormData, getAllFiles } from "@/lib/s3FormController";
+import { getFilesToDelete, getBody } from "@/lib/s3FormController";
+import { uploadFilesToUrl } from "@/backend/data_access/S3";
import { validImageTypes } from "@/lib/Constants";
import { readSettings, modifyLogo } from "@/lib/Constants";
export default function Settings({ cache }) {
const formRef = useRef();
const [state, dispatch] = useReducer(settingReducer, initialState);
- const isValueExists = Object.keys(state.values).length !== 0
+ const { state: rootState, dispatch: rootDispatch } = useContext(RootContext);
+ const isValueExists = Object.keys(state.values).length !== 0;
const capabilities = cache?.capabilities;
- const setInitialValues = (data) => {
- const initialVal = Object.keys(data).length !== 0
- ? { mainlogo: { name: data.key, link: data.link, key: data.value } }
- : {};
- return initialVal;
- };
-
- useEffect(() => {
- (async () => {
- try {
- const response = await slsFetch("/api/settings/mainlogo");
- const { data } = await response.json();
- const newData = setInitialValues(data);
-
- dispatch({ type: SET_VALUES, payload: newData });
- } catch (error) {
- dispatch({ type: SET_ERROR, payload: error.message });
- } finally {
- dispatch({ type: CLEANUP });
- }
- })();
- }, []);
-
- const onDelete = useCallback((setStaticLink) => {
- (async () => {
- try {
- dispatch({ type: DELETING, payload: true });
- const response = await slsFetch(`/api/settings/mainlogo`, {
- method: "DELETE",
- headers: {
- "Content-type": "application/json",
- },
- });
- dispatch({ type: SET_VALUES, payload: {} });
- formRef.current.resetForm({ values: {} });
- setStaticLink('');
- dispatch({ type: SET_CHANGED, payload:false })
- } catch (ex) {
- console.error(ex);
- } finally {
- dispatch({ type: DELETING, payload: false });
- }
- })();
- }, []);
-
const onSubmit = (evt) => {
evt.preventDefault();
formRef.current.handleSubmit();
};
- const getS3Keys = (files) => {
- if(!files) return
+ const getFilesToDelete = (values) => {
+ const files = Object.keys(values).filter(
+ (value) => values[value] instanceof File
+ );
+ const keys = files.map((file) => state.values[file].key);
- const fileKeys = Object.keys(files);
- const s3Keys = fileKeys.map((file) => state.values[file].key);
-
- return s3Keys;
+ return keys;
};
const formikParams = {
innerRef: formRef,
- initialValues: state.values,
+ initialValues: rootState.settings,
+ enableReinitialize: true,
onSubmit: (values) => {
(async () => {
try {
dispatch({ type: SAVING });
- const isFile = Object.entries(values)[0][1] instanceof File;
- const isCreateMode = !isValueExists && isFile;
-
- const filesToUpload = !isCreateMode && getAllFiles(values);
- const s3Keys = getS3Keys(filesToUpload);
- const newValues = isCreateMode ? values : {...values, toDeleteRaw: s3Keys}
+ const { files, data, fileNames } = await getBody(values);
+ const toDelete = getFilesToDelete(values);
+
+ const entry = {
+ ...data,
+ fileNames,
+ toDelete,
+ };
+
+ const url = `/api/settings`;
+ const params = {
+ method: "PUT",
+ headers: {
+ "Content-type": "application/json",
+ },
+ body: JSON.stringify(entry),
+ };
+
+ const response = await slsFetch(url, params);
- const formattedEntries = convertToFormData(newValues);
-
- const response = await slsFetch(`/api/settings${isCreateMode ? '' : '/mainlogo'}`, {
- method: `${isCreateMode ? "POST" : "PUT"}`,
- body: formattedEntries,
- });
- const { data } = await response.json()
+ const { presignedUrls } = await response.json();
- const newData = setInitialValues(data);
- dispatch({ type: SET_VALUES, payload: newData });
- formRef.current.resetForm({ values: newData });
- dispatch({ type: SET_CHANGED, payload:false })
+ if (files.length > 0) await uploadFilesToUrl(files, presignedUrls);
} catch (ex) {
console.error(ex);
} finally {
@@ -127,47 +105,43 @@ export default function Settings({ cache }) {
- {capabilities.includes(readSettings) ?
-
-
-
Settings
-
-
- {capabilities.includes(modifyLogo) &&
:
}
- onClick={onSubmit}
- isDisabled={state.isLoading || state.isSaving || state.isDeleting || !state.isChanged}
- />}
-
+
+
+
Settings
+
:
}
+ onClick={onSubmit}
+ />
- {!state.isLoading && (
-
- {() => (
-
- )}
-
- )}
- {!isValueExists && !state.isLoading && "Logo is not set"}
-
:
{state.errorMessage}
}
+
+
+
+
diff --git a/pages/api/settings.js b/pages/api/settings.js
index 1deb080e..eee3aaa6 100644
--- a/pages/api/settings.js
+++ b/pages/api/settings.js
@@ -3,6 +3,7 @@ import { withSession } from '@klaudsol/commons/lib/Session';
import { defaultErrorHandler } from '@klaudsol/commons/lib/ErrorHandler';
import {
generateResource,
+ generatePresignedUrls,
addFileToBucket
}
from "@/backend/data_access/S3";
@@ -17,12 +18,6 @@ import { readSettings, writeSettings } from '@/lib/Constants';
export default withSession(handler);
-export const config = {
- api: {
- bodyParser: false,
- },
-}
-
async function handler(req, res) {
try {
@@ -32,6 +27,8 @@ async function handler(req, res) {
case "POST":
const { req: parsedReq, res: parsedRes } = await parseFormData(req, res);
return await create(parsedReq, parsedRes);
+ case "PUT":
+ return update(req, res);
default:
throw new Error(`Unsupported method: ${req.method}`);
}
@@ -41,9 +38,33 @@ async function handler(req, res) {
}
async function get(req, res) {
-
+ await assertUserCan(readSettings, req);
+
+ const settings = await Setting.get();
+
+ // Formats the values for the `main_logo` property since its an image from S3
+ const mainLogoIndex = settings.findIndex((item) => item.setting === 'main_logo');
+ const mainLogo = settings[mainLogoIndex];
+ const mainLogoValue = mainLogo.value;
+ mainLogo.value = {
+ name: mainLogoValue.substring(mainLogoValue.indexOf('_') + 1),
+ key: mainLogoValue,
+ link: `${process.env.KS_S3_BASE_URL}/${mainLogoValue}`
+ }
+ settings[mainLogoIndex] = mainLogo;
+
+ const output = {
+ data: settings,
+ metadata: {}
+ }
+
+ output.metadata.hash = createHash(output);
+
+ setCORSHeaders({response: res, url: process.env.FRONTEND_URL});
+ settings ? res.status(OK).json(output ?? []) : res.status(NOT_FOUND).json({})
}
+// deprecated
async function create(req, res) {
try {
await assert({
@@ -97,3 +118,19 @@ async function create(req, res) {
}
}
+
+async function update(req, res) {
+ await assert({
+ loggedIn: true,
+ }, req);
+
+ await assertUserCan(writeSettings, req);
+
+ const { fileNames, toDelete, ...entry } = req.body;
+ await Setting.update(entry);
+
+ const presignedUrls = fileNames.length > 0 && await generatePresignedUrls(fileNames);
+
+ res.status(OK).json({ message: 'Successfully updated the settings', presignedUrls })
+}
+
diff --git a/pages/index.js b/pages/index.js
index d70ce767..e64ef0fd 100644
--- a/pages/index.js
+++ b/pages/index.js
@@ -13,33 +13,35 @@ export default function Index(props) {
export const getServerSideProps = withIronSessionSsr(
async function getServerSideProps({ req, res }) {
-
try {
- var rawData = await Setting.get({ slug: mainlogo });
- var data = { ...rawData[0], link:`${process.env.KS_S3_BASE_URL}/${rawData[0].value}` };
- // To ensure maximum efficiency and avoid any unnecessary involvement with the assertUserCan() function,
- // it is recommended to directly fetch our logo from the core setting.
- } catch (err) {}
+ const rawData = await Setting.getLogo();
+ const data = rawData[0];
- try{
- if(req.session?.cache?.forcePasswordChange){
- await serverSideLogout(req)
- }
- } catch(err){}
+ if (req.session?.cache?.forcePasswordChange) {
+ await serverSideLogout(req);
+ }
+
+ const homepage = req.session?.cache?.homepage;
+ if (homepage && !req.session?.cache?.forcePasswordChange) {
+ return {
+ redirect: {
+ permanent: false,
+ destination: `/${homepage}`,
+ },
+ };
+ } else {
+ const logoLink = `${process.env.KS_S3_BASE_URL}/${data.value}`;
+
+ return {
+ props: {
+ logo: data.value !== "default" ? logoLink : "/logo-180x180.png",
+ },
+ };
+ }
+ } catch (err) {
+ console.error(err);
- let homepage = req.session?.cache?.homepage;
- if ((homepage && !req.session?.cache?.forcePasswordChange)) {
- return {
- redirect: {
- permanent: false,
- destination: `/${homepage}`,
- },
- };
- }
- else {
- return {
- props: { logo: (process.env.KS_S3_BASE_URL && rawData?.length) ? data : {} },
- };
+ return { props: {} };
}
},
sessionOptions