@colisweb/rescript-toolkit 2.67.0 → 2.67.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/.gitlab-ci.yml +3 -2
  2. package/.yarn/cache/boolbase-npm-1.0.0-965fe9af6d-3e25c80ef6.zip +0 -0
  3. package/.yarn/cache/camelcase-npm-3.0.0-0c65af0c7f-ae4fe1c17c.zip +0 -0
  4. package/.yarn/cache/comma-separated-tokens-npm-1.0.8-00dbbf3418-0adcb07174.zip +0 -0
  5. package/.yarn/cache/css-selector-parser-npm-1.4.1-b8c642c4c5-31948754e5.zip +0 -0
  6. package/.yarn/cache/fault-npm-2.0.1-c462630f58-c9b30f47d9.zip +0 -0
  7. package/.yarn/cache/format-npm-0.2.2-679f3acc64-646a60e133.zip +0 -0
  8. package/.yarn/cache/github-slugger-npm-2.0.0-3afba76e6c-250375cde2.zip +0 -0
  9. package/.yarn/cache/hast-util-has-property-npm-1.0.4-a09b607810-23025cee66.zip +0 -0
  10. package/.yarn/cache/hast-util-has-property-npm-2.0.1-aa6919669c-cc909b7e29.zip +0 -0
  11. package/.yarn/cache/hast-util-heading-rank-npm-2.1.1-0d71da5801-a49233e9ac.zip +0 -0
  12. package/.yarn/cache/hast-util-is-element-npm-1.1.0-be10e62fa7-30fad3f65e.zip +0 -0
  13. package/.yarn/cache/hast-util-is-element-npm-2.1.3-3051d610ff-9d988f6839.zip +0 -0
  14. package/.yarn/cache/hast-util-select-npm-1.0.1-115974f390-9cdb20850f.zip +0 -0
  15. package/.yarn/cache/hast-util-to-string-npm-2.0.0-c6108aa2b8-0c087f8dee.zip +0 -0
  16. package/.yarn/cache/hast-util-to-text-npm-3.1.2-922eb1f623-d17cf3344c.zip +0 -0
  17. package/.yarn/cache/hast-util-whitespace-npm-1.0.4-43bb1ff3d0-b7f4a1942b.zip +0 -0
  18. package/.yarn/cache/{husky-npm-8.0.2-46c70b41ed-e101656fcb.zip → husky-npm-8.0.3-b0b59c5127-837bc7e441.zip} +0 -0
  19. package/.yarn/cache/lowlight-npm-2.8.0-c65abb6cac-c45a91e715.zip +0 -0
  20. package/.yarn/cache/not-npm-0.1.0-a1712708cd-8043bb53bc.zip +0 -0
  21. package/.yarn/cache/nth-check-npm-1.0.2-3f6d0d22eb-59e115fdd7.zip +0 -0
  22. package/.yarn/cache/property-information-npm-3.2.0-ae434c241d-ed2614520d.zip +0 -0
  23. package/.yarn/cache/rehype-add-classes-npm-1.0.0-ddf6b4e74d-25c0e2dbf5.zip +0 -0
  24. package/.yarn/cache/rehype-autolink-headings-npm-6.1.1-fe8058cc11-60782fb2e5.zip +0 -0
  25. package/.yarn/cache/rehype-highlight-npm-6.0.0-5179257139-5a70e7ad45.zip +0 -0
  26. package/.yarn/cache/rehype-slug-npm-5.1.0-ae08840ba8-2a7c17fd74.zip +0 -0
  27. package/.yarn/cache/space-separated-tokens-npm-1.1.5-2352c83473-8ef68f1cfa.zip +0 -0
  28. package/.yarn/cache/unist-util-find-after-npm-4.0.0-11b3b7fb4f-8381ef0bad.zip +0 -0
  29. package/.yarn/cache/zwitch-npm-1.0.5-5911cef6ce-28a1bebaca.zip +0 -0
  30. package/.yarn/install-state.gz +0 -0
  31. package/package.json +8 -5
  32. package/playground/{App.res → PlaygroundApp.res} +14 -7
  33. package/playground/PlaygroundComponents.res +109 -0
  34. package/playground/PlaygroundLocales.res +1 -0
  35. package/playground/PlaygroundRouter.res +23 -0
  36. package/playground/{CodeBlock.res → Playground_CodeBlock.res} +12 -16
  37. package/playground/{stories/IntroductionColors.stories.mdx → design/DesignSystem_Colors.mdx} +0 -0
  38. package/playground/{stories/IntroductionFonts.stories.mdx → design/DesignSystem_Fonts.mdx} +0 -0
  39. package/playground/{stories/IntroductionMediaQueries.stories.mdx → design/DesignSystem_MediaQueries.mdx} +0 -0
  40. package/playground/design/Playground_DesignSystem.res +12 -0
  41. package/playground/{stories/TailwindConfigBreakpoints.js → design/TailwindConfigBreakpoints.jsx} +1 -1
  42. package/playground/{stories/TailwindConfigColorsPreview.js → design/TailwindConfigColorsPreview.jsx} +1 -1
  43. package/playground/{stories/TailwindConfigFontsPreview.js → design/TailwindConfigFontsPreview.jsx} +1 -1
  44. package/playground/docs/ApiDecoding.mdx +70 -0
  45. package/playground/docs/Form.mdx +109 -0
  46. package/playground/docs/Identifiers.mdx +38 -0
  47. package/playground/{Doc.res → docs/Playground_Docs.res} +8 -8
  48. package/playground/docs/Primitives.mdx +53 -0
  49. package/playground/docs/Request.mdx +281 -0
  50. package/playground/docs/Router.mdx +43 -0
  51. package/playground/docs/Setup.mdx +58 -0
  52. package/playground/docs/Unleash.mdx +53 -0
  53. package/playground/main.jsx +1 -1
  54. package/src/intl/Toolkit__Intl.res +5 -9
  55. package/src/intl/Toolkit__Intl.resi +1 -0
  56. package/src/logger/Toolkit__BrowserLogger.res +15 -15
  57. package/src/tailwind/tailwind.config.cjs +3 -5
  58. package/vite.config.js +43 -1
  59. package/.yarn/cache/cosmiconfig-npm-7.0.0-b9d0d7d156-6801feaa02.zip +0 -0
  60. package/.yarn/cache/import-fresh-npm-3.3.0-3e34265ca9-2cacfad06e.zip +0 -0
  61. package/.yarn/cache/klona-npm-2.0.4-6bc4e7cd86-abc6690882.zip +0 -0
  62. package/.yarn/cache/postcss-loader-npm-4.2.0-f01fec2503-c45ec1ca1b.zip +0 -0
  63. package/.yarn/cache/semver-npm-7.3.4-4c3baf0ead-96451bfd7c.zip +0 -0
  64. package/playground/Playground_Component.res +0 -33
  65. package/playground/Playground_ComponentDetails.res +0 -25
  66. package/playground/Playground_ComponentsList.res +0 -43
