@autobusal/common 0.0.40 → 1.0.0

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 (77) hide show
  1. package/ApiDetails/ApiDetails.tsx +50 -0
  2. package/ApiDetails/Content.tsx +48 -0
  3. package/ApiDetails/Devpos.tsx +139 -0
  4. package/ApiDetails/services.ts +39 -0
  5. package/ApiDetails/types.ts +13 -0
  6. package/Autocomplete/Autocomplete.tsx +3 -3
  7. package/Avatar.tsx +28 -0
  8. package/{BackTo.tsx → Back/BackTo.tsx} +4 -3
  9. package/Back/BackWithTitle.tsx +30 -0
  10. package/Button/Button.tsx +4 -2
  11. package/Calendar/Calendar.tsx +2 -2
  12. package/{BrowseCompanyItem/BrowseCompanyItem.tsx → CompanyItem/CompanyItem.tsx} +2 -2
  13. package/ContactInfo/ContactInfo.tsx +40 -0
  14. package/ContactInfo/styles.ts +33 -0
  15. package/CookieNotification/CookieNotification.tsx +2 -2
  16. package/File/File.tsx +11 -7
  17. package/IpLogs/IpLogs.tsx +47 -0
  18. package/IpLogs/View.tsx +48 -0
  19. package/IpLogs/services.ts +27 -0
  20. package/IpLogs/styles.ts +10 -0
  21. package/Loading/Loading.tsx +25 -20
  22. package/Loading/Paragraph.tsx +62 -0
  23. package/Loading/styles.ts +34 -1
  24. package/Meta.tsx +1 -1
  25. package/Modal/Modal.tsx +1 -1
  26. package/Pagination/Pagination.tsx +2 -1
  27. package/Passengers/Passengers.tsx +6 -5
  28. package/Passengers/Persons.tsx +7 -7
  29. package/Passengers/{utilities/getText.ts → utilities.ts} +3 -5
  30. package/Password/Password.tsx +4 -3
  31. package/Password/styles.ts +1 -1
  32. package/Policy/services.ts +1 -3
  33. package/Report/Report.tsx +39 -0
  34. package/Report/Send.tsx +52 -0
  35. package/Report/services.ts +19 -0
  36. package/Report/styles.ts +31 -0
  37. package/Report/types.ts +3 -0
  38. package/RouteItem/styles.ts +0 -1
  39. package/Seats/ChooseSeat.tsx +3 -3
  40. package/Seats/Preview.tsx +3 -3
  41. package/Seats/styles.ts +1 -43
  42. package/Table/Actions/Actions.tsx +40 -0
  43. package/Table/Actions/Get.tsx +49 -0
  44. package/Table/Actions/Icon.tsx +54 -0
  45. package/Table/Actions/styles.ts +22 -0
  46. package/Table/Header/Header.tsx +46 -0
  47. package/Table/Header/Sort.tsx +33 -0
  48. package/Table/Header/styles.ts +48 -0
  49. package/Table/Paginate.tsx +34 -0
  50. package/Table/Row.tsx +22 -0
  51. package/Table/Rows/Loading.tsx +22 -0
  52. package/Table/Rows/NotFound.tsx +22 -0
  53. package/Table/Rows/Rows.tsx +63 -0
  54. package/Table/Rows/styles.ts +37 -0
  55. package/Table/Table.tsx +76 -0
  56. package/Table/Top/Search.tsx +36 -0
  57. package/Table/Top/Top.tsx +44 -0
  58. package/Table/Top/styles.ts +32 -0
  59. package/Table/browseUrl.ts +21 -0
  60. package/Table/styles.ts +28 -0
  61. package/Table/types.ts +11 -0
  62. package/Viewer/Actions.tsx +61 -53
  63. package/Viewer/Data.tsx +74 -8
  64. package/Viewer/Item.tsx +10 -81
  65. package/Viewer/Items/CheckboxList.tsx +53 -30
  66. package/Viewer/Items/DatePicker.tsx +70 -0
  67. package/Viewer/Items/Dropdown.tsx +14 -12
  68. package/Viewer/Items/Linked.tsx +27 -0
  69. package/Viewer/Items/TextareaHtml.tsx +51 -24
  70. package/Viewer/Items/styles.ts +73 -0
  71. package/Viewer/Viewer.tsx +24 -17
  72. package/Viewer/styles.ts +21 -1
  73. package/Viewer/types.ts +11 -8
  74. package/index.ts +30 -8
  75. package/package.json +1 -1
  76. package/Pagination/types.ts +0 -12
  77. /package/{BrowseCompanyItem → CompanyItem}/styles.ts +0 -0
