diff --git a/src/components/fields/Duration/TableCell.tsx b/src/components/fields/Duration/TableCell.tsx
index b42b6cf1..78be60c0 100644
--- a/src/components/fields/Duration/TableCell.tsx
+++ b/src/components/fields/Duration/TableCell.tsx
@@ -1,8 +1,8 @@
-import { IHeavyCellProps } from "@src/components/fields/types";
+import { IBasicCellProps } from "@src/components/fields/types";
import { getDurationString } from "./utils";
-export default function Duration({ value }: IHeavyCellProps) {
+export default function Duration({ value }: IBasicCellProps) {
if (
!value ||
!value.start ||
diff --git a/src/components/fields/Duration/index.tsx b/src/components/fields/Duration/index.tsx
index 1c82fe03..3ce1bf18 100644
--- a/src/components/fields/Duration/index.tsx
+++ b/src/components/fields/Duration/index.tsx
@@ -1,6 +1,6 @@
import { lazy } from "react";
import { IFieldConfig, FieldType } from "@src/components/fields/types";
-import withHeavyCell from "@src/components/fields/_withTableCell/withHeavyCell";
+import withBasicCell from "@src/components/fields/_withTableCell/withBasicCell";
import DurationIcon from "@mui/icons-material/TimerOutlined";
import BasicCell from "@src/components/fields/_BasicCell/BasicCellNull";
@@ -24,7 +24,7 @@ export const config: IFieldConfig = {
initialValue: {},
icon: ,
description: "Duration calculated from two timestamps.",
- TableCell: withHeavyCell(BasicCell, TableCell),
+ TableCell: withBasicCell(TableCell),
TableEditor: withSideDrawerEditor(TableCell),
SideDrawerField,
};
diff --git a/src/components/fields/GeoPoint/SideDrawerField.tsx b/src/components/fields/GeoPoint/SideDrawerField.tsx
new file mode 100644
index 00000000..97d21f38
--- /dev/null
+++ b/src/components/fields/GeoPoint/SideDrawerField.tsx
@@ -0,0 +1,56 @@
+import { ISideDrawerFieldProps } from "@src/components/fields/types";
+
+import { Box, Stack, TextField } from "@mui/material";
+import DatePicker from "@mui/lab/DatePicker";
+import DateTimeIcon from "@mui/icons-material/AccessTime";
+import { fieldSx, getFieldId } from "@src/components/SideDrawer/utils";
+import { GeoPoint } from "firebase/firestore";
+
+export default function GeoPointField({
+ column,
+ value,
+ onChange,
+ onSubmit,
+ disabled,
+}: ISideDrawerFieldProps) {
+ if (value !== undefined) {
+ }
+ const latitude = value?.latitude ?? null;
+ const longitude = value?.longitude ?? null;
+
+ const handleChange = (type: "latitude" | "longitude") => (e: any) => {
+ const v = e.target.value;
+ const updatedValue =
+ type === "latitude"
+ ? new GeoPoint(v ?? 0, longitude)
+ : new GeoPoint(latitude, v ?? 0);
+ onChange(updatedValue);
+ };
+
+ return (
+ <>
+
+
+
+
+ >
+ );
+}
diff --git a/src/components/fields/GeoPoint/TableCell.tsx b/src/components/fields/GeoPoint/TableCell.tsx
new file mode 100644
index 00000000..2fb90667
--- /dev/null
+++ b/src/components/fields/GeoPoint/TableCell.tsx
@@ -0,0 +1,13 @@
+import { IBasicCellProps } from "@src/components/fields/types";
+
+export default function Duration({ value }: IBasicCellProps) {
+ if (value === undefined) return null;
+
+ if (value.latitude === undefined || value.longitude === undefined)
+ throw new Error("Invalid value");
+ return (
+ <>
+ {value.latitude},{value.longitude}
+ >
+ );
+}
diff --git a/src/components/fields/GeoPoint/index.tsx b/src/components/fields/GeoPoint/index.tsx
new file mode 100644
index 00000000..3b3168ec
--- /dev/null
+++ b/src/components/fields/GeoPoint/index.tsx
@@ -0,0 +1,30 @@
+import { lazy } from "react";
+import { IFieldConfig, FieldType } from "@src/components/fields/types";
+import withBasicCell from "@src/components/fields/_withTableCell/withBasicCell";
+
+import GeoPointIcon from "@mui/icons-material/PinDropOutlined";
+import withSideDrawerEditor from "@src/components/Table/editors/withSideDrawerEditor";
+
+const TableCell = lazy(
+ () => import("./TableCell" /* webpackChunkName: "TableCell-GeoPoint" */)
+);
+const SideDrawerField = lazy(
+ () =>
+ import(
+ "./SideDrawerField" /* webpackChunkName: "SideDrawerField-GeoPoint" */
+ )
+);
+
+export const config: IFieldConfig = {
+ type: FieldType.geoPoint,
+ name: "GeoPoint (Alpha)",
+ group: "Numeric",
+ dataType: "{latitude:number; longitude:number}",
+ initialValue: {},
+ icon: ,
+ description: "Geo point is represented as latitude/longitude pair.",
+ TableCell: withBasicCell(TableCell),
+ TableEditor: withSideDrawerEditor(TableCell),
+ SideDrawerField,
+};
+export default config;
diff --git a/src/components/fields/GeoPoint/utils.ts b/src/components/fields/GeoPoint/utils.ts
new file mode 100644
index 00000000..97f1afd7
--- /dev/null
+++ b/src/components/fields/GeoPoint/utils.ts
@@ -0,0 +1,12 @@
+export const getDurationString = (start: Date, end: Date) => {
+ let distance = Math.abs(end.getTime() - start.getTime());
+ const hours = Math.floor(distance / 3600000);
+ distance -= hours * 3600000;
+ const minutes = Math.floor(distance / 60000);
+ distance -= minutes * 60000;
+ const seconds = Math.floor(distance / 1000);
+
+ return `${hours ? `${hours}h` : ""} ${("0" + minutes).slice(-2)}m ${(
+ "0" + seconds
+ ).slice(-2)}s`;
+};
diff --git a/src/components/fields/index.ts b/src/components/fields/index.ts
index 62ad1358..dff8bdfc 100644
--- a/src/components/fields/index.ts
+++ b/src/components/fields/index.ts
@@ -18,6 +18,7 @@ import Percentage from "./Percentage";
import Rating from "./Rating";
import Slider from "./Slider";
import Color from "./Color";
+import GeoPoint from "./GeoPoint";
import Date_ from "./Date";
import DateTime from "./DateTime";
import Duration from "./Duration";
@@ -61,6 +62,7 @@ export const FIELDS: IFieldConfig[] = [
Rating,
Slider,
Color,
+ GeoPoint,
/** DATE & TIME */
Date_,
DateTime,
diff --git a/src/constants/fields.ts b/src/constants/fields.ts
index b797a225..95eed901 100644
--- a/src/constants/fields.ts
+++ b/src/constants/fields.ts
@@ -17,6 +17,7 @@ export enum FieldType {
rating = "RATING",
slider = "SLIDER",
color = "COLOR",
+ geoPoint = "GEO_POINT",
// DATE & TIME
date = "DATE",
dateTime = "DATE_TIME",