diff --git a/README.md b/README.md
index 2d250f59..921fe43e 100644
--- a/README.md
+++ b/README.md
@@ -66,7 +66,7 @@ Screnshots: https://cms.demo.klaudsol.app
-
+Testing.....
diff --git a/backend/models/core/Entity.js b/backend/models/core/Entity.js
index 9353f027..b96a6a56 100644
--- a/backend/models/core/Entity.js
+++ b/backend/models/core/Entity.js
@@ -258,14 +258,21 @@ class Entity {
? { booleanValue: entry[attributeName] }
: { isNull: true },
},
+ {
+ name: "value_datetime",
+ value:
+ attributeType == "datetime"
+ ? { stringValue: entry[attributeName] }
+ : { isNull: true },
+ },
],
];
}, []);
//Insert Values by batch
const insertValuesBatchSQL = `INSERT INTO \`values\`(entity_id, attribute_id,
- value_string, value_long_string, value_double, value_boolean
- ) VALUES (:entity_id, :attribute_id, :value_string, :value_long_string, :value_double, :value_boolean)
+ value_string, value_long_string, value_datetime, value_double, value_boolean
+ ) VALUES (:entity_id, :attribute_id, :value_string, :value_long_string, :value_datetime, :value_double, :value_boolean)
`;
await db.batchExecuteStatement(insertValuesBatchSQL, valueBatchParams);
@@ -452,6 +459,13 @@ class Entity {
? { booleanValue: entries[attributeName] }
: { isNull: true },
},
+ {
+ name: "value_datetime",
+ value:
+ attributeType == "datetime"
+ ? { stringValue: entries[attributeName] }
+ : { isNull: true },
+ },
],
];
}, []);
@@ -487,8 +501,8 @@ class Entity {
if (nonExistingVal.length) {
const insertValuesBatchSQL = `INSERT INTO \`values\`(entity_id, attribute_id,
- value_string, value_long_string, value_double, value_boolean
- ) VALUES (:entity_id, :attribute_id, :value_string, :value_long_string, :value_double, :value_boolean)
+ value_string, value_long_string, value_datetime, value_double, value_boolean
+ ) VALUES (:entity_id, :attribute_id, :value_string, :value_long_string, :value_datetime, :value_double, :value_boolean)
`;
await db.batchExecuteStatement(insertValuesBatchSQL, nonExistingVal);
@@ -499,6 +513,7 @@ class Entity {
const updateValuesBatchSQL = `UPDATE \`values\` SET
value_string = :value_string,
value_long_string = :value_long_string,
+ value_datetime = :value_datetime,
value_double = :value_double,
value_boolean = :value_boolean
WHERE entity_id = :entity_id AND attribute_id = :attribute_id
@@ -511,4 +526,4 @@ class Entity {
}
}
-export default Entity;
+export default Entity;
\ No newline at end of file
diff --git a/components/EntityAttributeValue.js b/components/EntityAttributeValue.js
index de01eac3..4f42f28b 100644
--- a/components/EntityAttributeValue.js
+++ b/components/EntityAttributeValue.js
@@ -47,6 +47,8 @@ const formatImage = (key) => {
case 'float':
//TODO: Find a more accurate representation of float
return Number(item.value_double);
+ case 'datetime':
+ return item.value_datetime;
case 'custom':
//TODO: In the future, everything would pass this code
@@ -62,4 +64,4 @@ const formatImage = (key) => {
return attributeType.toDatabase(item);
}
- }
+ }
\ No newline at end of file
diff --git a/components/attribute_types/AttributeType.js b/components/attribute_types/AttributeType.js
index c4e84a33..3ec6ce90 100644
--- a/components/attribute_types/AttributeType.js
+++ b/components/attribute_types/AttributeType.js
@@ -12,6 +12,7 @@ export default class AttributeType {
static TEXT_CMS_TYPE = 'text';
static TEXTAREA_CMS_TYPE = 'textarea';
static RICH_TEXT_CMS_TYPE = 'rich-text';
+ static DATETIME_CMS_TYPE = 'datetime';
static FILE_CMS_TYPE = 'file';
static CUSTOM = 'custom';
diff --git a/components/attribute_types/AttributeTypeFactory.js b/components/attribute_types/AttributeTypeFactory.js
index 035d3e7d..a6605435 100644
--- a/components/attribute_types/AttributeTypeFactory.js
+++ b/components/attribute_types/AttributeTypeFactory.js
@@ -4,6 +4,7 @@ import TextareaAttributeType from "@/components/attribute_types/TextareaAttribut
import LegacyAttributeType from '@/components/attribute_types/LegacyAttributeType';
import { plugin } from '@/components/plugin/plugin';
import RichTextAttributeType from '@/components/attribute_types/RichTextAttributeType';
+import DateTimeAttributeType from '@/components/attribute_types/DateTimeAttributeType';
import FileAtrributeType from './FileAttributeType';
export default class AttributeTypeFactory {
@@ -15,6 +16,8 @@ export default class AttributeTypeFactory {
return new TextareaAttributeType({data, metadata});
case AttributeType.RICH_TEXT_CMS_TYPE:
return new RichTextAttributeType({data, metadata});
+ case AttributeType.DATETIME_CMS_TYPE:
+ return new DateTimeAttributeType({data, metadata});
case AttributeType.FILE_CMS_TYPE:
return new FileAtrributeType({data, metadata});
case AttributeType.CUSTOM:
diff --git a/components/attribute_types/DateTimeAttributeType.js b/components/attribute_types/DateTimeAttributeType.js
new file mode 100644
index 00000000..371045c8
--- /dev/null
+++ b/components/attribute_types/DateTimeAttributeType.js
@@ -0,0 +1,51 @@
+import AttributeType from '@/components/attribute_types/AttributeType';
+import { useFormikContext, useField } from "formik";
+import { useState, useEffect } from 'react';
+import DatePicker from 'react-datepicker';
+import 'react-datepicker/dist/react-datepicker.css';
+import moment from 'moment';
+
+const DateTimeAttributeReadOnlyComponent = ({ text }) => {
+ const parsedDate = new Date(text);
+ const formattedDate = moment(parsedDate).format('MMM. D, YYYY - hh:mm A');
+ return <>{formattedDate}>;
+};
+
+const DateTimeAttributeEditableComponent = ({ name }) => {
+ const { setFieldValue } = useFormikContext();
+ const [{ value }] = useField(name);
+ const [selectedDate, setSelectedDate] = useState(value ? new Date(value) : new Date()); // Set initial selected date to today
+
+ useEffect(() => {
+ if (selectedDate) {
+ const formattedDate = moment(selectedDate).format('YYYY-MM-DD HH:mm');
+ setFieldValue(name, formattedDate);
+ } else {
+ setFieldValue(name, null);
+ }
+ }, [selectedDate, name, setFieldValue]);
+
+ const handleDateChange = (date) => {
+ setSelectedDate(date);
+ };
+
+ return (
+
+ );
+};
+
+export default class DateTimeAttributeType extends AttributeType {
+ readOnlyComponent() {
+ return DateTimeAttributeReadOnlyComponent;
+ }
+
+ editableComponent() {
+ return DateTimeAttributeEditableComponent;
+ }
+}
\ No newline at end of file
diff --git a/components/cmsTypes.js b/components/cmsTypes.js
index 697098db..4163d08c 100644
--- a/components/cmsTypes.js
+++ b/components/cmsTypes.js
@@ -14,6 +14,7 @@ export const CMS_TYPES = {
CHECKBOX: "checkbox",
CUSTOM: "custom",
RICH_TEXT: "rich-text",
+ DATETIME: "datetime",
FILE: "file"
};
@@ -44,4 +45,3 @@ export const resourceValueTypes = [
"value_double",
"value_boolean",
];
-
diff --git a/components/renderers/admin/AdminRenderer.js b/components/renderers/admin/AdminRenderer.js
index d55bc4fd..f15907ad 100644
--- a/components/renderers/admin/AdminRenderer.js
+++ b/components/renderers/admin/AdminRenderer.js
@@ -11,6 +11,7 @@ import VideoRenderer from "./VideoRenderer";
import BooleanRenderer from "./BooleanRenderer";
import { plugin } from "@/components/plugin/plugin";
import RichTextAttributeType from "@/components/attribute_types/RichTextAttributeType";
+import DateTimeAttributeType from "@/components/attribute_types/DateTimeAttributeType";
import AttributeTypeFactory from "@/components/attribute_types/AttributeTypeFactory";
const AdminRenderer = ({ type, ...params }) => {
@@ -35,6 +36,7 @@ const AdminRenderer = ({ type, ...params }) => {
case CMS_TYPES.BOOLEAN:
return ;
case CMS_TYPES.RICH_TEXT:
+ case CMS_TYPES.DATETIME:
case CMS_TYPES.FILE:
case CMS_TYPES.CUSTOM:
const attributeType = AttributeTypeFactory.create({metadata: {type, custom_name: params.customName, id: params.id}});
@@ -45,4 +47,4 @@ const AdminRenderer = ({ type, ...params }) => {
}
};
-export default AdminRenderer;
+export default AdminRenderer;
\ No newline at end of file
diff --git a/constants/index.js b/constants/index.js
index 8519c65f..9551a053 100644
--- a/constants/index.js
+++ b/constants/index.js
@@ -7,6 +7,7 @@ export const inputValues = [
{ value: "gallery", option: "Gallery" },
{ value: "float", option: "Number" },
{ value: "video", option: "Video" },
+ { value: "datetime", option: "DateTime" },
{ value: "boolean", option: "Boolean" },
{ value: "file", option: "File" },
{ value: "custom", option: "Custom" }
@@ -45,4 +46,3 @@ export const operators = {
};
export const slugTooltipText = "Slugs are the URL-friendly names of your contents. You can access the contens in your API via their numerical ID (e.g. /api/articles/12) or their slug (e.g. /api/articles/my-first-blog-post)";
-
diff --git a/db/migrations/20230427114000_connect_read_pending_users_capabilities.json b/db/migrations/20230427114000_connect_read_pending_users_capabilities.json
index 557f2d99..1f427b10 100644
--- a/db/migrations/20230427114000_connect_read_pending_users_capabilities.json
+++ b/db/migrations/20230427114000_connect_read_pending_users_capabilities.json
@@ -8,4 +8,4 @@
"DELETE FROM group_capabilities WHERE group_id IN (1, 2) ",
"AND capabilities_id = (SELECT id FROM capabilities WHERE name = 'read_pending_users' AND is_system_supplied = true);"
]
-}
+}
\ No newline at end of file
diff --git a/package.json b/package.json
index f5e70ae5..f9e63916 100644
--- a/package.json
+++ b/package.json
@@ -58,7 +58,7 @@
"react-component-export-image": "^1.0.6",
"react-confirm-alert": "2.0.2",
"react-csv-downloader": "^2.8.0",
- "react-datepicker": "^4.8.0",
+ "react-datepicker": "^4.15.0",
"react-dom": "^18.2.0",
"react-hook-form": "^7.33.0",
"react-icons": "^4.3.1",
diff --git a/styles/klaudsolcms.scss b/styles/klaudsolcms.scss
index cd635cc4..cf20565f 100644
--- a/styles/klaudsolcms.scss
+++ b/styles/klaudsolcms.scss
@@ -1398,3 +1398,21 @@ $onFocus: #323C4E;
font-weight: 590;
}
}
+
+/**
+======================================================
+ MODIFY DATE PICKER DESIGN
+======================================================
+**/
+.react-datepicker__input-container input {
+ padding: 8px;
+ border-radius: 5px;
+ border: 1px solid #ccc !important;
+}
+// change the selected date color
+.react-datepicker__day--selected, .react-datepicker__time-list-item--selected {
+ background-color: #467286 !important;
+}
+.react-datepicker__time-container {
+ overflow: hidden;
+}
diff --git a/yarn.lock b/yarn.lock
index 4d0d8c4c..d88bf603 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -4294,10 +4294,10 @@ react-csv-downloader@^2.8.0:
dependencies:
file-saver "^2.0.2"
-react-datepicker@^4.8.0:
- version "4.11.0"
- resolved "https://registry.yarnpkg.com/react-datepicker/-/react-datepicker-4.11.0.tgz#40e73b4729a284ed206fdb322b8e84eb566e11a3"
- integrity sha512-50n93o7mQwBEhg05tbopjFKgs8qgi8VBCAOMC4VqrKut72eAjESc/wXS/k5hRtnP0oe2FCGw7MJuIwh37wuXOw==
+react-datepicker@^4.15.0:
+ version "4.15.0"
+ resolved "https://registry.yarnpkg.com/react-datepicker/-/react-datepicker-4.15.0.tgz#489834773fbcf87852273b4642f0c5bd3811cef7"
+ integrity sha512-kysEqVv6wRQkmAyn0wJi4Xx+JjBPBtXWfQSfh6sR3wdzZX1/LjYTPmaurnVI6ao177ecompg8ze7NCgtEGW78A==
dependencies:
"@popperjs/core" "^2.9.2"
classnames "^2.2.6"