@@ -1,32 +1,32 @@
1
1
  module ApiDecoding = {
2
- @module("../../../docs/ApiDecoding.mdx") @react.component
2
+ @module("../../../../playground/docs/ApiDecoding.mdx") @react.component
3
3
  external make: unit => React.element = "default"
4
4
  }
5
5
  module Form = {
6
- @module("../../../docs/Form.mdx") @react.component
6
+ @module("../../../../playground/docs/Form.mdx") @react.component
7
7
  external make: unit => React.element = "default"
8
8
  }
9
9
  module Identifiers = {
10
- @module("../../../docs/Identifiers.mdx") @react.component
10
+ @module("../../../../playground/docs/Identifiers.mdx") @react.component
11
11
  external make: unit => React.element = "default"
12
12
  }
13
13
  module Primitives = {
14
- @module("../../../docs/Primitives.mdx") @react.component
14
+ @module("../../../../playground/docs/Primitives.mdx") @react.component
15
15
  external make: unit => React.element = "default"
16
16
  }
17
17
  module Requests = {
18
- @module("../../../docs/Request.mdx") @react.component
18
+ @module("../../../../playground/docs/Request.mdx") @react.component
19
19
  external make: unit => React.element = "default"
20
20
  }
21
21
  module Setup = {
22
- @module("../../../docs/Setup.mdx") @react.component
22
+ @module("../../../../playground/docs/Setup.mdx") @react.component
23
23
  external make: unit => React.element = "default"
24
24
  }