@@ -0,0 +1,50 @@
1
+ import { useState } from 'react';
2
+ import { TFunction } from 'i18next';
3
+ import { IoKeySharp } from 'react-icons/io5';
4
+ import { Button, Modal } from '../index';
5
+ import Content from './Content';
6
+
7
+ interface Props {
8
+ id?: number
9
+ type: 'devpos'
10
+ t: TFunction<'common'>
11
+ }
12
+
13
+ const ApiDetails = ({ id, type, t }: Props): JSX.Element => {
14
+ const [ show, setShow ] = useState<boolean>(false);
15
+
16
+ if (id === undefined) {
17
+ return <>-</>;
18
+ }
19
+
20
+ return (
21
+ <>
22
+ <Button
23
+ type="button"
24
+ subtype="secondary"
25
+ size="small"
26
+ text={ (
27
+ <>
28
+ <IoKeySharp />
29
+ { t('api_details.manage', { ns: 'common' }) }
30
+ </>
31
+ ) }
32
+ noMargin
33
+ onClick={ () => setShow(true) }
34
+ />
35
+
36
+ { show && (
37
+ <Modal
38
+ width={ 700 }
39
+ title={ t('api_details.title', { ns: 'common', title: type.toUpperCase() }) }
40
+ content={
41
+ <Content id={ id } type={ type } t={ t } />
42
+ }
43
+ onClose={ () => setShow(false) }
44
+ />
45
+ ) }
46
+ </>
47
+ );
48
+ };
49
+
50
+ export default ApiDetails;
@@ -0,0 +1,48 @@
1
+ import { TFunction } from 'i18next';
2
+ import { Paragraph } from '../index';
3
+ import { success } from '@autobusal/utilities';
4
+ import DevPos from './Devpos';
5
+ import { DevPosForm } from './types';
6
+ import { GetSettings, PostSettings } from './services';
7
+
8
+ interface Props {
9
+ id: number
10
+ type: 'devpos'
11
+ t: TFunction<'common'>
12
+ }
13
+
14
+ const Content = ({ id, type, t }: Props): JSX.Element => {
15
+ const { data, isLoading } = GetSettings(id, type);
16
+
17
+ const { mutate: SaveSettings, isPending } = PostSettings(id, type);
18
+
19
+ if (isLoading) {
20
+ return <Paragraph count={ 3 } />;
21
+ }
22
+
23
+ if (typeof data === 'string') {
24
+ return (
25
+ <div>{ t('api_details.unavailable', { ns: 'common' }) }</div>
26
+ );
27
+ }
28
+
29
+ const onSave = (data: DevPosForm) => {
30
+ SaveSettings(data, {
31
+ onSuccess: () => success(t('api_details.messages.saved'))
32
+ });
33
+ };
34
+
35
+ switch (type) {
36
+ case 'devpos':
37
+ return (
38
+ <DevPos
39
+ data={ data }
40
+ loading={ isPending }
41
+ t={ t }
42
+ onSave={ onSave }
43
+ />
44
+ );
45
+ }
46
+ };
47
+
48
+ export default Content;
@@ -0,0 +1,139 @@
1
+ import { TFunction } from 'i18next';
2
+ import { useForm } from 'react-hook-form';
3
+ import { Button } from '../index';
4
+ import { Validate, Display } from '@autobusal/utilities';
5
+ import { ApiDetailsData } from '@autobusal/providers/types/users';
6
+ import { DevPosForm } from './types';
7
+
8
+ interface Props {
9
+ data?: ApiDetailsData
10
+ loading: boolean
11
+ t: TFunction<'common'>
12
+ onSave: (data: DevPosForm) => void
13
+ }
14
+
15
+ const DevPos = ({ data, loading, t, onSave }: Props): JSX.Element => {
16
+ const { register, handleSubmit, formState: { errors } } = useForm<DevPosForm>();
17
+
18
+ const onClick = (): void => {
19
+ handleSubmit(onSave)();
20
+ };
21
+
22
+ const onKeyDown = (event: React.KeyboardEvent<HTMLInputElement>): void => {
23
+ if (event.key === 'Enter') {
24
+ event.preventDefault();
25
+ onClick();
26
+ }
27
+ };
28
+
29
+ return (
30
+ <>
31
+ <div className="column">
32
+ <div className="row">
33
+ { t('api_details.devpos.business_code', { ns: 'common' }) }
34
+
35
+ <input type="text" defaultValue={ data?.business_code } { ...register('business_code', Validate('required|min_length:2', t)) } onKeyDown={ onKeyDown } />
36
+
37
+ { Display(errors.business_code) }
38
+ </div>
39
+
40
+ <div className="row">
41
+ { t('api_details.devpos.operator_code', { ns: 'common' }) }
42
+
43
+ <input type="text" defaultValue={ data?.operator_code } { ...register('operator_code', Validate('required|min_length:2', t)) } onKeyDown={ onKeyDown } />
44
+
45
+ { Display(errors.operator_code) }
46
+ </div>
47
+ </div>
48
+
49
+ <div className="column">
50
+ <div className="row">
51
+ { t('api_details.devpos.nuis', { ns: 'common' }) }
52
+
53
+ <input type="text" defaultValue={ data?.nuis } { ...register('nuis', Validate('required|min_length:2', t)) } onKeyDown={ onKeyDown } />
54
+
55
+ { Display(errors.nuis) }
56
+ </div>
57
+
58
+ <div className="row">
59
+ { t('api_details.devpos.fiscalization_number', { ns: 'common' }) }
60
+
61
+ <input type="text" defaultValue={ data?.fiscalization_number } { ...register('fiscalization_number', Validate('required|min_length:2', t)) } onKeyDown={ onKeyDown } />
62
+
63
+ { Display(errors.fiscalization_number) }
64
+ </div>
65
+ </div>
66
+
67
+ <div className="column">
68
+ <div className="row">
69
+ { t('api_details.devpos.username', { ns: 'common' }) }
70
+
71
+ <input type="text" defaultValue={ data?.username } { ...register('username', Validate('required|min_length:2', t)) } onKeyDown={ onKeyDown } />
72
+
73
+ { Display(errors.username) }
74
+ </div>
75
+
76
+ <div className="row">
77
+ { t('api_details.devpos.password', { ns: 'common' }) }
78
+
79
+ <input type="text" defaultValue={ data?.password } { ...register('password', Validate('required|min_length:2', t)) } onKeyDown={ onKeyDown } />
80
+
81
+ { Display(errors.password) }
82
+ </div>
83
+ </div>
84
+
85
+ <div className="row">
86
+ { t('api_details.devpos.bank_name', { ns: 'common' }) }
87
+
88
+ <input type="text" defaultValue={ data?.bank_name } { ...register('bank_name', Validate('required|min_length:2', t)) } onKeyDown={ onKeyDown } />
89
+
90
+ { Display(errors.bank_name) }
91
+ </div>
92
+
93
+ <div className="column">
94
+ <div className="row">
95
+ { t('api_details.devpos.bank_swift', { ns: 'common' }) }
96
+
97
+ <input type="text" defaultValue={ data?.bank_swift } { ...register('bank_swift', Validate('required|min_length:2', t)) } onKeyDown={ onKeyDown } />
98
+
99
+ { Display(errors.bank_swift) }
100
+ </div>
101
+
102
+ <div className="row">
103
+ { t('api_details.devpos.bank_account', { ns: 'common' }) }
104
+
105
+ <input type="text" defaultValue={ data?.bank_account } { ...register('bank_account', Validate('required|min_length:2', t)) } onKeyDown={ onKeyDown } />
106
+
107
+ { Display(errors.bank_account) }
108
+ </div>
109
+ </div>
110
+
111
+ <div className="column">
112
+ <div className="row">
113
+ { t('api_details.devpos.bank_address', { ns: 'common' }) }
114
+
115
+ <input type="text" defaultValue={ data?.bank_address } { ...register('bank_address', Validate('required|min_length:2', t)) } onKeyDown={ onKeyDown } />
116
+
117
+ { Display(errors.bank_address) }
118
+ </div>
119
+
120
+ <div className="row">
121
+ { t('api_details.devpos.bank_city', { ns: 'common' }) }
122
+
123
+ <input type="text" defaultValue={ data?.bank_city } { ...register('bank_city', Validate('required|min_length:2', t)) } onKeyDown={ onKeyDown } />
124
+
125
+ { Display(errors.bank_city) }
126
+ </div>
127
+ </div>
128
+
129
+ <Button
130
+ type="button"
131
+ loading={ loading }
132
+ text={ t('api_details.save', { ns: 'common' }) }
133
+ onClick={ onClick }
134
+ />
135
+ </>
136
+ );
137
+ };
138
+
139
+ export default DevPos;
@@ -0,0 +1,39 @@
1
+ import { useQuery, UseQueryResult, useMutation, UseMutationResult } from '@tanstack/react-query';
2
+ import { apiClient } from '@autobusal/providers';
3
+ import { ApiDetailsData } from '@autobusal/providers/types/users';
4
+ import { DevPosForm } from './types';
5
+
6
+ export const GetSettings = (id: number, type: string): UseQueryResult<ApiDetailsData | string> => (
7
+ useQuery({
8
+ queryKey: ['apidetails-get-settings', { id, type }],
9
+ queryFn: async () => (
10
+ await apiClient
11
+ .get('/api/api_details/admin/get', {
12
+ params: {
13
+ id,
14
+ type
15
+ }
16
+ })
17
+ .then(response => (
18
+ response.data
19
+ ))
20
+ )
21
+ })
22
+ );
23
+
24
+ export const PostSettings = (id: number, type: string): UseMutationResult<void, Error, DevPosForm, unknown> => (
25
+ useMutation({
26
+ mutationKey: ['apidetails-update-settings'],
27
+ mutationFn: async (data: DevPosForm) => (
28
+ await apiClient
29
+ .post('/api/api_details/admin/update', {
30
+ ...data,
31
+ id,
32
+ type
33
+ })
34
+ .then(response => (
35
+ response.data
36
+ ))
37
+ )
38
+ })
39
+ );
@@ -0,0 +1,13 @@
1
+ export interface DevPosForm {
2
+ business_code: string
3
+ operator_code: string
4
+ nuis: string
5
+ fiscalization_number: string
6
+ username: string
7
+ password: string
8
+ bank_name: string
9
+ bank_swift: string
10
+ bank_account: string
11
+ bank_address: string
12
+ bank_city: string
13
+ }
@@ -1,8 +1,8 @@
1
1
  import { useState, useRef, ChangeEvent, KeyboardEvent } from 'react';
