Browse Source

Merge branch 'addTaskScreen' into 'master'

Add task screen

See merge request jetup/rws/rws-appication!40
merge-requests/41/merge
Coder 3 years ago
parent
commit
89fa854349
  1. BIN
      android/app/src/main/assets/fonts/fontello.ttf
  2. BIN
      src/assets/fonts/fontello.ttf
  3. 14
      src/config/fontello.json
  4. 2
      src/modules/root/index.tsx
  5. 4
      src/modules/tasks/atoms/add-task-row.atom.tsx
  6. 169
      src/modules/tasks/components/create-task-info.component.tsx
  7. 1
      src/modules/tasks/config/index.ts
  8. 26
      src/modules/tasks/config/selected-task-executors.mock.ts
  9. 104
      src/modules/tasks/screens/add-task.screen.tsx
  10. 22
      src/modules/tasks/smart-components/select-task-executor-list.smart-component.tsx
  11. 19
      src/modules/users/components/selected-user-list.component.tsx
  12. 3
      src/shared/components/elements/index.ts
  13. 30
      src/shared/components/elements/picker.component.tsx
  14. 44
      src/shared/components/forms/form-select.component.tsx
  15. 6
      src/shared/components/headers/primary-header.component.tsx
  16. 1
      src/shared/components/layouts/screen-layout.component.tsx

BIN
android/app/src/main/assets/fonts/fontello.ttf

Binary file not shown.

BIN
src/assets/fonts/fontello.ttf

Binary file not shown.

14
src/config/fontello.json

