diff --git a/packages/example/src/lib/schema/datetime.ts b/packages/example/src/lib/schema/datetime.ts new file mode 100644 index 0000000..54875d4 --- /dev/null +++ b/packages/example/src/lib/schema/datetime.ts @@ -0,0 +1,32 @@ +import { DateTime, identity, ParseResult, Schema } from "effect" + + +export const DateTimeUtcFromZoned = Schema.transformOrFail( + Schema.DateTimeZonedFromSelf, + Schema.DateTimeUtcFromSelf, + { + strict: true, + encode: DateTime.setZoneCurrent, + decode: zoned => ParseResult.succeed(DateTime.toUtc(zoned)), + }, +) + +export const DateTimeZonedFromUtc = Schema.transformOrFail( + Schema.DateTimeUtcFromSelf, + Schema.DateTimeZonedFromSelf, + { + strict: true, + encode: zoned => ParseResult.succeed(DateTime.toUtc(zoned)), + decode: DateTime.setZoneCurrent, + }, +) + +export const DateTimeUtcFromZonedInput = Schema.transform( + Schema.String, + Schema.compose(Schema.DateTimeZoned, DateTimeUtcFromZoned), + { + strict: true, + encode: v => v.slice(0, 16), + decode: identity, + }, +) diff --git a/packages/example/src/lib/schema/index.ts b/packages/example/src/lib/schema/index.ts new file mode 100644 index 0000000..b1e80ed --- /dev/null +++ b/packages/example/src/lib/schema/index.ts @@ -0,0 +1 @@ +export * from "./datetime" diff --git a/packages/example/src/runtime.ts b/packages/example/src/runtime.ts index 67f73ea..5524d5f 100644 --- a/packages/example/src/runtime.ts +++ b/packages/example/src/runtime.ts @@ -1,10 +1,11 @@ import { FetchHttpClient } from "@effect/platform" import { Clipboard, Geolocation, Permissions } from "@effect/platform-browser" -import { Layer } from "effect" +import { DateTime, Layer } from "effect" import { ReactManagedRuntime } from "effect-fc" export const AppLive = Layer.empty.pipe( + Layer.provideMerge(DateTime.layerCurrentZoneLocal), Layer.provideMerge(Clipboard.layer), Layer.provideMerge(Geolocation.layer), Layer.provideMerge(Permissions.layer), diff --git a/packages/example/src/todo/Todo.tsx b/packages/example/src/todo/Todo.tsx index 75bf32f..e2de3bd 100644 --- a/packages/example/src/todo/Todo.tsx +++ b/packages/example/src/todo/Todo.tsx @@ -1,4 +1,5 @@ import * as Domain from "@/domain" +import { DateTimeUtcFromZonedInput } from "@/lib/schema" import { TextAreaInput } from "@/lib/TextAreaInput" import { TextFieldInput } from "@/lib/TextFieldInput" import { Box, Button, Flex, IconButton } from "@radix-ui/themes" @@ -13,7 +14,7 @@ import { TodosState } from "./TodosState.service" const StringTextAreaInput = TextAreaInput({ schema: Schema.String }) -const OptionalDateInput = TextFieldInput({ optional: true, schema: Schema.DateTimeUtc }) +const OptionalDateInput = TextFieldInput({ optional: true, schema: DateTimeUtcFromZonedInput }) const makeTodo = makeUuid4.pipe( Effect.map(id => Domain.Todo.Todo.make({ @@ -58,7 +59,10 @@ export class Todo extends Component.makeUntraced(function* Todo(props: TodoProps - + {props._tag === "new" &&