2
- import { UseFormRegister, UseFormSetValue } from 'react-hook-form';
3
2
  import { TFunction } from 'i18next';
3
+ import { UseFormRegister, UseFormSetValue } from 'react-hook-form';
4
4
  import { useOutside } from '@autobusal/hooks';
5
- import { validate } from '@autobusal/utilities';
5
+ import { Validate } from '@autobusal/utilities';
6
6
  import Suggestions from './Suggestions';
7
7
  import { Container } from './styles';
8
8
  import { AutocompleteData } from './types';
@@ -97,7 +97,7 @@ const Autocomplete = ({ name, defaultValue, data, validation, t, refs, onUpdate
97
97
 
98
98
  { (show && q.length > 1 && options.length > 0) && <Suggestions options={ options } selected={ selected } onClick={ onSelected } /> }
99
99
 
100
- <input type="hidden" defaultValue={ value } { ...refs(name, validate(validation, t)) } />
100
+ <input type="hidden" defaultValue={ value } { ...refs(name, Validate(validation, t)) } />
101
101
  </Container>
102
102
  );
103
103
  }
package/Avatar.tsx ADDED
@@ -0,0 +1,28 @@
1
+ import styled from 'styled-components';
2
+ import { OperatorData } from '@autobusal/providers/types/operators';
3
+ import { AgentData } from '@autobusal/providers/types/agents';
4
+
5
+ interface Props {
6
+ display?: OperatorData | AgentData
7
+ }
8
+
9
+ const Avatar = ({ display }: Props): JSX.Element => (
10
+ <Container>
11
+ { display?.logo_url !== '' && <img src={ display?.logo_url } />}
12
+ { display?.company }
13
+ </Container>
14
+ );
15
+
16
+ const Container = styled.div`
17
+ display: flex;
18
+ align-items: center;
19
+ gap: 10px;
20
+
21
+ & > img {
22
+ display: block;
23
+ width: 80px;
24
+ border-radius: ${ props => props.theme.borderRadius };
25
+ }
26
+ `;
27
+
28
+ export default Avatar;
@@ -1,6 +1,6 @@
1
1
  import { TFunction } from 'i18next';