25
25
  module Router = {
26
- @module("../../../docs/Router.mdx") @react.component
26
+ @module("../../../../playground/docs/Router.mdx") @react.component
27
27
  external make: unit => React.element = "default"
28
28
  }
29
29
  module Unleash = {
30
- @module("../../../docs/Unleash.mdx") @react.component
30
+ @module("../../../../playground/docs/Unleash.mdx") @react.component
31
31
  external make: unit => React.element = "default"
32
32
  }
@@ -0,0 +1,53 @@
1
+ # Primitives
2
+
3
+ Utililties functions for primitives types :
4
+
5
+ - `option`
6
+ - `string`
7
+ - `array`
8
+
9
+ ## Option
10
+
11
+ ### string
12
+
13
+ - `fromString` : `string => option(string)`
14
+ - `toString` : `option(string) => string`
15
+
16
+ ```rescript
17
+ let anEmptyString = "";
18
+
19
+ Toolkit.Primitives.Option.fromString(anEmptyString)
20
+ ->Option.map(v => v ++ "test");
21
+
22
+ Toolkit.Primitives.Option.toString(Some("test")); // "test"
23
+ Toolkit.Primitives.Option.toString(None); // ""
24
+ ```
25
+
26
+ ### boolean
27
+
28
+ - `fromBool` : `bool => option(bool)`
29
+
30
+ ```rescript
31
+ Toolkit.Primitives.Option.fromBool(true); // Some(true)
32
+ Toolkit.Primitives.Option.fromBool(false); // None
33
+ ```
34
+
35
+ ## Array
36
+
37
+ ```rescript
38
+ let variable = ["abc", "dce", ""];
39
+
40
+ Js.log(Primitives.Array.joinNonEmpty(anEmptyString)); // "abc, dce"
41
+ Js.log(Primitives.Array.joinNonEmpty(~separator="+", anEmptyString)); // "abc+dce"
42
+ Js.log(variable->Primitives.Array.tail); // ""
43
+ ```
44
+
45
+ ## Result
46
+
47
+ ```rescript
48
+ let result = Ok("test");
49
+ let test = Error("error");
50
+
51
+ Js.log(Primitives.Result.get(result)); // Some("test")
52
+ Js.log(Primitives.Result.get(test)); // None
53
+ ```
@@ -0,0 +1,281 @@
1
+ # How to manage an API request
2
+
3
+ ## 1. Create the request config
4
+
5
+ You have to declare 3 types :
6
+
7
+ - `argument` is what you give to the function
8
+ - `response` is what your API answer
9
+ - `error` is the potential custom errors that can occur (⚠️ this has to be handled manually)
10
+
11
+ And the `exec` method.
12
+
13
+ We use [decco](https://github.com/reasonml-labs/decco) to serialize / deserialize the data.
14
+
15
+ ```rescript
16
+ let request = Axios.Instance.create(
17
+ Axios.makeConfig(~baseURL=envState.apiUrl,()),
18
+ );
19
+
20
+ module FetchUsers = {
21
+ module Config = {
22
+ type argument = unit;
23
+
24
+ @decco
25
+ type response = array<user>
26
+ @decco
27
+ and user = {
28
+ name: string
29
+ };
30
+
31
+ type error = string;
32
+
33
+ let exec = () => {
34
+ request->Request.get("/", response_decode);
35
+ };
36
+ };
37
+ module Request = Toolkit.Request.Make(Config);
38
+ };
39
+
40
+ FetchUsers.Request.exec();
41
+ ```
42
+
43
+ ### 1.2 Send data
44
+
45
+ We create a decodable `body` type that we give to the `argument` type.
46
+ This decodable `body` will be used in the exec method.
47
+
48
+ ```rescript
49
+ module UpdateUser = {
50
+ module Config = {
51
+ type argument = body
52
+ @decco
53
+ and body = {
54
+ name: string,
55
+ };
56
+
57
+ @decco
58
+ type response = unit;
59
+
60
+ type error = unit;
61
+
62
+ let exec = body => {
63
+ request->Request.postData("/update-user", response_decode, body->body_encode);
64
+ };
65
+ };
66
+ module Request = Toolkit_Request.Make(Config);
67
+ };
68
+
69
+ UpdateUser.Request.exec({ name: "test" })
70
+ ```
71
+
72
+ ### 1.3 Handle errors
73
+
74
+ In order to handle special errors comming from the API, you can use the `mapError` parameter.
75
+
76
+ This parameter requires a callback which contains the **response** as argument and needs to return this type :
77
+
78
+ ```rescript
79
+ option<result<'data, error<'a>>>
80
+ ```
81
+
82
+ The `result` is useful for some cases when an API error should not break the flow so you can handle the specific error and just return `Ok()`.
83
+
84
+ #### Request error type
85
+
86
+ ```rescript
87
+ type undecodedResponse = {
88
+ data: undecodedData,
89
+ headers,
90
+ config,
91
+ status: int,
92
+ };
93
+
94
+ type noResponse = {
95
+ message: string,
96
+ config,
97
+ };
98
+
99
+ // We get this type in mapError callback argument
100
+ type failedResponse = {
101
+ message: string,
102
+ config,
103
+ response,
104
+ }
105
+ and response = {
106
+ data: failedResponseData,
107
+ headers,
108
+ status: int,
109
+ };
110
+
111
+ type error<'a> = [
112
+ | #noResponse(noResponse)
113
+ | #invalidResponse(failedResponse)
114
+ | #invalidResponseData(undecodedResponse, string)
115
+ | #invalidErrorData
116
+ | #unknown(Js.Promise.error)
117
+ | #custom('a)
118
+ ]
119
+ ```
120
+
121
+ ```rescript
122
+ let exec = token => {
123
+ request->Request.get(
124
+ "/test",
125
+ ~mapError=
126
+ error => {
127
+ // have to return option(Toolkit.Request.error('a'))
128
+ },
129
+ response_decode,
130
+ );
131
+ };
132
+ ```
133
+
134
+ `failedResponseData` can be anything depending on the API behavior. So you have to use `Obj.magic` to cast and use the correct field.
135
+
136
+ ```rescript
137
+ let handleError = (error: failedResponse) => {
138
+ // the API return an object { code: string }
139
+ let code = error.response.data->Obj.magic##code;
140
+
141
+ // If code can be undefined
142
+ code
143
+ ->Option.map(code => {
144
+ switch (code) {
145
+ | "some_code" => Error(#custom("message"))
146
+ | "other_code" => Error(#invalidErrorData)
147
+ | "its_ok" => Ok()
148
+ | _ => Error(#custom("unknown"))
149
+ }
150
+ })
151
+ };
152
+ ```
153
+
154
+ Often, we use decco in order to handle complex error (error with data). We create a custom Decoder for this kind of case
155
+
156
+ ```rescript
157
+ module UpdateUser = {
158
+ module Config = {
159
+ type argument = body
160
+ @decco
161
+ and body = {name: string};
162
+
163
+ @decco
164
+ type response = unit;
165
+
166
+ module Error =
167
+ Decoders.Enum({
168
+ @deriving(jsConverter)
169
+ type enum = [
170
+ | #"unknown-user"
171
+ | #invalidData
172
+ | #unknownError
173
+ ];
174
+ });
175
+
176
+ @decco
177
+ type error = Error.t;
178
+
179
+ let exec = body => {
180
+ request->Request.postData(
181
+ "/update-user",
182
+ response_decode,
183
+ body->body_encode,
184
+ ~mapError=
185
+ ({response}) => {
186
+ switch (response.data->Obj.magic->error_decode) {
187
+ | Ok(error) => Some(Error(`custom(error)))
188
+ | Error(err) =>
189
+ Js.log(err);
190
+ Some(Error(`custom(`unknownError)));
191
+ }
192
+ }
193
+ );
194
+ };
195
+ };
196
+ module Request = Toolkit_Request.Make(Config);
197
+ };
198
+
199
+ UpdateUser.Request.exec({ name: "test" })
200
+ ->Promise.tapError(err => {
201
+ switch (err) {
202
+ | #custom(#"unknown-user") => Js.log("user not found")
203
+ | #custom(#unknownError) => Js.log("alert sentry")
204
+ | _ => Js.log("generic handler")
205
+ }
206
+ })
207
+ ```
208
+
209
+ ## 2. Use request in React
210
+
211
+ ### 2.1 Fetching data with swr
212
+
213
+ There are several ways to manage a request in React, we chose to use [swr](https://swr.vercel.app/) with [react-suspense](https://reactjs.org/docs/concurrent-mode-suspense.html) enabled.
214
+ We have a functor to generate automaticatly a swr fetcher based on the request created before :
215
+
216
+ ```rescript
217
+ module GetUsers = {
218
+ module Config = {
219
+ type argument = unit;
220
+
221
+ @decco
222
+ type response = array<user>
223
+ @decco
224
+ and user = {
225
+ name: string
226
+ };
227
+
228
+ type error = string;
229
+
230
+ let exec = () => {
231
+ request->Request.get("/users", response_decode);
232
+ };
233
+ };
234
+ module Request = Toolkit.Request.Make();
235
+ };
236
+
237
+
238
+ module GetUsersFetcher =
239
+ Fetcher.Make({
240
+ module Request = GetUsers.Request;
241
+ let key = () => [|
242
+ "GetUsers",
243
+ |];
244
+ });
245
+ ```
246
+
247
+ Later in the react app
248
+
249
+ ```rescript
250
+ module PageUsers = {
251
+ [@react.component]
252
+ let make = () => {
253
+ let (users, _, _) = GetUsersFetcher.use();
254
+
255
+ <div>
256
+ {
257
+ users
258
+ ->Belt.Array.mapWithIndex((i, user) => {
259
+ <div key={i->Belt.Int.toString}>
260
+ {user.name->React.String}
261
+ </div>
262
+ })
263
+ }
264
+ </div>
265
+ };
266
+ };
267
+
268
+ [@react.component]
269
+ let make = () => {
270
+ <ErrorBoundary>
271
+ <React.Suspense fallback={<Spinner />}>
272
+ <PageUsers />
273
+ </React.Suspense>
274
+ </ErrorBoundary>
275
+ };
276
+ ```
277
+
278
+ There are 2 functions generated by the fetcher functor :
279
+
280
+ - `use` can be used when the API will always return something
281
+ - `useOptional` return an `option<'a>` so it's used when the API can return nothing
@@ -0,0 +1,43 @@
1
+ # Router
2
+
3
+ Type-safe navigation
4
+
5
+ ## Usage
6
+
7
+ ```rescript
8
+ open Toolkit
9
+
10
+ module StoreId = Identifiers.MakeString()
11
+
12
+ module RouterConfig = {
13
+ type admin = Home
14
+
15
+ type t =
16
+ | Home
17
+ | StoreDetails(StoreId.t)
18
+ | Admin(admin)
19
+ | NotFound
20
+
21
+ let make = url =>
22
+ switch url.path {
23
+ | list{} => Home
24
+ | list{"stores", storeId} => StoreDetails(StoreId.make(storeId))
25
+ | list{"admin", ...rest} =>
26
+ switch rest {
27
+ | list{} => Admin(Home)
28
+ | _ => NotFound
29
+ }
30
+ | _ => NotFound
31
+ }
32
+
33
+ let toString = route =>
34
+ switch route {
35
+ | Home => ""
36
+ | StoreDetails(storeId) => "/stores/" ++ storeId->StoreId.toString
37
+ | Admin(Home) => "/admin/"
38
+ | NotFound => "/404"
39
+ }
40
+ }
41
+
42
+ module Navigation = Router.Make(RouterConfig)
43
+ ```
@@ -0,0 +1,58 @@
1
+ # ReScript toolkit
2
+
3
+ ## Setup
4
+
5
+ Install the package :
6
+
7
+ ```bash
8
+ npm i -S @colisweb/rescript-toolkit
9
+ ```
10
+
11
+ Add the package to the `bsconfig.json` file :
12
+
13
+ ```json
14
+ {
15
+ "bs-dependencies": ["@colisweb/rescript-toolkit"]
16
+ }
17
+ ```
18
+
19
+ Import the style in your app :
20
+
21
+ ```js
22
+ // App.js
23
+ import "@colisweb/rescript-toolkit/src/ui/styles.css";
24
+ ```
25
+
26
+ ### Add Tailwind
27
+
28
+ This toolkit is based on [tailwindcss](https://tailwindcss.com/).
29
+ We share a postcss config that you can include to your webpack config
30
+
31
+ ## Usage
32
+
33
+ The bindings in the _vendors_ are **globaly accessible**. Everything else is scoped into the `Toolkit` namespace.
34
+
35
+ ```rescript
36
+ open Toolkit;
37
+
38
+ @react.component
39
+ let make = () => {
40
+ let dialog = Hooks.useDisclosure();
41
+
42
+ <div className=Tw.(style([bgWhite])) />
43
+ };
44
+ ```
45
+
46
+ ### Local development
47
+
48
+ Run bsb
49
+
50
+ ```bash
51
+ npm run dev
52
+ ```
53
+
54
+ Run storybook
55
+
56
+ ```bash
57
+ npm run storybook
58
+ ```
@@ -0,0 +1,53 @@
1
+ # Unleash
2
+
3
+ [Unleash](https://github.com/Unleash/unleash) is feature flipping solution. It allows us to activate or restrain fonctionalities acording a configuration.
4
+
5
+ ## Usage
6
+
7
+ ### 1. Create a rule
8
+
9
+ We use a functor to enforce several parameters :
10
+
11
+ | Params | value |
12
+ | ----------- | :--------------------------------------------: |
13
+ | parameters | 'parameters |
14
+ | input | 'input |
15
+ | output | 'output |
16
+ | envUrl | string |
17
+ | featureName | string |
18
+ | exec | ('input, Unleash.config(parameters)) => output |
19
+
20
+ ```rescript
21
+ module OutdatedApplicationConfig = {
22
+ @decco
23
+ type parameters = {version: string}
24
+ type input = unit
25
+ type output = bool
26
+ let envUrl = Env.unleashUrl
27
+ let featureName = "minimum-supported-version"
28
+
29
+ let exec = (_, config: Unleash.config<parameters>) => {
30
+ let appVersion =
31
+ ReactNativeVersionNumber.appVersion->Js.Nullable.toOption->Option.getWithDefault("")
32
+
33
+ config.strategies
34
+ ->Array.get(0)
35
+ ->Option.mapWithDefault(false, strategy =>
36
+ config.enabled ? Semver.lt(appVersion, strategy.parameters.version) : false
37
+ )
38
+ }
39
+ }
40
+
41
+ module OutdatedApplication = Toolkit.Unleash.MakeFeature(OutdatedApplicationConfig)
42
+ ```
43
+
44
+ ### 2. Use the rule
45
+
46
+ ```rescript
47
+ OutdatedApplication.exec()
48
+ ->Promise.tapOk(outdated => {
49
+ if (outdated) {
50
+ Js.log("app outdated");
51
+ }
52
+ })
53
+ ```
@@ -3,7 +3,7 @@ import ReactDOM from "react-dom/client";
3
3
  import "../src/ui/styles.css";
4
4
  import "../src/ui/Toolkit__Ui_DatetimeInput.css";
5
5
  import "./custom.css";
6
- import App from "../lib/es6_global/playground/App.bs";
6
+ import App from "../lib/es6_global/playground/PlaygroundApp.bs";
7
7
 
8
8
  const root = ReactDOM.createRoot(document.getElementById("root"));
9
9
 
@@ -31,16 +31,11 @@ let availableLanguagesFromString = v =>
31
31
  | _ => #fr
32
32
  }
33
33
 
34
- let createIntl = (locale: availableLanguages, messages) => {
34
+ let createIntl = (~onError=?, locale: availableLanguages, messages) => {
35
35
  let cache = createIntlCache()
36
36
 
37
37
  createIntl(
38
- intlConfig(
39
- ~locale=locale->availableLanguagesToString,
40
- ~messages,
41
- ~onError=message => Toolkit__BrowserLogger.error2("create intl error", message),
42
- (),
43
- ),
38
+ intlConfig(~locale=locale->availableLanguagesToString, ~messages, ~onError?, ()),
44
39
  cache,
45
40
  )
46
41
  }
@@ -48,6 +43,7 @@ let createIntl = (locale: availableLanguages, messages) => {
48
43
  module type IntlConfig = {
49
44
  let messages: messages
50
45
  let defaultLocale: option<availableLanguages>
46
+ let onError: string => unit
51
47
  }
52
48
 
53
49
  module Make = (Config: IntlConfig) => {
@@ -67,10 +63,10 @@ module Make = (Config: IntlConfig) => {
67
63
 
68
64
  type action = SetLocale(availableLanguages)
69
65
 
70
- let store = Restorative.createStore({locale: locale, intl: intl}, (_state, action) =>
66
+ let store = Restorative.createStore({locale, intl}, (_state, action) =>
71
67
  switch action {
72
68
  | SetLocale(locale) => {
73
- locale: locale,
69
+ locale,
74
70
  intl: {
75
71
  let messages = switch locale {
76
72
  | #fr => Config.messages.fr->toDict
@@ -14,6 +14,7 @@ let availableLanguagesFromString: string => availableLanguages
14
14
  module type IntlConfig = {
15
15
  let messages: messages
16
16
  let defaultLocale: option<availableLanguages>
17
+ let onError: string => unit
17
18
  }
18
19
 
19
20
  module Make: (Config: IntlConfig) =>
@@ -51,22 +51,22 @@ let warning3 = (str, str2, str3) => {
51
51
  }
52
52
 
53
53
  let error = (str: string) => {
54
- if nodeEnv !== "production" {
55
- Js.Console.log3("%cERROR", errorStyle, str)
56
- } else {
57
- DatadogRum.Browser.addError(makeError(str))
58
- }
54
+ DatadogRum.Browser.addError(makeError(str))
55
+ // if nodeEnv !== "production" {
56
+ // Js.Console.log3("%cERROR", errorStyle, str)
57
+ // } else {
58
+ // }
59
59
  }
60
60
 
61
61
  let error2 = (str, str2) => {
62
- if nodeEnv !== "production" {
63
- Js.Console.log4("%cERROR", errorStyle, str, str2)
64
- } else {
65
- DatadogRum.Browser.addErrorWithContext(
66
- makeError(str),
67
- {
68
- "cause": str2,
69
- },
70
- )
71
- }
62
+ DatadogRum.Browser.addErrorWithContext(
63
+ makeError(str),
64
+ {
65
+ "cause": str2,
66
+ },
67
+ )
68
+ // if nodeEnv !== "production" {
69
+ // Js.Console.log4("%cERROR", errorStyle, str, str2)
70
+ // } else {
71
+ // }
72
72
  }
@@ -1,5 +1,3 @@
1
- const defaultColors = require("tailwindcss/colors");
2
-
3
1
  module.exports = {
4
2
  theme: {
5
3
  extend: {
@@ -65,9 +63,9 @@ module.exports = {
65
63
  screen: "100vh",
66
64
  },
67
65
  colors: {
68
- white: defaultColors.white,
69
- black: defaultColors.black,
70
- transparent: defaultColors.transparent,
66
+ white: "#fff",
67
+ black: "#000",
68
+ transparent: "transparent",
71
69
  routeWithdraw: "#176693",
72
70
  gray: {
73
71
  100: "#f7fafc",