@ -678,6 +678,20 @@ @@ -678,6 +678,20 @@
"vectorstart"
]
},
{
"uid": "5ea1da031a5eef7a623dd0cfcbf2c193",
"css": "add-file",
"code": 59441,
"src": "custom_icons",
"selected": true,
"svg": {
"path": "M40.5 55.3C57.1 38.7 79.5 29.4 102.9 29.4H397.1C416.1 29.4 434.7 35.6 450 47.1L602.9 161.8H1073.5C1096.9 161.8 1119.4 171.1 1135.9 187.6 1152.5 204.2 1161.8 226.6 1161.8 250V872.5C1161.8 894.7 1153 915.8 1137.4 931.5 1121.7 947.1 1100.5 955.9 1078.4 955.9H102.9C79.5 955.9 57.1 946.6 40.5 930 24 913.5 14.7 891 14.7 867.6V117.6C14.7 94.2 24 71.8 40.5 55.3ZM397.1 117.6L102.9 117.6 102.9 867.6H1073.5V250H602.9C583.8 250 565.3 243.8 550 232.4L397.1 117.6ZM411.8 558.8C411.8 534.5 431.5 514.7 455.9 514.7H544.1V426.5C544.1 402.1 563.9 382.4 588.2 382.4 612.6 382.4 632.4 402.1 632.4 426.5V514.7H720.6C745 514.7 764.7 534.5 764.7 558.8 764.7 583.2 745 602.9 720.6 602.9H632.4V691.2C632.4 715.5 612.6 735.3 588.2 735.3 563.9 735.3 544.1 715.5 544.1 691.2V602.9H455.9C431.5 602.9 411.8 583.2 411.8 558.8Z",
"width": 1176
},
"search": [
"unionfile"
]
},
{
"uid": "5341b344eb9e77ffc9d1edcc2e5ad646",
"css": "magnifyingglasssearch",

2
src/modules/root/index.tsx

@ -37,7 +37,7 @@ export const Navigation = () => { @@ -37,7 +37,7 @@ export const Navigation = () => {
}
const navigation = React.useMemo(() => {
return modules[1]
return modules[activeModule]
}, [activeModule])
return (

4
src/modules/tasks/atoms/add-task-row.atom.tsx

@ -6,19 +6,21 @@ import { TouchableOpacity } from 'react-native-gesture-handler' @@ -6,19 +6,21 @@ import { TouchableOpacity } from 'react-native-gesture-handler'
interface IProps {
title: string
rightComponent: { text?: string; icon?: string }
onPress: () => void
borderBottom?: boolean
}
export const AddTaskRow: FC<IProps> = ({
title,
rightComponent,
onPress,
borderBottom = true,
}) => {
return (
<View style={[styles.container, borderBottom && styles.borderBottom]}>
<Txt style={styles.title}>{title}</Txt>
<TouchableOpacity>
<TouchableOpacity onPress={onPress}>
{rightComponent?.text ? (
<Txt style={styles.text}>{rightComponent.text}</Txt>
) : (

169
src/modules/tasks/components/create-task-info.component.tsx

@ -1,102 +1,103 @@ @@ -1,102 +1,103 @@
import { $size, getTheme } from "@/shared"
import { FakeDateInputForm, FormTextarea, LargeFormControlWithIcon } from "@/shared/components/forms"
import React from "react"
import { View, Text, StyleSheet } from "react-native"
import { $size, getTheme } from '@/shared'
import {
FakeDateInputForm,
FormTextarea,
LargeFormControlWithIcon,
} from '@/shared/components/forms'
import React from 'react'
import { View, Text, StyleSheet, ViewStyle } from 'react-native'
interface IPropsDateOptions {
value: Date
onPress: () => void
value: Date
onPress: () => void
}
interface IPropsInputOption {
name: string
value: string
error?: string
onChange: (name: string, val: string) => void
name: string
value: string
error?: string
onChange: (name: string, val: string) => void
}
interface IProps {
startDate: IPropsDateOptions
endDate: IPropsDateOptions
title: IPropsInputOption
description: IPropsInputOption
initName: string
startDate: IPropsDateOptions
endDate: IPropsDateOptions
title: IPropsInputOption
description: IPropsInputOption
initName: string
style?: ViewStyle
}
export const CreateTaskInfoComponent = (props: IProps) => {
return (
<View style={styles.wrapper}>
return (
<View style={[styles.wrapper, props.style]}>
<View style={styles.datePairWrapper}>
<FakeDateInputForm
value={props.endDate.value}
onPress={() => props.endDate.onPress()}
title={'Кінець'}
smallSize
/>
<View style={styles.datePairWrapper}>
<FakeDateInputForm
value={props.endDate.value}
onPress={() => props.endDate.onPress()}
title={'Кінець'}
smallSize />
<FakeDateInputForm
value={props.startDate.value}
onPress={() => props.startDate.onPress()}
title={'Початок'}
smallSize
/>
</View>
<FakeDateInputForm
value={props.startDate.value}
onPress={() => props.startDate.onPress()}
title={'Початок'}
smallSize />
</View>
<LargeFormControlWithIcon
name="title"
value={props.title.value}
placeHolder="Назва"
error={props.title.error}
onChange={val => props.title.onChange(props.title.name, val)}
title={<Text style={styles.inputLabel}>Назва</Text>}
/>
<LargeFormControlWithIcon
name='title'
value={props.title.value}
placeHolder='Назва'
error={props.title.error}
onChange={(val) => props.title.onChange(props.title.name, val)}
title={
<Text style={styles.inputLabel}>Назва</Text>
}
/>
<FormTextarea
name="description"
label="Опис"
value={props.description.value}
error={props.description.error}
placeholder="Опис"
onChange={props.description.onChange}
/>
<FormTextarea
name='description'
label='Опис'
value={props.description.value}
error={props.description.error}
placeholder='Опис'
onChange={props.description.onChange}
/>
<View style={styles.initWrapper}>
<Text style={styles.initTitle}>Ініціатор</Text>
<Text style={styles.initName}>{props.initName}</Text>
</View>
</View>
)
<View style={styles.initWrapper}>
<Text style={styles.initTitle}>Ініціатор</Text>
<Text style={styles.initName}>{props.initName}</Text>
</View>
</View>
)
}
const styles = StyleSheet.create({
wrapper: {
marginHorizontal: $size(20),
},
datePairWrapper: {
flexDirection: 'row',
justifyContent: 'space-between',
marginBottom: -$size(20),
},
inputLabel: {
color: getTheme().$secondaryText,
fontSize: $size(12),
marginBottom: -10,
fontWeight: '300'
},
initWrapper: {
flexDirection: 'row',
justifyContent: 'space-between',
marginTop: $size(10)
},
initTitle: {
fontSize: $size(16, 14),
color: getTheme().$secondaryText,
fontWeight: '300'
},
initName: {
fontSize: $size(16, 14),
fontWeight: '300'
}
})
wrapper: {},
datePairWrapper: {
flexDirection: 'row',
justifyContent: 'space-between',
marginBottom: -$size(20),
},
inputLabel: {
color: getTheme().$secondaryText,
fontSize: $size(12),
marginBottom: -10,
fontWeight: '300',
},
initWrapper: {
flexDirection: 'row',
justifyContent: 'space-between',
marginTop: $size(10),
},
initTitle: {
fontSize: $size(16, 14),
color: getTheme().$secondaryText,
fontWeight: '300',
},
initName: {
fontSize: $size(16, 14),
fontWeight: '300',
},
})

1
src/modules/tasks/config/index.ts

@ -1,2 +1,3 @@ @@ -1,2 +1,3 @@
export * from './task-card-icons.config'
export * from './task-card-buttons.config'
export * from './selected-task-executors.mock'

26
src/modules/tasks/config/selected-task-executors.mock.ts

@ -0,0 +1,26 @@ @@ -0,0 +1,26 @@
export const selectedTaskExecutorData = [
{
id: 1,
userName: 'User',
},
{
id: 1,
userName: 'User',
},
{
id: 1,
userName: 'User',
},
{
id: 1,
userName: 'User',
},
{
id: 1,
userName: 'User',
},
{
id: 1,
userName: 'User',
},
]

104
src/modules/tasks/screens/add-task.screen.tsx

@ -1,31 +1,103 @@ @@ -1,31 +1,103 @@
import { SelectedUserList } from '@/modules/users/components/selected-user-list.component'
import { ScreenLayout } from '@/shared'
import {
$size,
Button,
getTheme,
PickerComponent,
ScreenLayout,
Txt,
} from '@/shared'
import { FromSelect } from '@/shared/components/forms'
import React, { FC } from 'react'
import { StyleSheet } from 'react-native'
import { StyleSheet, View } from 'react-native'
import { AddTaskRow } from '../atoms'
import { CreateTaskInfoComponent } from '../components'
import { SelectTaskExecutorListSmart } from '../smart-components/select-task-executor-list.smart-component'
export const AddTaskScreen: FC = () => {
return (
<ScreenLayout header={{ title: 'Нова задача' }}>
<ScreenLayout
needScroll
header={{ title: 'Нова задача', style: styles.header }}>
<>
<AddTaskRow
title={'Ініціатор'}
rightComponent={{ text: 'Арем Осядлий' }}
<CreateTaskInfoComponent
style={styles.createTaskInfo}
startDate={{ value: new Date(), onPress: () => {} }}
endDate={{ value: new Date(), onPress: () => {} }}
title={{
name: 'title',
value: 'Title',
onChange: (name, val) => {},
}}
description={{
name: 'description',
value: 'Description',
onChange: (name, val) => {},
}}
initName={'User'}
/>
<SelectTaskExecutorListSmart />
<AddTaskRow
title={'Ініціатор'}
rightComponent={{ icon: 'plus-2' }}
onPress={() => {}}
title={'Група'}
rightComponent={{ text: 'Група' }}
/>
<SelectedUserList
data={[{ id: 1, userName: 'User' }]}
onPressRemove={id =>
console.log(`Delete user from list with id: ${id}`)
}
/>
<View>
<Txt style={styles.blockTitle}>Підстава</Txt>
<FromSelect
title="Оберіть зі списку"
icon={{ name: 'caretleft-2-1', size: $size(23, 21) }}
style={{ marginBottom: $size(10, 8) }}
modal={{
title: 'Оберіть зі списку',
height: $size(250, 330),
children: (
<PickerComponent
data={[]}
onChange={val => {}}
/>
),
}}
/>
<FromSelect
title="Додайте нову"
icon={{ name: 'add-file', size: $size(23, 21) }}
style={{ marginBottom: $size(20, 18) }}
modal={{
title: 'Додайте нову',
height: $size(250, 330),
children: <></>,
}}
/>
<Button
title="Створити"
type="primary"
style={{ marginBottom: $size(40, 35) }}
onPress={() => {}}
/>
</View>
</>
</ScreenLayout>
)
}
const styles = StyleSheet.create({})
const styles = StyleSheet.create({
header: {
marginBottom: $size(20, 18),
},
createTaskInfo: {
paddingBottom: $size(15, 13),
borderBottomWidth: 1,
borderBottomColor: getTheme().$border,
},
blockTitle: {
fontSize: $size(16, 14),
color: getTheme().$secondaryText,
marginVertical: $size(15, 13),
},
})

22
src/modules/tasks/smart-components/select-task-executor-list.smart-component.tsx

@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
import { SelectedUserList } from '@/modules/users/components/selected-user-list.component'
import React, { FC } from 'react'
import { AddTaskRow } from '../atoms'
import { selectedTaskExecutorData } from '../config'
export const SelectTaskExecutorListSmart: FC = () => {
return (
<>
<AddTaskRow
title={'Виконавець'}
rightComponent={{ icon: 'plus-1' }}
onPress={() => {}}
/>
<SelectedUserList
onPressRemove={() => {}}
needScroll={false}
data={selectedTaskExecutorData}
/>
</>
)
}

19
src/modules/users/components/selected-user-list.component.tsx

@ -1,20 +1,29 @@ @@ -1,20 +1,29 @@
import { $size, getTheme, IconComponent } from '@/shared'
import React, { FC, useCallback, useMemo } from 'react'
import { FlatList, StyleSheet, TouchableOpacity } from 'react-native'
import React, { FC, useMemo } from 'react'
import { StyleSheet, TouchableOpacity, View, ViewStyle } from 'react-native'
import { ScrollView } from 'react-native-gesture-handler'
import { UserRowCard } from './user-row-card.component'
interface IProps {
data: any[]
needScroll?: boolean
onPressRemove: (id: number) => void
style?: ViewStyle
}
export const SelectedUserList: FC<IProps> = ({ data, onPressRemove }) => {
export const SelectedUserList: FC<IProps> = ({
data,
needScroll = true,
style,
onPressRemove,
}) => {
const Wrapper = needScroll ? ScrollView : View
const itemToRender = useMemo(
() =>
data.map(item => (
<UserRowCard
imageUri={item.imageUri}
imageUri={item?.imageUri}
userName={item.userName}
rightComponent={() => (
<TouchableOpacity
@ -32,7 +41,7 @@ export const SelectedUserList: FC<IProps> = ({ data, onPressRemove }) => { @@ -32,7 +41,7 @@ export const SelectedUserList: FC<IProps> = ({ data, onPressRemove }) => {
[data],
)
return <ScrollView>{itemToRender}</ScrollView>
return <Wrapper style={style}>{itemToRender}</Wrapper>
}
const styles = StyleSheet.create({

3
src/shared/components/elements/index.ts

@ -2,4 +2,5 @@ export * from './txt.component' @@ -2,4 +2,5 @@ export * from './txt.component'
export * from './icon.component'
export * from './image.component'
export * from './checkbox.component'
export * from './avatar.component'
export * from './avatar.component'
export * from './picker.component'

30
src/shared/components/elements/picker.component.tsx

@ -0,0 +1,30 @@ @@ -0,0 +1,30 @@
import { $size } from '@/shared'
import { Picker } from '@react-native-picker/picker'
import React, { FC, useMemo } from 'react'
import { ViewStyle } from 'react-native'
type DataType = {
label: string
value: string
}[]
interface IProps {
data: DataType
onChange: (val: string) => void
style?: ViewStyle
}
export const PickerComponent: FC<IProps> = ({ data, onChange, style }) => {
const pickerItems = useMemo(
() => data?.map(item => <Picker.Item {...item} />),
[data],
)
return (
<Picker
style={{ width: $size(250, 230), ...style }}
onValueChange={(itemValue: string) => onChange(itemValue)}>
{pickerItems}
</Picker>
)
}

44
src/shared/components/forms/form-select.component.tsx

@ -1,39 +1,25 @@ @@ -1,39 +1,25 @@
import { $size, BottomModal, getTheme, IconComponent, Txt } from '@/shared'
import { Picker } from '@react-native-picker/picker'
import React, { FC, useMemo } from 'react'
import React, { FC, ReactElement, useMemo } from 'react'
import { StyleSheet, View, ViewStyle } from 'react-native'
import { TouchableOpacity } from 'react-native-gesture-handler'
import RBSheet from 'react-native-raw-bottom-sheet'
type DataType = {
label: string
value: string
interface IModal {
title: string
height: number
children: ReactElement
}
interface IProps {
title: string
modalTitle: string
iconName: string
onChange: (value: string) => void
data: DataType[]
modal: IModal
icon: { name: string; size: number }
style?: ViewStyle
}
export const FromSelect: FC<IProps> = ({
title,
modalTitle,
iconName,
onChange,
data,
style,
}) => {
export const FromSelect: FC<IProps> = ({ title, modal, icon, style }) => {
const sheetRef = React.useRef<RBSheet>(null)
const pickerItems = useMemo(
() => data?.map(item => <Picker.Item {...item} />),
[data],
)
return (
<>
<View style={[styles.container, style]}>
@ -43,8 +29,8 @@ export const FromSelect: FC<IProps> = ({ @@ -43,8 +29,8 @@ export const FromSelect: FC<IProps> = ({
style={styles.iconWrap}
onPress={() => sheetRef.current.open()}>
<IconComponent
name={iconName}
size={$size(23, 21)}
name={icon.name}
size={icon.size}
color={getTheme().formSelect.$icon}
/>
</TouchableOpacity>
@ -52,13 +38,9 @@ export const FromSelect: FC<IProps> = ({ @@ -52,13 +38,9 @@ export const FromSelect: FC<IProps> = ({
<BottomModal
sheetRef={ref => (sheetRef.current = ref)}
height={$size(320, 300)}
title={modalTitle}>
<Picker
style={{ width: $size(250, 230) }}
onValueChange={(itemValue: string) => onChange(itemValue)}>
{pickerItems}
</Picker>
height={modal.height}
title={modal.title}>
{modal.children}
</BottomModal>
</>
)

6
src/shared/components/headers/primary-header.component.tsx

@ -1,22 +1,24 @@ @@ -1,22 +1,24 @@
import { $size, isAndroid } from '@/shared/helpers'
import { getTheme } from '@/shared/themes'
import React, { FC, ReactElement } from 'react'
import { StyleSheet, TouchableOpacity, View } from 'react-native'
import { StyleSheet, TouchableOpacity, View, ViewStyle } from 'react-native'
import { IconComponent, Txt } from '../elements'
interface IProps {
title: string
style?: ViewStyle
goBack?: () => void
rightComponents?: () => ReactElement | ReactElement[]
}
export const PrimaryHeader: FC<IProps> = ({
title = 'Title',
style,
goBack,
rightComponents,
}) => {
return (
<View style={styles.container}>
<View style={[styles.container, style]}>
<View style={styles.goBack}>
{goBack && (
<TouchableOpacity onPress={goBack}>

1
src/shared/components/layouts/screen-layout.component.tsx

@ -15,6 +15,7 @@ interface ScreenLayoutProps { @@ -15,6 +15,7 @@ interface ScreenLayoutProps {
withOutKeyboardSpacer?: boolean
header?: {
title: string
style?: ViewStyle
goBack?: () => void
rightComponents?: () => ReactElement | ReactElement[]
}

Loading…
Cancel
Save