2
- import { Link } from 'react-router-dom';
3
2
  import styled from 'styled-components';
3
+ import { Link } from 'react-router-dom';
4
4
  import { BiChevronLeftCircle } from 'react-icons/bi';
5
5
 
6
6
  interface Props {
@@ -15,13 +15,14 @@ const LinkStyled = styled(Link)`
15
15
  padding: 4px 12px;
16
16
  font-size: calc(${ props => props.theme.size.info } - 1px);
17
17
  text-transform: uppercase;
18
- background: ${ props => props.theme.neutral };
18
+ background: ${ props => props.theme.foreground.normal };
19
19
  border-radius: ${ props => props.theme.borderRadius };
20
+ box-shadow: ${ props => props.theme.boxShadow };
20
21
  transition: all 0.3s ease;
21
22
 
22
23
  &:hover {
24
+ opacity: .8;
23
25
  text-decoration: none;
24
- background: ${ props => props.theme.primaryTransparent };
25
26
  }
26
27
  `;
27
28
 
@@ -0,0 +1,30 @@
1
+ import { TFunction } from 'i18next';
2
+ import styled from 'styled-components';
3
+ import BackTo from './BackTo';
4
+
5
+ interface Props {
6
+ title: string
7
+ to: string
8
+ t: TFunction<'common'>
9
+ }
10
+
11
+ const Container = styled.div`
12
+ display: flex;
13
+ gap: 15px;
14
+ align-items: center;
15
+ margin-bottom: 20px;
16
+
17
+ & > h1 {
18
+ margin-bottom: 0;
19
+ }
20
+ `;
21
+
22
+ const BackWithTitle = ({ title, to, t }: Props): JSX.Element => (
23
+ <Container>
24
+ <BackTo to={ to } t={ t } />
25
+
26
+ <h1>{ title }</h1>
27
+ </Container>
28
+ );
29
+
30
+ export default BackWithTitle;
package/Button/Button.tsx CHANGED
@@ -13,7 +13,7 @@ interface Props {
13
13
  onClick?: any
14
14
  }
15
15
 
16
- export const Button = ({ type, size, loading, active, subtype, text, noMargin, maxWidth, onClick }: Props) => (
16
+ const Button = ({ type, size, loading, active, subtype, text, noMargin, maxWidth, onClick }: Props) => (
17
17
  <ButtonStyled
18
18
  $size={ size }
19
19
  type={ loading ? 'button' : type }
@@ -25,4 +25,6 @@ export const Button = ({ type, size, loading, active, subtype, text, noMargin, m
25
25
  >
26
26
  { loading ? <RiLoader2Fill /> : text }
27
27
  </ButtonStyled>
28
- );
28
+ );
29
+
30
+ export default Button;
@@ -2,7 +2,7 @@ import { useState, useRef } from 'react';
2
2
  import { UseFormRegister, UseFormSetValue } from 'react-hook-form';
3
3
  import { TFunction } from 'i18next';
4
4
  import { useOutside } from '@autobusal/hooks';
5
- import { validate, prepareDate } from '@autobusal/utilities';
5
+ import { Validate, prepareDate } from '@autobusal/utilities';
6
6
  import Picker from './Picker';
7
7
  import { Container } from './styles';
8
8
 
@@ -48,7 +48,7 @@ const Calendar = ({ type, name, defaultValue, t, validation, refs, onUpdate }: P
48
48
  />
49
49
  ) }
50
50
 
51
- <input type="hidden" defaultValue={ prepared } { ...refs(name, validate(validation ?? '', t)) } />
51
+ <input type="hidden" defaultValue={ prepared } { ...refs(name, Validate(validation ?? '', t)) } />
52
52
  </Container>
53
53
  );
54
54
  }
