code7-leia 1.0.13 → 1.0.15

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "code7-leia",
3
- "version": "1.0.13",
3
+ "version": "1.0.15",
4
4
  "author": "code7-xlab",
5
5
  "license": "MIT",
6
6
  "main": "dist/index.es.js",
@@ -18,7 +18,7 @@
18
18
  "scripts": {
19
19
  "dev": "vite",
20
20
  "build": "vite build",
21
- "deploy": "npm run build && npm version patch && npm publish"
21
+ "deploy": "npm run build && npm publish"
22
22
  },
23
23
  "dependencies": {
24
24
  "axios": "^1.6.7",
@@ -39,7 +39,7 @@
39
39
  "devDependencies": {
40
40
  "@types/node": "^22.16.0",
41
41
  "@types/react-dom": "^18.2.0",
42
- "@types/styled-components": "^5.1.34",
42
+ "@types/styled-components": "^5.1.36",
43
43
  "@vitejs/plugin-react": "5.0.2",
44
44
  "react": "^18.2.0",
45
45
  "react-dom": "^18.2.0",
@@ -79,3 +79,7 @@ export const Container = styled.div<ContainerProps>`
79
79
  }
80
80
  }
81
81
  `;
82
+
83
+ const Table = styled.table`
84
+ margin-top: 12px;
85
+ `
@@ -1,9 +1,10 @@
1
1
  import React from 'react';
2
2
  import * as S from './styles';
3
3
  import { IoClose } from 'react-icons/io5';
4
+ import Tooltip from '../Tootip';
4
5
 
5
6
  interface ModalProps {
6
- title?: string;
7
+ title?: React.ReactNode;
7
8
  children: React.ReactNode;
8
9
  onClose: () => void;
9
10
  }
@@ -13,7 +14,7 @@ const Modal = ({ title, children, onClose }: ModalProps) => {
13
14
  <S.Overlay>
14
15
  <S.Container>
15
16
  <S.Header>
16
- {title && <h3>{title}</h3>}
17
+ {title && <>{title}</>}
17
18
  <button onClick={onClose}>
18
19
  <IoClose />
19
20
  </button>
@@ -1,6 +1,6 @@
1
1
  import { useState } from 'react';
2
2
  import { getLanguage } from '../../utils/getLanguage';
3
- import { FaPlus, FaCopy, FaEdit, FaTrash } from 'react-icons/fa';
3
+ import { FaPlus, FaCopy, FaEdit, FaQuestionCircle, FaTrash } from 'react-icons/fa';
4
4
  import Modal from '../Modal';
5
5
  import Input from '../TestArea/components/InputTest';
6
6
  import TextArea from '../TestArea/components/TextArea';
@@ -10,6 +10,7 @@ import LengthCounter from '../LengthCounter';
10
10
  import { useLeia } from '../../contexts/LeiaProvider';
11
11
 
12
12
  import * as S from './styles';
13
+ import Tooltip from '../Tootip';
13
14
 
14
15
  interface Persona {
15
16
  id: number;
@@ -102,10 +103,29 @@ export const PersonasArea = () => {
102
103
  p.name.toLowerCase().includes(search.toLowerCase())
103
104
  );
104
105
 
106
+ const ModalTitle = () => {
107
+ return (
108
+ <S.ModalTitleContainer className='modal-title'>
109
+ <h3>{t.personas?.modalTitle}</h3>
110
+ <Tooltip
111
+ position="right"
112
+ width={'200px'}
113
+ render={() =>
114
+ t.personas?.modalTooltip
115
+ }
116
+ >
117
+ <>
118
+ <FaQuestionCircle color = "#8D9CA1" size={16}/>
119
+ </>
120
+ </Tooltip>
121
+ </S.ModalTitleContainer>
122
+ )
123
+ }
124
+
105
125
  return (
106
126
  <S.Container>
107
127
  <S.Header>
108
- <div>
128
+ <div className='infos'>
109
129
  <h2>{t.personas?.title}</h2>
110
130
  <p>{t.personas?.description}</p>
111
131
  </div>
@@ -113,19 +133,22 @@ export const PersonasArea = () => {
113
133
  <FaPlus /> {t.personas?.add}
114
134
  </button>
115
135
  </S.Header>
116
- <Search placeholder={t.search} setFiles={setPersonas} initialFiles={personas} />
117
- <S.List>
118
- {filteredPersonas?.map((persona: any) => (
119
- <S.Row key={persona.id}>
120
- <div className="info">
121
- <strong>{persona.name}</strong>
122
- <span>{persona.description}</span>
123
- </div>
124
- {/**
125
- * Se tiver o created_at, significa que é uma persona criada pelo usuário
126
- * e pode ser editada ou clonada. Caso contrário, é uma persona padrão e não pode ser editada.
127
- */}
128
- {persona.created_at && (
136
+ <S.Search>
137
+ <Search placeholder={t.search} setFiles={setPersonas} initialFiles={personas} />
138
+ </S.Search>
139
+ <S.TableContainer>
140
+ <tbody>
141
+ {filteredPersonas?.map((persona: any) => (
142
+
143
+ <tr className = "tr-Row" key = {persona.id}>
144
+ <td>
145
+ <div className="info">
146
+ <p><strong>{persona.name}</strong></p>
147
+ <span>{persona.description}</span>
148
+ </div>
149
+ </td>
150
+ <td className='td-actions'>
151
+ {persona.created_at && (
129
152
  <div className="actions">
130
153
  <button onClick={() => openEdit(persona)}>
131
154
  <FaEdit /> {t.edit}
@@ -133,28 +156,34 @@ export const PersonasArea = () => {
133
156
  <button onClick={() => openClone(persona)}>
134
157
  <FaCopy /> {t.clone}
135
158
  </button>
136
- <button onClick={() => openDelete(persona)}>
159
+ <button className="button-delete" onClick={() => openDelete(persona)}>
137
160
  <FaTrash /> {t.delete}
138
161
  </button>
139
162
  </div>
140
163
  )}
164
+ </td>
165
+ </tr>
166
+
141
167
 
142
- </S.Row>
143
- ))}
144
- </S.List>
168
+ ))}
169
+ </tbody>
170
+ </S.TableContainer>
171
+
145
172
 
146
173
  {isOpen && (
147
- <Modal onClose={() => setIsOpen(false)} title={t.personas?.modalTitle}>
174
+ <Modal onClose={() => setIsOpen(false)} title={<ModalTitle/>}>
148
175
  <S.InputWrapper>
149
176
  <Input
150
177
  value={form.name}
151
178
  placeholder={t.personas?.fields.name}
152
179
  onChange={(value: any) => setForm({ ...form, name: value })}
180
+ maxLength={50}
153
181
  />
154
182
  <Input
155
183
  value={form.description}
156
184
  placeholder={t.personas?.fields.description}
157
185
  onChange={(value: any) => setForm({ ...form, description: value })}
186
+ maxLength={200}
158
187
  />
159
188
  </S.InputWrapper>
160
189
  <TextArea
@@ -18,7 +18,6 @@ export const Header = styled.div`
18
18
 
19
19
  h2 {
20
20
  font-size: 20px;
21
- margin: 0;
22
21
  }
23
22
 
24
23
  p {
@@ -48,7 +47,7 @@ export const Header = styled.div`
48
47
 
49
48
  export const Search = styled.div`
50
49
  width: 320px;
51
- margin-bottom: 15px;
50
+ margin-bottom: 12px;
52
51
  `;
53
52
 
54
53
  export const List = styled.div`
@@ -87,7 +86,7 @@ export const Row = styled.div`
87
86
  gap: 8px;
88
87
 
89
88
  button {
90
- background: white;
89
+ background: red;
91
90
  border: 1px solid #dcdfe6;
92
91
  padding: 6px 10px;
93
92
  border-radius: 4px;
@@ -135,3 +134,78 @@ export const InputWrapper = styled.div`
135
134
  margin-bottom: 12px;
136
135
  max-width: 100%;
137
136
  `;
137
+
138
+ export const TableContainer = styled.table`
139
+
140
+ .tr-Row {
141
+ display: flex;
142
+ justify-content: space-between;
143
+ align-items: center;
144
+
145
+ background: white;
146
+ padding: 14px;
147
+ border-radius: 5px;
148
+ border: 1px solid #dcdfe6;
149
+ margin-bottom: 2px;
150
+
151
+ .info {
152
+ display: flex;
153
+ flex-direction: column;
154
+
155
+ strong {
156
+ font-size: 14px;
157
+ }
158
+
159
+ span {
160
+ font-size: 13px;
161
+ color: #5a5d68;
162
+ margin-top: 2px;
163
+ }
164
+ }
165
+
166
+ .actions {
167
+ display: flex;
168
+ gap: 8px;
169
+
170
+ button {
171
+ background: #f3f5f9;
172
+ cursor: pointer;
173
+ border: 1px solid #dcdfe6;
174
+ padding: 8px 12px;
175
+ border-radius: 4px;
176
+ color: rgb(16, 38, 147);
177
+
178
+ display: flex;
179
+ align-items: center;
180
+ gap: 6px;
181
+
182
+ font-size: 12px;
183
+
184
+ svg {
185
+ width: 12px;
186
+ height: 12px;
187
+ }
188
+
189
+ &:hover {
190
+ background: #dadce3;
191
+ }
192
+ }
193
+
194
+ .button-delete {
195
+ background: #fae0d2;
196
+ border: 1px solid #f5c2c2;
197
+ color: #5b0a1f;
198
+
199
+ &:hover {
200
+ background: #f5bba7;
201
+ }
202
+ }
203
+ }
204
+ }
205
+ `;
206
+
207
+ export const ModalTitleContainer = styled.div`
208
+ display: flex;
209
+ gap: 8px;
210
+ align-items: center;
211
+ `;
@@ -1,20 +1,21 @@
1
1
  import React from 'react';
2
2
  import * as S from './styles';
3
3
 
4
- interface InputTestProps {
5
- placeholder: string;
4
+ interface InputTestProps
5
+ extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'onChange'> {
6
6
  onChange: (value: string) => void;
7
- value?: string;
8
7
  }
9
8
 
10
- const InputTest: React.FC<InputTestProps> = ({ placeholder, onChange, value }) => {
9
+
10
+ const InputTest: React.FC<InputTestProps> = ({
11
+ onChange,
12
+ ...rest
13
+ }) => {
11
14
  return (
12
15
  <S.Container>
13
16
  <S.StyledInput
14
- type="text"
15
- value={value}
16
- onChange={(e: any) => onChange(e.target.value)}
17
- placeholder={placeholder}
17
+ {...rest}
18
+ onChange={(e: React.ChangeEvent<HTMLInputElement>) => onChange(e.target.value)}
18
19
  />
19
20
  </S.Container>
20
21
  );
@@ -0,0 +1,45 @@
1
+ import React, { ReactElement, ReactNode } from 'react';
2
+ import cc from 'classcat';
3
+
4
+ import { Container } from './styles';
5
+
6
+ interface TooltipProps extends React.HTMLAttributes<HTMLDivElement> {
7
+ render: () => ReactNode;
8
+ children: ReactElement;
9
+ position?: 'left' | 'right' | 'top' | 'bottom';
10
+ theme?: 'light' | 'dark';
11
+ show?: boolean;
12
+ className?: string;
13
+ width?: string;
14
+ }
15
+
16
+ const Tooltip: React.FC<TooltipProps> = ({
17
+ position = 'bottom',
18
+ theme = 'dark',
19
+ render,
20
+ children,
21
+ show = true,
22
+ className = '',
23
+ width = '100px',
24
+ ...rest
25
+ }) => {
26
+ return (
27
+ <>
28
+ {!show ? (
29
+ children
30
+ ) : (
31
+ <Container
32
+ width={width}
33
+ className={cc([theme, position, className])}
34
+ {...rest}
35
+ >
36
+ {render && <div className="tooltip-content">{render()}</div>}
37
+
38
+ <div className="tooltip-target">{children}</div>
39
+ </Container>
40
+ )}
41
+ </>
42
+ );
43
+ };
44
+
45
+ export default Tooltip;
@@ -0,0 +1,177 @@
1
+ import styled from 'styled-components';
2
+
3
+ interface ContainerProps {
4
+ width?: string;
5
+ }
6
+
7
+ export const Container = styled.div<ContainerProps>`
8
+ align-items: center;
9
+ display: inline-flex;
10
+ justify-content: center;
11
+ position: relative;
12
+
13
+ .tooltip-content {
14
+ border-radius: 5px;
15
+ font-size: 13px;
16
+ display: none;
17
+ padding: 6px 10px;
18
+ position: absolute;
19
+ transition: opacity 0.5s;
20
+ z-index: 6;
21
+ width: ${({ width }) => width};
22
+ line-height: 20px;
23
+
24
+ &::after {
25
+ border-style: solid;
26
+ border-width: 6px;
27
+ content: '';
28
+ position: absolute;
29
+ }
30
+ }
31
+
32
+ &:hover {
33
+ .tooltip-content {
34
+ display: block;
35
+ opacity: 1;
36
+ visibility: visible;
37
+ }
38
+ }
39
+
40
+ &.dark {
41
+ .tooltip-content {
42
+ background-color: var(--neutral-3);
43
+ color: #fff;
44
+ box-shadow: 0px 5px 6px #00000040;
45
+
46
+ &::after {
47
+ border-color: var(--neutral-3) transparent transparent transparent;
48
+ }
49
+ }
50
+ }
51
+
52
+ &.light {
53
+ .tooltip-content {
54
+ background: #fff;
55
+ border-radius: 5px;
56
+ box-shadow: 1px 4px 4px rgba(0, 0, 0, 0.25);
57
+
58
+ &::after {
59
+ border-color: #fff transparent transparent transparent;
60
+ }
61
+
62
+ &::before {
63
+ content: '';
64
+ border-style: solid;
65
+ border-width: 9px;
66
+ position: absolute;
67
+ border-color: #d8d8d8 transparent transparent transparent;
68
+ }
69
+ }
70
+ }
71
+
72
+ &.top {
73
+ .tooltip-content {
74
+ bottom: calc(100% + 10px);
75
+ left: 50%;
76
+ transform: translateX(-50%);
77
+ }
78
+
79
+ &.dark .tooltip-content {
80
+ &::after {
81
+ top: calc(100%);
82
+ left: 50%;
83
+ transform: translateX(-50%);
84
+ }
85
+ }
86
+
87
+ &.light .tooltip-content {
88
+ &::before,
89
+ &::after {
90
+ top: 100%;
91
+ left: 50%;
92
+ transform: translateX(-50%);
93
+ }
94
+ }
95
+ }
96
+
97
+ &.bottom {
98
+ .tooltip-content {
99
+ top: calc(100% + 10px);
100
+ left: 50%;
101
+ transform: translateX(-50%);
102
+ }
103
+
104
+ &.dark .tooltip-content {
105
+ &::after {
106
+ bottom: calc(100%);
107
+ left: 50%;
108
+ transform: translateX(-50%) rotate(180deg);
109
+ }
110
+ }
111
+
112
+ &.light .tooltip-content {
113
+ &::before,
114
+ &::after {
115
+ bottom: 100%;
116
+ left: 50%;
117
+ transform: translateX(-50%) rotate(180deg);
118
+ }
119
+ }
120
+ }
121
+
122
+ &.right {
123
+ .tooltip-content {
124
+ left: calc(100% + 10px);
125
+ top: 50%;
126
+ transform: translateY(-50%);
127
+ }
128
+
129
+ &.dark .tooltip-content {
130
+ &::after {
131
+ right: 100%;
132
+ top: 50%;
133
+ transform: translateY(-50%) rotate(90deg);
134
+ }
135
+ }
136
+
137
+ &.light .tooltip-content {
138
+ &::before,
139
+ &::after {
140
+ right: 100%;
141
+ top: 50%;
142
+ transform: translateY(-50%) rotate(90deg);
143
+ }
144
+ }
145
+ }
146
+
147
+ &.left {
148
+ .tooltip-content {
149
+ right: calc(100% + 10px);
150
+ top: 50%;
151
+ transform: translateY(-50%);
152
+ }
153
+
154
+ &.dark .tooltip-content {
155
+ &::after {
156
+ left: 100%;
157
+ top: 50%;
158
+ transform: translateY(-50%) rotate(270deg);
159
+ }
160
+ }
161
+
162
+ &.light .tooltip-content {
163
+ &::before,
164
+ &::after {
165
+ left: 100%;
166
+ top: 50%;
167
+ transform: translateY(-50%) rotate(270deg);
168
+ }
169
+ }
170
+ }
171
+
172
+ &.show {
173
+ .tooltip-content {
174
+ display: inline-block;
175
+ }
176
+ }
177
+ `;
@@ -2,7 +2,7 @@ import axios from 'axios';
2
2
 
3
3
  export const API_TOKEN = 'API_TOKEN';
4
4
 
5
- const url = 'http://localhost:5000';
5
+ const url = 'https://api-hml.leia.digitalcontact.cloud'
6
6
 
7
7
  axios.defaults.baseURL = `${url}`;
8
8
 
@@ -8,6 +8,7 @@ export const enTranslation: Language = {
8
8
  edit: 'Edit',
9
9
  clone: 'Clone',
10
10
  save: 'Save',
11
+ delete: 'Delete',
11
12
  copyPrefix: 'Copy',
12
13
 
13
14
  personas: {
@@ -16,6 +17,7 @@ export const enTranslation: Language = {
16
17
  add: 'Add persona',
17
18
  modalTitle: 'Persona',
18
19
  modalAlert: 'Are you sure you want to delete',
20
+ modalTooltip: "The AI will behave exactly as described in this prompt. Anything it says from here on is the responsibility of the user.",
19
21
 
20
22
  fields: {
21
23
  name: 'Name',
@@ -7,6 +7,7 @@ export const esTranslation: Language = {
7
7
  search: 'Buscar',
8
8
  edit: 'Editar',
9
9
  clone: 'Clonar',
10
+ delete: 'Borrar',
10
11
  save: 'Guardar',
11
12
  copyPrefix: 'Copia',
12
13
 
@@ -16,6 +17,7 @@ export const esTranslation: Language = {
16
17
  add: 'Agregar persona',
17
18
  modalTitle: 'Persona',
18
19
  modalAlert: '¿Seguro que deseas eliminar',
20
+ modalTooltip: "La IA se comportará exactamente según este prompt. Todo lo que diga a partir de aquí es responsabilidad del usuario.",
19
21
 
20
22
  fields: {
21
23
  name: 'Nombre',
@@ -7,6 +7,7 @@ export const ptTranslation: Language = {
7
7
  search: 'Pesquisar',
8
8
  edit: 'Editar',
9
9
  clone: 'Clonar',
10
+ delete: 'Excluir',
10
11
  save: 'Salvar',
11
12
  copyPrefix: 'Cópia',
12
13
 
@@ -16,6 +17,7 @@ export const ptTranslation: Language = {
16
17
  add: 'Adicionar persona',
17
18
  modalTitle: 'Persona',
18
19
  modalAlert: 'Quer mesmo deletar',
20
+ modalTooltip: "A IA vai se comportar exatamente como este prompt descreve. Tudo o que ela disser a partir disso é responsabilidade do usuário.",
19
21
 
20
22
  fields: {
21
23
  name: 'Nome',