@tactics/toddle-styleguide 1.5.0 → 1.6.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 (29) hide show
  1. package/App.tsx +13 -5
  2. package/index.d.ts +4 -1
  3. package/index.tsx +7 -1
  4. package/package.json +2 -1
  5. package/src/components/molecules/bare-time-picker/bare-time-picker.component.d.ts +9 -0
  6. package/src/components/molecules/bare-time-picker/bare-time-picker.component.tsx +80 -0
  7. package/src/components/molecules/bare-time-picker/bare-time-picker.preview.d.ts +2 -0
  8. package/src/components/molecules/bare-time-picker/bare-time-picker.preview.tsx +86 -0
  9. package/src/components/molecules/bare-time-picker/bare-time-picker.styles.d.ts +8 -0
  10. package/src/components/molecules/bare-time-picker/bare-time-picker.styles.js +12 -0
  11. package/src/components/organisms/timetable-edit/timetable-edit.component.d.ts +5 -1
  12. package/src/components/organisms/timetable-edit/timetable-edit.component.tsx +20 -19
  13. package/src/components/organisms/timetable-edit/timetable-edit.preview.tsx +13 -3
  14. package/src/components/organisms/timetable-editor/components/timetable-edit-wrapper.d.ts +12 -0
  15. package/src/components/organisms/timetable-editor/components/timetable-edit-wrapper.tsx +63 -0
  16. package/src/components/organisms/timetable-editor/timetable-editor.component.d.ts +8 -0
  17. package/src/components/organisms/timetable-editor/timetable-editor.component.tsx +71 -0
  18. package/src/components/organisms/timetable-editor/timetable-editor.preview.d.ts +2 -0
  19. package/src/components/organisms/timetable-editor/timetable-editor.preview.tsx +53 -0
  20. package/src/components/organisms/timetable-editor/timetable-editor.styles.d.ts +8 -0
  21. package/src/components/organisms/timetable-editor/timetable-editor.styles.js +12 -0
  22. package/src/components/templates/modal/modal.component.tsx +1 -1
  23. package/src/components/templates/popover/components/modal/modal.component.tsx +1 -1
  24. package/src/models/time-slot-record.d.ts +14 -0
  25. package/src/models/time-slot-record.ts +33 -0
  26. package/src/models/time-slot-sequence.d.ts +15 -0
  27. package/src/models/time-slot-sequence.ts +76 -0
  28. package/src/types/timetable-edit.enum.d.ts +2 -1
  29. package/src/types/timetable-edit.enum.ts +1 -0
package/App.tsx CHANGED
@@ -73,10 +73,11 @@ import {QuickMessagePreview} from './src/components/atoms/quick-message/quick-me
73
73
  import {TabViewPreview} from './src/components/organisms/tab-view/tab-view.preview';
74
74
  import {LinePreview} from './src/components/atoms/line/line.preview';
75
75
  import {JournalEntryPreview} from './src/components/organisms/journal-entry/journal-entry.preview';
76
- import { TimetableEditPreview } from './src/components/organisms/timetable-edit/timetable-edit.preview';
77
76
  import { ContextLabelPreview } from './src/components/molecules/context-label/context-label.preview';
78
77
  import { CountPreview } from './src/components/atoms/count/count.preview';
79
78
  import { AmountPreview } from './src/components/molecules/amount/amount.preview';
79
+ import { BareTimePickerPreview } from './src/components/molecules/bare-time-picker/bare-time-picker.preview';
80
+ import { TimetableEditorPreview } from './src/components/organisms/timetable-editor/timetable-editor.preview';
80
81
 