@@ -7,7 +7,7 @@ interface Props {
7
7
  type: 'agent' | 'operator'
8
8
  }
9
9
 
10
- const BrowseCompanyItem = ({ item, type }: Props): JSX.Element => {
10
+ const CompanyItem = ({ item, type }: Props): JSX.Element => {
11
11
  const isColumn = item.column === 1;
12
12
  const isBanner = item.banner === 1;
13
13
 
@@ -36,4 +36,4 @@ const BrowseCompanyItem = ({ item, type }: Props): JSX.Element => {
36
36
  );
37
37
  };
38
38
 
39
- export default BrowseCompanyItem;
39
+ export default CompanyItem;
@@ -0,0 +1,40 @@
1
+ import { TFunction } from 'i18next';
2
+ import { BiTransfer } from 'react-icons/bi';
3
+ import { RiMoneyEuroCircleFill, RiPhoneLine } from 'react-icons/ri';
4
+ import { Container, Funds, LinkMore } from './styles';
5
+
6
+ interface Props {
7
+ item: any
8
+ t: TFunction<'common'>
9
+ }
10
+
11
+ const ContactInfo = ({ item, t }: Props): JSX.Element => {
12
+ const onClick = (event: React.MouseEvent<HTMLAnchorElement>): void => {
13
+ event.stopPropagation();
14
+ };
15
+
16
+ return (
17
+ <Container>
18
+ { item.funds_display && <Funds>{ item.funds_display }</Funds> }
19
+
20
+ { item.mobile && (
21
+ <LinkMore to={ `tel:${ item.mobile }` } onClick={ (event) => onClick(event) }>
22
+ <RiPhoneLine />
23
+ { item.mobile }
24
+ </LinkMore>
25
+ ) }
26
+
27
+ <LinkMore to={ `/admin/funds/manage/${ item.user.id }` } onClick={ (event) => onClick(event) }>
28
+ <RiMoneyEuroCircleFill />
29
+ { t('contact_info.add_funds', { ns: 'common' }) }
30
+ </LinkMore>
31
+
32
+ <LinkMore to={ `/account/transactions?id=${ item.user.id }` } onClick={ (event) => onClick(event) }>
33
+ <BiTransfer />
34
+ { t('contact_info.view_transactions', { ns: 'common' }) }
35
+ </LinkMore>
36
+ </Container>
37
+ );
38
+ };
39
+
40
+ export default ContactInfo;
@@ -0,0 +1,33 @@
1
+ import styled from 'styled-components';
2
+ import { Link } from 'react-router-dom';
3
+
4
+ export const Container = styled.div`
5
+ display: flex;
6
+ flex-direction: column;
7
+ gap: 5px;
8
+ `;
9
+
10
+ export const Funds = styled.div`
11
+ font-weight: 700;
12
+ color: ${ props => props.theme.font.info };
13
+ `;
14
+
15
+ export const LinkMore = styled(Link)`
16
+ align-self: center;
17
+ display: flex;
18
+ align-items: center;
19
+ justify-content: center;
20
+ gap: 5px;
21
+ padding: 2px 5px;
22
+ font-weight: 700;
23
+ font-size: ${ props => props.theme.size.xs };
24
+ border: 1px solid ${ props => props.theme.primary.normal };
25
+ border-radius: ${ props => props.theme.borderRadius };
26
+ transition: all 0.3s ease;
27
+
28
+ &:hover {
29
+ text-decoration: none;
30
+ color: ${ props => props.theme.primary.contrast };
31
+ background: ${ props => props.theme.primary.normal };
32
+ }
33
+ `;
@@ -1,6 +1,6 @@
1
1
  import { useState } from 'react';
2
2
  import { TFunction } from 'i18next';
3
- import { Button } from '../Button/Button';
3
+ import Button from '../Button/Button';
4
4
  import { Container, Info } from './styles';
5
5
 
6
6
  interface Props {
@@ -18,7 +18,7 @@ const CookieNotification = ({ t }: Props): (JSX.Element | null) => {
18
18
  const CookieDate = new Date();
19
19
  CookieDate.setFullYear(CookieDate.getFullYear() + 1);
20
20
 
21
- document.cookie = 'AutobusCookieNotification=viewed; expires=' + CookieDate.toUTCString() + "; path=/; SameSite=None; Secure";
21
+ document.cookie = 'OBTCookieNotification=viewed; expires=' + CookieDate.toUTCString() + '; path=/; SameSite=None; Secure';
22
22
  };
23
23
 
24
24
  if (! show) {
package/File/File.tsx CHANGED
@@ -2,26 +2,27 @@ import { TFunction } from 'i18next';
2
2
  import { useState, useRef } from 'react';
3
3
  import { UseFormRegister } from 'react-hook-form';
4
4
  import { HiOutlineCloudUpload, HiCheck } from 'react-icons/hi';
5
- import { Modal } from '@autobusal/common';
6
- import { validate } from '@autobusal/utilities';
7
- import { Button } from '../Button/Button';
5
+ import Modal from '../Modal/Modal';
6
+ import { Validate } from '@autobusal/utilities';
7
+ import Button from '../Button/Button';
8
8
  import { Container, ImgView, ImgPreview } from './styles';
9
9
 
10
10
  interface Props {
11
11
  name: string
12
12
  value?: string
13
13
  validation?: string
14
+ multiple?: boolean
14
15
  t: TFunction<'comon'>
15
16
  refs: UseFormRegister<any>
16
17
  }
17
18
 
18
- const File = ({ name, value, validation, t, refs }: Props): JSX.Element => {
19
+ const File = ({ name, value, validation, multiple, t, refs }: Props): JSX.Element => {
19
20
  const [ uploaded, setUploaded ] = useState<boolean>(false);
20
21
  const [ preview, setPreview ] = useState<boolean>(false);
21
22
 
22
23
  const inputRef = useRef<HTMLInputElement | null>(null);
23
24
 
24
- const rules = validate(String(validation), t);
25
+ const rules = Validate(String(validation), t);
25
26
 
26
27
  const onChange = (): void => {
27
28
  setUploaded(true);
@@ -38,6 +39,8 @@ const File = ({ name, value, validation, t, refs }: Props): JSX.Element => {
38
39
  }
39
40
  };
40
41
 
42
+ const type = multiple ? 'multiple' : 'single';
43
+
41
44
  return (
42
45
  <>
43
46
  <Container>
@@ -45,6 +48,7 @@ const File = ({ name, value, validation, t, refs }: Props): JSX.Element => {
45
48
  { ...rest }
46
49
  type="file"
47
50
  name={ name }
51
+ multiple={ multiple }
48
52
  style={{ display: 'none' }}
49
53
  ref={ (e) => {
50
54
  ref(e);
@@ -57,8 +61,8 @@ const File = ({ name, value, validation, t, refs }: Props): JSX.Element => {
57
61
  size="small"
58
62
  text={
59
63
  uploaded
60
- ? <><HiCheck /> { t('file.done', { ns: 'common' }) }</>
61
- : <><HiOutlineCloudUpload /> { t('file.ready', { ns: 'common' }) }</>
64
+ ? <><HiCheck /> { t(`file.${ type }.done`, { ns: 'common' }) }</>
65
+ : <><HiOutlineCloudUpload /> { t(`file.${ type }.ready`, { ns: 'common' }) }</>
62
66
  }
63
67
  noMargin
64
68
  onClick={ onClick }
@@ -0,0 +1,47 @@
1
+ import { TFunction } from 'i18next';
2
+ import { useState } from 'react';
3
+ import { AiOutlineLogin } from 'react-icons/ai';
4
+ import { Button } from '../index';
5
+ import View from './View';
6
+ import { NotAvailable } from './styles';
7
+
8
+ interface Props {
9
+ id: number
10
+ page: number
11
+ type: 'admins' | 'agents' | 'financers' | 'operators' | 'visitors'
12
+ t: TFunction<'common'>
13
+ }
14
+
15
+ const IpLogs = ({ id, page, type, t }: Props): (JSX.Element | string) => {
16
+ const [ show, setShow ] = useState<boolean>(false);
17
+
18
+ if (id === 0) {
19
+ return (
20
+ <NotAvailable>
21
+ { t('ip_logs.not_available', { ns: 'common' }) }
22
+ </NotAvailable>
23
+ );
24
+ }
25
+
26
+ return (
27
+ <>
28
+ <Button
29
+ type="button"
30
+ subtype="secondary"
31
+ size="small"
32
+ text={ (
33
+ <>
34
+ <AiOutlineLogin />
35
+ { t('ip_logs.view', { ns: 'common' }) }
36
+ </>
37
+ ) }
38
+ noMargin
39
+ onClick={ () => setShow(true) }
40
+ />
41
+
42
+ { show && <View id={ id } page={ page } type={ type } t={ t } /> }
43
+ </>
44
+ );
45
+ };
46
+
47
+ export default IpLogs;