81
82
  import {
82
83
  SafeAreaProvider,
@@ -287,13 +288,17 @@ const HomeScreen = ({navigation}: {navigation: any}) => {
287
288
  title="Time Picker"
288
289
  onPress={() => navigation.push('time-picker')}
289
290
  />
291
+ <ReactBtn
292
+ title="Bare Time Picker"
293
+ onPress={() => navigation.push('bare-time-picker')}
294
+ />
290
295
  <ReactBtn
291
296
  title="Time Tracker"
292
297
  onPress={() => navigation.push('time-tracker')}
293
298
  />
294
299
  <ReactBtn
295
- title="Timetable Edit"
296
- onPress={() => navigation.push('timetable-edit')}
300
+ title="Timetable Editor"
301
+ onPress={() => navigation.push('timetable-editor')}
297
302
  />
298
303
  <ReactBtn title="Timeline" onPress={() => navigation.push('timeline')} />
299
304
  <ReactBtn
@@ -485,11 +490,14 @@ function App() {
485
490
  <Stack.Screen name="time-picker">
486
491
  {() => <TimePickerPreview />}
487
492
  </Stack.Screen>
493
+ <Stack.Screen name="bare-time-picker">
494
+ {() => <BareTimePickerPreview />}
495
+ </Stack.Screen>
488
496
  <Stack.Screen name="time-tracker">
489
497
  {() => <TimeTrackerPreview />}
490
498
  </Stack.Screen>
491
- <Stack.Screen name="timetable-edit">
492
- {() => <TimetableEditPreview />}
499
+ <Stack.Screen name="timetable-editor">
500
+ {() => <TimetableEditorPreview />}
493
501
  </Stack.Screen>
494
502
  <Stack.Screen name="timeline">
495
503
  {() => <TimeLinePreview />}
package/index.d.ts CHANGED
@@ -62,13 +62,16 @@ import { TimetableEdit } from './src/components/organisms/timetable-edit/timetab
62
62
  import { ContextLabel } from './src/components/molecules/context-label/context-label.component';
63
63
  import { Count } from './src/components/atoms/count/count.component';
64
64
  import { Amount } from './src/components/molecules/amount/amount.component';
65
+ import { TimetableEditor } from './src/components/organisms/timetable-editor/timetable-editor.component';
65
66
  import { BubbleAlignment } from './src/types/bubble-alignment.enum';
66
67
  import { KeyBoardTypes } from './src/types/keyboard-types.enum';
67
68
  import { Size } from './src/types/size.enum';
68
69
  import { VisualState } from './src/types/visual-state.enum';
69
70
  import { Initials } from './src/models/initials.model';
71
+ import { TimeSlotRecord } from './src/models/time-slot-record';
72
+ import { TimeSlotSequence } from './src/models/time-slot-sequence';
70
73
  import { ToddleDateTime } from './src/utilities/toddle-datetime/toddle-datetime.class';
71
74
  import { ThemeCtx } from './src/context/theme.context';
72
75
  import { Scale } from './src/theme/scale/index';
73
76
  import CreateResponsiveStyle from './src/theme/responsive/index';
74
- export { AllCapsHeading, Avatar, BackgroundGradient, BlockedMessage, Button, Calendar, CalendarSelect, CancelLink, Check, Checkbox, ChildListItem, ContactItem, ContactRole, DateInput, DaySelect, DefaultSelect, DepartmentLogo, FilterRange, FilterTab, Footer, Heading1, Heading2, Heading3, Heading4, Icon, ImageBubble, IncrementInput, Info, JournalEntry, LanguageButton, Line, LoadingIndicator, Logo, MessageInput, Modal, MoreInfoButton, MyChildListItem, Paragraph, PasswordInput, PersonInfoCard, Pill, Popover, PopOverAction, PressableIcon, QuickFilter, QuickMessage, Search, SelectLink, SelectListItem, SelectPicker, SmallText, Snackbar, SplitContainer, Swipe, TabView, Tag, TextBubble, TextInput, TimeLine, TimePicker, TimeTracker, TinyText, WaveBackground, WideButton, BubbleAlignment, Initials, KeyBoardTypes, Size, ThemeCtx, ToddleDateTime, VisualState, CreateResponsiveStyle, Scale, TimetableEdit, ContextLabel, Count, Amount };
77
+ export { AllCapsHeading, Avatar, BackgroundGradient, BlockedMessage, Button, Calendar, CalendarSelect, CancelLink, Check, Checkbox, ChildListItem, ContactItem, ContactRole, DateInput, DaySelect, DefaultSelect, DepartmentLogo, FilterRange, FilterTab, Footer, Heading1, Heading2, Heading3, Heading4, Icon, ImageBubble, IncrementInput, Info, JournalEntry, LanguageButton, Line, LoadingIndicator, Logo, MessageInput, Modal, MoreInfoButton, MyChildListItem, Paragraph, PasswordInput, PersonInfoCard, Pill, Popover, PopOverAction, PressableIcon, QuickFilter, QuickMessage, Search, SelectLink, SelectListItem, SelectPicker, SmallText, Snackbar, SplitContainer, Swipe, TabView, Tag, TextBubble, TextInput, TimeLine, TimePicker, TimeTracker, TinyText, WaveBackground, WideButton, BubbleAlignment, Initials, KeyBoardTypes, Size, ThemeCtx, ToddleDateTime, VisualState, CreateResponsiveStyle, Scale, TimetableEdit, ContextLabel, Count, Amount, TimetableEditor, TimeSlotRecord, TimeSlotSequence };
package/index.tsx CHANGED
@@ -80,6 +80,7 @@ import {TimetableEdit} from './src/components/organisms/timetable-edit/timetable
80
80
  import { ContextLabel } from './src/components/molecules/context-label/context-label.component';
81
81
  import { Count } from './src/components/atoms/count/count.component';
82
82
  import { Amount } from './src/components/molecules/amount/amount.component';
83
+ import { TimetableEditor } from './src/components/organisms/timetable-editor/timetable-editor.component';
83
84
 
84
85
  // Exports of enums
85
86
  import {BubbleAlignment} from './src/types/bubble-alignment.enum';
@@ -89,6 +90,8 @@ import {VisualState} from './src/types/visual-state.enum';
89
90
 
90
91
  // Exports of models
91
92
  import {Initials} from './src/models/initials.model';
93
+ import { TimeSlotRecord } from './src/models/time-slot-record';
94
+ import { TimeSlotSequence } from './src/models/time-slot-sequence';
92
95
 
93
96
  // Exports of classes
94
97
  import {ToddleDateTime} from './src/utilities/toddle-datetime/toddle-datetime.class';
@@ -179,5 +182,8 @@ export {
179
182
  TimetableEdit,
180
183
  ContextLabel,
181
184
  Count,
182
- Amount
185
+ Amount,
186
+ TimetableEditor,
187
+ TimeSlotRecord,
188
+ TimeSlotSequence
183
189
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tactics/toddle-styleguide",
3
- "version": "1.5.0",
3
+ "version": "1.6.1",
4
4
  "main": "index.tsx",
5
5
  "types": "index.d.ts",
6
6
  "prepublish": "tsc",
@@ -57,6 +57,7 @@
57
57
  "react-native-swipe-gestures": "^1.0.5",
58
58
  "react-native-web": "~0.19.6",
59
59
  "react-native-wheel-picker-expo": "^0.5.4",
60
+ "react-native-wheely": "^0.6.0",
60
61
  "react-test-renderer": "^18.2.0"
61
62
  },
62
63
  "devDependencies": {
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ interface BareTimePickerProps {
3
+ initialHours: string;
4
+ initialMinutes: string;
5
+ onChangeHours: (value: string) => void;
6
+ onChangeMinutes: (value: string) => void;
7
+ }
8
+ export declare const BareTimePicker: ({ initialHours, initialMinutes, onChangeHours, onChangeMinutes, }: BareTimePickerProps) => React.JSX.Element;
9
+ export {};
@@ -0,0 +1,80 @@
1
+ import { useContext } from "react";
2
+ import { ThemeCtx } from "../../../context/theme.context";
3
+ import { Stylesheet } from "./bare-time-picker.styles";
4
+ import { View } from "react-native";
5
+ import React from "react";
6
+ import WheelPicker from 'react-native-wheely';
7
+ import { Scale } from "../../../theme/scale";
8
+
9
+
10
+ interface BareTimePickerProps {
11
+ initialHours: string;
12
+ initialMinutes: string;
13
+ onChangeHours: (value: string) => void;
14
+ onChangeMinutes: (value: string) => void;
15
+ }
16
+
17
+ const HOURS: string[] = [
18
+ '',
19
+ ...Array.from({length: 24}, (_, i) => i.toString().padStart(2, '0')),
20
+ ];
21
+ const MINUTES: string[] = [
22
+ '',
23
+ ...Array.from({length: 60}, (_, i) => i.toString().padStart(2, '0')),
24
+ ];
25
+
26
+
27
+ export const BareTimePicker = ({
28
+ initialHours,
29
+ initialMinutes,
30
+ onChangeHours,
31
+ onChangeMinutes,
32
+ }: BareTimePickerProps) => {
33
+ const context = useContext(ThemeCtx);
34
+ const styles = Stylesheet(context);
35
+
36
+ const initialIndexHandler = (dataArray: string[], value: string): number => {
37
+ return dataArray.findIndex((element) => element === value);
38
+ };
39
+
40
+ return (
41
+ <View style={styles.rootContainer}>
42
+ <WheelPicker
43
+ options={HOURS.map((value) => (value == '' ? '--' : value))}
44
+ onChange={(index) => onChangeHours(HOURS[index])}
45
+ selectedIndex={initialIndexHandler(HOURS, initialHours)}
46
+ visibleRest={1}
47
+ selectedIndicatorStyle={{
48
+ borderRadius: 0,
49
+ backgroundColor: context.colors.main[9],
50
+ }}
51
+ containerStyle={{
52
+ backgroundColor: context.colors.ui.xlightgrey,
53
+ width: '50%',
54
+ borderTopLeftRadius:Scale.xxs,
55
+ borderBottomLeftRadius:Scale.xxs,
56
+ }}
57
+ itemTextStyle={{fontSize: Scale.l}}
58
+ scaleFunction={(x) => x/1.5}
59
+ />
60
+ <WheelPicker
61
+ options={MINUTES.map((value) => (value == '' ? '--' : value))}
62
+ onChange={(index) => onChangeMinutes(MINUTES[index])}
63
+ selectedIndex={initialIndexHandler(MINUTES, initialMinutes)}
64
+ visibleRest={1}
65
+ selectedIndicatorStyle={{
66
+ borderRadius: 0,
67
+ backgroundColor: context.colors.main[9]
68
+ }}
69
+ containerStyle={{
70
+ backgroundColor: context.colors.ui.xlightgrey,
71
+ width: '50%',
72
+ borderTopRightRadius:Scale.xxs,
73
+ borderBottomRightRadius:Scale.xxs,
74
+ }}
75
+ itemTextStyle={{fontSize: Scale.l}}
76
+ scaleFunction={(x) => x/1.5}
77
+ />
78
+ </View>
79
+ )
80
+ }
@@ -0,0 +1,2 @@
1
+ import React from 'react';
2
+ export declare const BareTimePickerPreview: ({}: {}) => React.JSX.Element;
@@ -0,0 +1,86 @@
1
+ import React, {useState} from 'react';
2
+ import {View} from 'react-native';
3
+ import {Heading3} from '../../atoms/heading-components';
4
+ import {Button} from '../button/button.component';
5
+ import {Avatar} from '../avatar/avatar.component';
6
+ import {Initials} from '../../../models/initials.model';
7
+ import {Size} from '../../../types/size.enum';
8
+ import {Modal} from '../../templates/modal/modal.component';
9
+ import { BareTimePicker } from './bare-time-picker.component';
10
+
11
+ export const BareTimePickerPreview = ({}: {}) => {
12
+ const [popoverIsVisible, setPopoverIsVisible] = useState(false);
13
+
14
+ const [checkInHours, setCheckInHours] = useState('09');
15
+ const [checkInMinutes, setCheckInMinutes] = useState('06');
16
+
17
+ console.log(`
18
+ Check In:
19
+ Hours: ${checkInHours}
20
+ Minutes: ${checkInMinutes}
21
+ `);
22
+
23
+ return (
24
+ <View
25
+ style={{
26
+ width: '100%',
27
+ height: '100%',
28
+ zIndex: 10000,
29
+ }}
30
+ >
31
+ <View
32
+ style={{
33
+ marginTop: 150,
34
+ }}
35
+ >
36
+ <Button
37
+ onPress={() => setPopoverIsVisible(true)}
38
+ label="Open popover"
39
+ />
40
+ </View>
41
+ <Modal
42
+ title={'Zeno Driesennnnnnnnnnnnnnnnn'}
43
+ subtitle={'Registratie aanpassen'}
44
+ onClose={() => setPopoverIsVisible(false)}
45
+ isVisible={popoverIsVisible}
46
+ >
47
+ <View>
48
+ <View style={{alignItems: 'center', marginBottom: 16}}>
49
+ <Avatar
50
+ source={Initials.for('Zeno', 'Driesen')}
51
+ size={Size.LARGE}
52
+ />
53
+ </View>
54
+ <View
55
+ style={{
56
+ flexDirection: 'column',
57
+ gap: 26,
58
+ }}
59
+ >
60
+ <View style={{alignItems: 'center'}}>
61
+ <Heading3
62
+ bold={true}
63
+ textAlign={'center'}
64
+ addStyle={{marginBottom: 8}}
65
+ >
66
+ Check In
67
+ </Heading3>
68
+ <BareTimePicker
69
+ initialHours={checkInHours}
70
+ initialMinutes={checkInMinutes}
71
+ onChangeHours={setCheckInHours}
72
+ onChangeMinutes={setCheckInMinutes}
73
+ />
74
+ </View>
75
+ </View>
76
+ <View style={{marginTop: 32, marginBottom: 16, alignItems: 'center'}}>
77
+ <Button
78
+ label={'Bewaar'}
79
+ onPress={() => console.log('Bewaar registratie aanpassing')}
80
+ />
81
+ </View>
82
+ </View>
83
+ </Modal>
84
+ </View>
85
+ );
86
+ };
@@ -0,0 +1,8 @@
1
+ export function Stylesheet(context: any): {
2
+ rootContainer: {
3
+ flexDirection: "row";
4
+ alignItems: "center";
5
+ width: "100%";
6
+ maxWidth: number;
7
+ };
8
+ };
@@ -0,0 +1,12 @@
1
+ import {StyleSheet} from 'react-native';
2
+ import {Scale} from '../../../theme/scale/index';
3
+
4
+ export const Stylesheet = (context) =>
5
+ StyleSheet.create({
6
+ rootContainer: {
7
+ flexDirection: 'row',
8
+ alignItems: 'center',
9
+ width: '100%',
10
+ maxWidth: 200
11
+ },
12
+ });
@@ -1,5 +1,7 @@
1
1
  import React from 'react';
2
+ import { TimetableEditState } from '../../../types/timetable-edit.enum';
2
3
  interface TimetableEditProps {
4
+ index: number;
3
5
  initialInHours: string;
4
6
  initialInMinutes: string;
5
7
  initialOutHours: string;
@@ -8,6 +10,8 @@ interface TimetableEditProps {
8
10
  onChangeInMinutes: (value: string) => void;
9
11
  onChangeOutHours: (value: string) => void;
10
12
  onChangeOutMinutes: (value: string) => void;
13
+ onPressTag: (val: TimetableEditState, index: number) => void;
14
+ initialEditState: string;
11
15
  }
12
- export declare const TimetableEdit: ({ initialInHours, initialInMinutes, initialOutHours, initialOutMinutes, onChangeInHours, onChangeInMinutes, onChangeOutHours, onChangeOutMinutes, }: TimetableEditProps) => React.JSX.Element;
16
+ export declare const TimetableEdit: ({ index, initialInHours, initialInMinutes, initialOutHours, initialOutMinutes, onChangeInHours, onChangeInMinutes, onChangeOutHours, onChangeOutMinutes, initialEditState, onPressTag }: TimetableEditProps) => React.JSX.Element;
13
17
  export {};
@@ -1,14 +1,15 @@
1
1
  import {View} from 'react-native';
2
2
  import {Heading3} from '../../atoms/heading-components';
3
- import {useContext, useState} from 'react';
3
+ import {useContext} from 'react';
4
4
  import {ThemeCtx} from '../../../context/theme.context';
5
5
  import React from 'react';
6
6
  import { Stylesheet } from './timetable-edit.styles';
7
7
  import { Tag } from '../../molecules/tag/tag.component';
8
8
  import { TimetableEditState } from '../../../types/timetable-edit.enum';
9
- import { TimePicker } from '../../molecules/time-picker/time-picker.component';
9
+ import { BareTimePicker } from '../../molecules/bare-time-picker/bare-time-picker.component';
10
10
 
11
11
  interface TimetableEditProps {
12
+ index: number;
12
13
  initialInHours: string;
13
14
  initialInMinutes: string;
14
15
  initialOutHours: string;
@@ -17,9 +18,12 @@ interface TimetableEditProps {
17
18
  onChangeInMinutes: (value: string) => void;
18
19
  onChangeOutHours: (value: string) => void;
19
20
  onChangeOutMinutes: (value: string) => void;
21
+ onPressTag: (val: TimetableEditState, index: number) => void
22
+ initialEditState: string
20
23
  }
21
24
 
22
25
  export const TimetableEdit = ({
26
+ index,
23
27
  initialInHours,
24
28
  initialInMinutes,
25
29
  initialOutHours,
@@ -28,18 +32,11 @@ export const TimetableEdit = ({
28
32
  onChangeInMinutes,
29
33
  onChangeOutHours,
30
34
  onChangeOutMinutes,
35
+ initialEditState,
36
+ onPressTag
31
37
  }: TimetableEditProps) => {
32
38
  const context = useContext(ThemeCtx);
33
39
  const styles = Stylesheet(context);
34
- const [editState, setEditState] = useState('');
35
-
36
- const updateEditState = (state: string) => {
37
- if (editState == state) {
38
- setEditState('')
39
- } else {
40
- setEditState(state);
41
- }
42
- }
43
40
 
44
41
  return (
45
42
  <View style={styles.rootContainer}>
@@ -52,8 +49,10 @@ export const TimetableEdit = ({
52
49
  <Tag
53
50
  value={TimetableEditState.IN}
54
51
  label={`${initialInHours == '' ? '--' : initialInHours}:${initialInMinutes == '' ? '--' : initialInMinutes}`}
55
- isSelected={editState == TimetableEditState.IN}
56
- onPress={updateEditState}
52
+ isSelected={initialEditState == TimetableEditState.IN}
53
+ onPress={() => {
54
+ onPressTag(TimetableEditState.IN, index)
55
+ }}
57
56
  />
58
57
  </View>
59
58
  <View style={styles.tagContainer}>
@@ -64,14 +63,16 @@ export const TimetableEdit = ({
64
63
  <Tag
65
64
  value={TimetableEditState.OUT}
66
65
  label={`${initialOutHours == '' ? '--' : initialOutHours}:${initialOutMinutes == '' ? '--' : initialOutMinutes}`}
67
- isSelected={editState == TimetableEditState.OUT}
68
- onPress={updateEditState}
66
+ isSelected={initialEditState == TimetableEditState.OUT}
67
+ onPress={() => {
68
+ onPressTag(TimetableEditState.OUT, index)
69
+ }}
69
70
  />
70
71
  </View>
71
72
  </View>
72
- {editState === TimetableEditState.IN &&
73
+ {initialEditState === TimetableEditState.IN &&
73
74
  <View style={styles.pickerContainer}>
74
- <TimePicker
75
+ <BareTimePicker
75
76
  initialHours={initialInHours}
76
77
  initialMinutes={initialInMinutes}
77
78
  onChangeHours={onChangeInHours}
@@ -79,9 +80,9 @@ export const TimetableEdit = ({
79
80
  />
80
81
  </View>
81
82
  }
82
- {editState === TimetableEditState.OUT &&
83
+ {initialEditState === TimetableEditState.OUT &&
83
84
  <View style={styles.pickerContainer}>
84
- <TimePicker
85
+ <BareTimePicker
85
86
  initialHours={initialOutHours}
86
87
  initialMinutes={initialOutMinutes}
87
88
  onChangeHours={onChangeOutHours}
@@ -3,15 +3,16 @@ import {View} from 'react-native';
3
3
  import {Modal} from '../../templates/modal/modal.component';
4
4
  import { Button } from '../../molecules/button/button.component';
5
5
  import { TimetableEdit } from './timetable-edit.component';
6
+ import { TimetableEditState } from '../../../types/timetable-edit.enum';
6
7
 
7
8
  export const TimetableEditPreview = ({}: {}) => {
8
9
  const [popoverIsVisible, setPopoverIsVisible] = useState(false);
9
-
10
10
  const [checkInHours, setCheckInHours] = useState('09');
11
11
  const [checkInMinutes, setCheckInMinutes] = useState('06');
12
12
 
13
13
  const [checkOutHours, setCheckOutHours] = useState('');
14
14
  const [checkOutMinutes, setCheckOutMinutes] = useState('');
15
+ const [editState, setEditState] = useState(TimetableEditState.NONE);
15
16
 
16
17
  console.log(`
17
18
  Check In:
@@ -37,7 +38,10 @@ export const TimetableEditPreview = ({}: {}) => {
37
38
  }}
38
39
  >
39
40
  <Button
40
- onPress={() => setPopoverIsVisible(true)}
41
+ onPress={() => {
42
+ setEditState(TimetableEditState.NONE);
43
+ setPopoverIsVisible(true)
44
+ }}
41
45
  label="Open popover"
42
46
  />
43
47
  </View>
@@ -49,6 +53,7 @@ export const TimetableEditPreview = ({}: {}) => {
49
53
  >
50
54
  <View>
51
55
  <TimetableEdit
56
+ index={1}
52
57
  initialInHours={checkInHours}
53
58
  initialInMinutes={checkInMinutes}
54
59
  initialOutHours={checkOutHours}
@@ -57,12 +62,17 @@ export const TimetableEditPreview = ({}: {}) => {
57
62
  onChangeInMinutes={setCheckInMinutes}
58
63
  onChangeOutHours={setCheckOutHours}
59
64
  onChangeOutMinutes={setCheckOutMinutes}
65
+ initialEditState={editState}
66
+ onPressTag={(val, index) => {setEditState(val)}}
60
67
  />
61
68
 
62
69
  <View style={{marginTop: 32, marginBottom: 16, alignItems: 'center'}}>
63
70
  <Button
64
71
  label={'Bewaar'}
65
- onPress={() => console.log('Bewaar registratie aanpassing')}
72
+ onPress={() => {
73
+ setEditState(TimetableEditState.NONE);
74
+ console.log('Bewaar registratie aanpassing')
75
+ }}
66
76
  />
67
77
  </View>
68
78
  </View>
@@ -0,0 +1,12 @@
1
+ import { TimeSlotRecord } from "../../../../models/time-slot-record";
2
+ import React from "react";
3
+ import { TimetableEditState } from "../../../../types/timetable-edit.enum";
4
+ interface TimetableEditWrapperProps {
5
+ index: number;
6
+ record: TimeSlotRecord;
7
+ onUpdate: (rec: TimeSlotRecord) => void;
8
+ onPressTag: (val: TimetableEditState, index: number) => void;
9
+ editState: TimetableEditState;
10
+ }
11
+ export declare const TimetableEditWrapper: ({ index, record, onUpdate, editState, onPressTag }: TimetableEditWrapperProps) => React.JSX.Element;
12
+ export {};
@@ -0,0 +1,63 @@
1
+ import { useState } from "react";
2
+ import { TimeSlotRecord } from "../../../../models/time-slot-record";
3
+ import { TimetableEdit } from "../../timetable-edit/timetable-edit.component";
4
+ import React from "react";
5
+ import { TimetableEditState } from "../../../../types/timetable-edit.enum";
6
+
7
+ interface TimetableEditWrapperProps {
8
+ index: number;
9
+ record: TimeSlotRecord;
10
+ onUpdate: (rec: TimeSlotRecord) => void;
11
+ onPressTag: (val: TimetableEditState, index: number) => void;
12
+ editState: TimetableEditState
13
+ }
14
+
15
+ export const TimetableEditWrapper = ({index, record, onUpdate, editState, onPressTag}: TimetableEditWrapperProps) => {
16
+ const [initialInhours, initialInMinutes] = record.start
17
+ ? record.start.split(':')
18
+ : ':'.split(':');
19
+ const [initialOuthours, initialOutMinutes] = record.end
20
+ ? record.end.split(':')
21
+ : ':'.split(':');
22
+ const [inHours, setInHours] = useState<string>(initialInhours);
23
+ const [inMinutes, setInMinutes] = useState<string>(initialInMinutes);
24
+ const [outHours, setOutHours] = useState<string>(initialOuthours);
25
+ const [outMinutes, setOutMinutes] = useState<string>(initialOutMinutes);
26
+
27
+ return (
28
+ <TimetableEdit
29
+ index={index}
30
+ initialEditState={editState}
31
+ initialInHours={inHours}
32
+ initialInMinutes={inMinutes}
33
+ initialOutHours={outHours}
34
+ initialOutMinutes={outMinutes}
35
+ onChangeInHours={(hour) => {
36
+ setInHours(hour);
37
+ const updatedInHour = `${hour}:${inMinutes}`;
38
+ record.start = updatedInHour === ':' ? '' : updatedInHour;
39
+ onUpdate(record);
40
+ }}
41
+ onChangeInMinutes={(minutes) => {
42
+ setInMinutes(minutes);
43
+ const updatedInMinutes = `${inHours}:${minutes}`;
44
+ record.start = updatedInMinutes === ':' ? '' : updatedInMinutes;
45
+ onUpdate(record);
46
+ }}
47
+ onChangeOutHours={(hour) => {
48
+ setOutHours(hour);
49
+ const updatedOutHour = `${hour}:${outMinutes}`;
50
+ record.end = updatedOutHour === ':' ? undefined : updatedOutHour;
51
+ onUpdate(record);
52
+ }}
53
+ onChangeOutMinutes={(minutes) => {
54
+ setOutMinutes(minutes);
55
+ const updatedOutMinutes = `${outHours}:${minutes}`;
56
+ record.end =
57
+ updatedOutMinutes === ':' ? undefined : updatedOutMinutes;
58
+ onUpdate(record);
59
+ }}
60
+ onPressTag={(val, index) => {onPressTag(val, index)}}
61
+ />
62
+ );
63
+ }
@@ -0,0 +1,8 @@
1
+ import React from "react";
2
+ import { TimeSlotSequence } from "../../../models/time-slot-sequence";
3
+ interface TimetableEditorProps {
4
+ sequence: TimeSlotSequence;
5
+ onChange: (seq: TimeSlotSequence) => void;
6
+ }
7
+ export declare const TimetableEditor: ({ sequence, onChange }: TimetableEditorProps) => React.JSX.Element;
8
+ export {};
@@ -0,0 +1,71 @@
1
+ import React, { useContext, useEffect, useState } from "react"
2
+ import { View } from "react-native";
3
+ import { TimeSlotRecord } from "../../../models/time-slot-record";
4
+ import { TimeSlotSequence } from "../../../models/time-slot-sequence";
5
+ import { TimetableEditWrapper } from "./components/timetable-edit-wrapper";
6
+ import { TimetableEditState } from "../../../types/timetable-edit.enum";
7
+ import { ThemeCtx } from "../../../context/theme.context";
8
+ import { Stylesheet } from "./timetable-editor.styles";
9
+
10
+ interface TimetableEditorProps {
11
+ sequence: TimeSlotSequence;
12
+ onChange: (seq: TimeSlotSequence) => void;
13
+ }
14
+
15
+ export const TimetableEditor = ({sequence, onChange}: TimetableEditorProps) => {
16
+ const context = useContext(ThemeCtx);
17
+ const styles = Stylesheet(context);
18
+ const [activeIndex, setActiveIndex] = useState(0);
19
+ const [activeEditState, setActiveEditState] = useState(TimetableEditState.NONE);
20
+ const [first, setFrist] = useState<TimeSlotRecord>(sequence.first);
21
+ const [second, setSecond] = useState<TimeSlotRecord>(sequence.second);
22
+ const [third, setThird] = useState<TimeSlotRecord>(sequence.third);
23
+ const [fourth, setFourth] = useState<TimeSlotRecord>(sequence.fourth);
24
+
25
+ useEffect(() => {
26
+ const newSeq = TimeSlotSequence.fromEmpty();
27
+ newSeq.first.start = first.start;
28
+ newSeq.first.end = first.end;
29
+ newSeq.second.start = second.start;
30
+ newSeq.second.end = second.end;
31
+ newSeq.third.start = third.start;
32
+ newSeq.third.end = third.end;
33
+ newSeq.fourth.start = fourth.start;
34
+ newSeq.fourth.end = fourth.end;
35
+
36
+ onChange(newSeq);
37
+ }, [first, second, third, fourth])
38
+
39
+ return (
40
+ <View style={styles.rootContainer}>
41
+ <TimetableEditWrapper
42
+ index={1}
43
+ record={first}
44
+ onUpdate={(seq) => {setFrist(TimeSlotRecord.fromRecord(seq))}}
45
+ editState={activeIndex === 1 ? activeEditState : TimetableEditState.NONE}
46
+ onPressTag={(val,index) => { setActiveIndex(index); setActiveEditState(val);}}
47
+ />
48
+ <TimetableEditWrapper
49
+ index={2}
50
+ record={second}
51
+ onUpdate={(seq) => {setSecond(TimeSlotRecord.fromRecord(seq))}}
52
+ editState={activeIndex === 2 ? activeEditState : TimetableEditState.NONE}
53
+ onPressTag={(val,index) => { setActiveIndex(index); setActiveEditState(val);}}
54
+ />
55
+ <TimetableEditWrapper
56
+ index={3}
57
+ record={third}
58
+ onUpdate={(seq) => {setThird(TimeSlotRecord.fromRecord(seq))}}
59
+ editState={activeIndex === 3 ? activeEditState : TimetableEditState.NONE}
60
+ onPressTag={(val,index) => { setActiveIndex(index); setActiveEditState(val);}}
61
+ />
62
+ <TimetableEditWrapper
63
+ index={4}
64
+ record={fourth}
65
+ onUpdate={(seq) => {setFourth(TimeSlotRecord.fromRecord(seq))}}
66
+ editState={activeIndex === 4 ? activeEditState : TimetableEditState.NONE}
67
+ onPressTag={(val,index) => { setActiveIndex(index); setActiveEditState(val);}}
68
+ />
69
+ </View>
70
+ );
71
+ }
@@ -0,0 +1,2 @@
1
+ import React from 'react';
2
+ export declare const TimetableEditorPreview: ({}: {}) => React.JSX.Element;
@@ -0,0 +1,53 @@
1
+ import React, {useState} from 'react';
2
+ import {View} from 'react-native';
3
+ import {Modal} from '../../templates/modal/modal.component';
4
+ import { Button } from '../../molecules/button/button.component';
5
+ import { TimetableEditor } from './timetable-editor.component';
6
+ import { TimeSlotSequence } from '../../../models/time-slot-sequence';
7
+
8
+ export const TimetableEditorPreview = ({}: {}) => {
9
+ const [popoverIsVisible, setPopoverIsVisible] = useState(false);
10
+ const [seq, setSeq] = useState(TimeSlotSequence.fromEmpty())
11
+
12
+ return (
13
+ <View
14
+ style={{
15
+ width: '100%',
16
+ height: '100%',
17
+ zIndex: 10000,
18
+ }}
19
+ >
20
+ <View
21
+ style={{
22
+ marginTop: 150,
23
+ }}
24
+ >
25
+ <Button
26
+ onPress={() => {
27
+ setPopoverIsVisible(true)
28
+ }}
29
+ label="Open popover"
30
+ />
31
+ </View>
32
+ <Modal
33
+ title={'Bewerken'}
34
+ subtitle={'17 Jan 2021'}
35
+ onClose={() => setPopoverIsVisible(false)}
36
+ isVisible={popoverIsVisible}
37
+ >
38
+ <View>
39
+ <TimetableEditor sequence={seq} onChange={(seq) => setSeq(seq)} />
40
+
41
+ <View style={{marginTop: 32, marginBottom: 16, alignItems: 'center'}}>
42
+ <Button
43
+ label={'Bewaar'}
44
+ onPress={() => {
45
+ console.log(seq)
46
+ }}
47
+ />
48
+ </View>
49
+ </View>
50
+ </Modal>
51
+ </View>
52
+ );
53
+ };
@@ -0,0 +1,8 @@
1
+ export function Stylesheet(context: any): {
2
+ rootContainer: {
3
+ flexDirection: "column";
4
+ gap: number;
5
+ justifyContent: "center";
6
+ alignItems: "center";
7
+ };
8
+ };
@@ -0,0 +1,12 @@
1
+ import {StyleSheet} from 'react-native';
2
+ import {Scale} from '../../../theme/scale/index';
3
+
4
+ export const Stylesheet = (context) =>
5
+ StyleSheet.create({
6
+ rootContainer: {
7
+ flexDirection: 'column',
8
+ gap: 16,
9
+ justifyContent: 'center',
10
+ alignItems: 'center'
11
+ }
12
+ });
@@ -30,7 +30,7 @@ export const Modal = ({
30
30
  return () => subscription?.remove();
31
31
  });
32
32
 
33
- const maxHeight = Math.round(windowHeight / 100) * 80;
33
+ const maxHeight = Math.round(windowHeight / 100) * 90;
34
34
 
35
35
  const styles = Stylesheet();
36
36
 
@@ -35,7 +35,7 @@ const Modal = ({
35
35
 
36
36
  const elementHeight = Math.round(elementSize.height);
37
37
 
38
- const maxHeight = Math.round(windowHeight / 100) * 80;
38
+ const maxHeight = Math.round(windowHeight / 100) * 90;
39
39
  const translateYStartingPoint = windowHeight;
40
40
 
41
41
  const saveHeight = elementHeight > maxHeight ? maxHeight : elementHeight;
@@ -0,0 +1,14 @@
1
+ export interface TimeSlotRecordJSON {
2
+ in: string;
3
+ out: string;
4
+ }
5
+ export declare class TimeSlotRecord {
6
+ start: string;
7
+ end?: string;
8
+ private constructor();
9
+ static fromJson(json: TimeSlotRecordJSON): TimeSlotRecord;
10
+ static fromEmpty(): TimeSlotRecord;
11
+ static fromRecord(seq: TimeSlotRecord): TimeSlotRecord;
12
+ isComplete(): boolean;
13
+ toJson(): TimeSlotRecordJSON;
14
+ }
@@ -0,0 +1,33 @@
1
+ export interface TimeSlotRecordJSON {
2
+ in: string;
3
+ out: string;
4
+ }
5
+
6
+ export class TimeSlotRecord {
7
+ private constructor(public start: string, public end?: string) {}
8
+
9
+ static fromJson(json: TimeSlotRecordJSON): TimeSlotRecord {
10
+ // add validation here if needed
11
+ return new TimeSlotRecord(json.in, json.out);
12
+ }
13
+
14
+ static fromEmpty(): TimeSlotRecord {
15
+ // add validation here if needed
16
+ return new TimeSlotRecord('', '');
17
+ }
18
+
19
+ static fromRecord(seq: TimeSlotRecord): TimeSlotRecord {
20
+ return new TimeSlotRecord(seq.start, seq.end);
21
+ }
22
+
23
+ isComplete(): boolean {
24
+ return this.start !== '' && this.end !== '';
25
+ }
26
+
27
+ toJson(): TimeSlotRecordJSON {
28
+ return {
29
+ in: this.start,
30
+ out: this.end ? this.end : '',
31
+ };
32
+ }
33
+ }
@@ -0,0 +1,15 @@
1
+ import { TimeSlotRecord, TimeSlotRecordJSON } from './time-slot-record';
2
+ export declare class TimeSlotSequence {
3
+ readonly first: TimeSlotRecord;
4
+ readonly second: TimeSlotRecord;
5
+ readonly third: TimeSlotRecord;
6
+ readonly fourth: TimeSlotRecord;
7
+ private constructor();
8
+ static fromAttendanceRecordArray(arr: TimeSlotRecord[]): TimeSlotSequence;
9
+ static fromTimeSlotRecordJSONArray(arr: TimeSlotRecordJSON[]): TimeSlotSequence;
10
+ static fromEmpty(): TimeSlotSequence;
11
+ asArray(): TimeSlotRecord[];
12
+ toJson(): TimeSlotRecord[];
13
+ addToNextSlot(checkInOutTime: string): void;
14
+ isComplete(): boolean;
15
+ }
@@ -0,0 +1,76 @@
1
+ import {TimeSlotRecord, TimeSlotRecordJSON} from './time-slot-record';
2
+
3
+ export class TimeSlotSequence {
4
+ private constructor(
5
+ public readonly first: TimeSlotRecord,
6
+ public readonly second: TimeSlotRecord,
7
+ public readonly third: TimeSlotRecord,
8
+ public readonly fourth: TimeSlotRecord
9
+ ) {}
10
+
11
+ static fromAttendanceRecordArray(arr: TimeSlotRecord[]): TimeSlotSequence {
12
+ return new TimeSlotSequence(
13
+ arr[0] ? arr[0] : TimeSlotRecord.fromEmpty(),
14
+ arr[1] ? arr[1] : TimeSlotRecord.fromEmpty(),
15
+ arr[2] ? arr[2] : TimeSlotRecord.fromEmpty(),
16
+ arr[3] ? arr[3] : TimeSlotRecord.fromEmpty()
17
+ );
18
+ }
19
+
20
+ static fromTimeSlotRecordJSONArray(
21
+ arr: TimeSlotRecordJSON[]
22
+ ): TimeSlotSequence {
23
+ return new TimeSlotSequence(
24
+ TimeSlotRecord.fromJson(arr[0]),
25
+ TimeSlotRecord.fromJson(arr[1]),
26
+ TimeSlotRecord.fromJson(arr[2]),
27
+ TimeSlotRecord.fromJson(arr[3])
28
+ );
29
+ }
30
+
31
+ static fromEmpty(): TimeSlotSequence {
32
+ return new TimeSlotSequence(
33
+ TimeSlotRecord.fromEmpty(),
34
+ TimeSlotRecord.fromEmpty(),
35
+ TimeSlotRecord.fromEmpty(),
36
+ TimeSlotRecord.fromEmpty()
37
+ );
38
+ }
39
+
40
+ asArray(): TimeSlotRecord[] {
41
+ return [this.first, this.second, this.third, this.fourth];
42
+ }
43
+
44
+ toJson(): TimeSlotRecord[] {
45
+ return [this.first, this.second, this.third, this.fourth];
46
+ }
47
+
48
+ addToNextSlot(checkInOutTime: string) {
49
+ if (this.first.start === '') {
50
+ this.first.start = checkInOutTime;
51
+ } else if (this.first.end === undefined || this.first.end === '') {
52
+ this.first.end = checkInOutTime;
53
+ } else if (this.second.start === '') {
54
+ this.second.start = checkInOutTime;
55
+ } else if (this.second.end === undefined || this.second.end === '') {
56
+ this.second.end = checkInOutTime;
57
+ } else if (this.third.start === '') {
58
+ this.third.start = checkInOutTime;
59
+ } else if (this.third.end === undefined || this.third.end === '') {
60
+ this.third.end = checkInOutTime;
61
+ } else if (this.fourth.start === '') {
62
+ this.fourth.start = checkInOutTime;
63
+ } else if (this.fourth.end === undefined || this.fourth.end === '') {
64
+ this.fourth.end = checkInOutTime;
65
+ }
66
+ }
67
+
68
+ isComplete(): boolean {
69
+ return (
70
+ this.first.isComplete() &&
71
+ this.second.isComplete() &&
72
+ this.third.isComplete() &&
73
+ this.fourth.isComplete()
74
+ );
75
+ }
76
+ }
@@ -1,4 +1,5 @@
1
1
  export declare enum TimetableEditState {
2
2
  IN = "IN",
3
- OUT = "OUT"
3
+ OUT = "OUT",
4
+ NONE = "NONE"
4
5
  }
@@ -1,4 +1,5 @@
1
1
  export enum TimetableEditState {
2
2
  IN = 'IN',
3
3
  OUT = 'OUT',
4
+ NONE = 'NONE',
4
5
  }