@audashai/cli 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.
- package/README.md +57 -0
- package/bin/audashai.js +3 -0
- package/dist/commands/add.d.ts +1 -0
- package/dist/commands/add.js +73 -0
- package/dist/commands/init.d.ts +1 -0
- package/dist/commands/init.js +62 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +16 -0
- package/dist/templates/components/AudashAIChatBot.d.ts +8 -0
- package/dist/templates/components/AudashAIChatBot.js +14 -0
- package/dist/templates/components/AudashAIInput.d.ts +1 -0
- package/dist/templates/components/AudashAIInput.js +114 -0
- package/dist/templates/components/AudashAIOutput.d.ts +1 -0
- package/dist/templates/components/AudashAIOutput.js +66 -0
- package/dist/templates/components/BarChart.d.ts +2 -0
- package/dist/templates/components/BarChart.js +41 -0
- package/dist/templates/components/ErrorDisplay.d.ts +4 -0
- package/dist/templates/components/ErrorDisplay.js +61 -0
- package/dist/templates/components/LineChart.d.ts +2 -0
- package/dist/templates/components/LineChart.js +41 -0
- package/dist/templates/context/AudashAIContext.d.ts +1 -0
- package/dist/templates/context/AudashAIContext.js +5 -0
- package/dist/templates/context/AudashAIProvider.d.ts +7 -0
- package/dist/templates/context/AudashAIProvider.js +50 -0
- package/dist/templates/hooks/useAudashAI.d.ts +1 -0
- package/dist/templates/hooks/useAudashAI.js +13 -0
- package/dist/templates/index.d.ts +9 -0
- package/dist/templates/index.js +38 -0
- package/dist/templates/types/index.d.ts +39 -0
- package/dist/templates/types/index.js +2 -0
- package/dist/templates/utils/api.d.ts +3 -0
- package/dist/templates/utils/api.js +52 -0
- package/dist/utils/config.d.ts +6 -0
- package/dist/utils/config.js +15 -0
- package/dist/utils/copy-files.d.ts +1 -0
- package/dist/utils/copy-files.js +14 -0
- package/package.json +42 -0
- package/templates/components/AudashAIChatBot.tsx +34 -0
- package/templates/components/AudashAIInput.tsx +181 -0
- package/templates/components/AudashAIOutput.tsx +90 -0
- package/templates/components/BarChart.tsx +113 -0
- package/templates/components/ErrorDisplay.tsx +87 -0
- package/templates/components/LineChart.tsx +105 -0
- package/templates/context/AudashAIContext.tsx +18 -0
- package/templates/context/AudashAIProvider.tsx +60 -0
- package/templates/hooks/useAudashAI.ts +10 -0
- package/templates/index.tsx +12 -0
- package/templates/types/index.ts +44 -0
- package/templates/utils/api.ts +57 -0
package/README.md
ADDED
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# @audashai/cli
|
|
2
|
+
|
|
3
|
+
CLI tool to add AudashAI components to your React project.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g @audashai/cli
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
### Initialize AudashAI in your project
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
audashai init
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### Add components
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
audashai add chatbot
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Available Components
|
|
26
|
+
|
|
27
|
+
- `chatbot` - AI-powered chatbot with data visualization
|
|
28
|
+
|
|
29
|
+
## Configuration
|
|
30
|
+
|
|
31
|
+
After running `audashai init`, a `audashai.config.json` file will be created:
|
|
32
|
+
|
|
33
|
+
```json
|
|
34
|
+
{
|
|
35
|
+
"componentsPath": "src/components/audashai",
|
|
36
|
+
"version": "1.0.0"
|
|
37
|
+
}
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Example
|
|
41
|
+
|
|
42
|
+
```tsx
|
|
43
|
+
import { AudashAIChatbot } from './components/audashai/components/AudashAIChatBot';
|
|
44
|
+
|
|
45
|
+
function App() {
|
|
46
|
+
return (
|
|
47
|
+
<AudashAIChatbot
|
|
48
|
+
apiKey={import.meta.env.VITE_SECRET_KEY_AUDASHAI}
|
|
49
|
+
apiUrl={import.meta.env.VITE_API_AI_AUDASHAI}
|
|
50
|
+
/>
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## License
|
|
56
|
+
|
|
57
|
+
MIT
|
package/bin/audashai.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function addCommand(component: string): Promise<void>;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.addCommand = addCommand;
|
|
7
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
8
|
+
const ora_1 = __importDefault(require("ora"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const copy_files_1 = require("../utils/copy-files");
|
|
11
|
+
const config_1 = require("../utils/config");
|
|
12
|
+
const COMPONENTS = {
|
|
13
|
+
chatbot: {
|
|
14
|
+
name: 'AudashAI Chatbot',
|
|
15
|
+
files: [
|
|
16
|
+
'components/AudashAIChatBot.tsx',
|
|
17
|
+
'components/AudashAIInput.tsx',
|
|
18
|
+
'components/AudashAIOutput.tsx',
|
|
19
|
+
'components/BarChart.tsx',
|
|
20
|
+
'components/LineChart.tsx',
|
|
21
|
+
'components/ErrorDisplay.tsx',
|
|
22
|
+
'context/AudashAIContext.tsx',
|
|
23
|
+
'context/AudashAIProvider.tsx',
|
|
24
|
+
'hooks/useAudashAI.ts',
|
|
25
|
+
'types/index.ts',
|
|
26
|
+
'utils/api.ts',
|
|
27
|
+
],
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
async function addCommand(component) {
|
|
31
|
+
console.log(chalk_1.default.blue.bold(`\n📦 Adding ${component}...\n`));
|
|
32
|
+
if (!COMPONENTS[component]) {
|
|
33
|
+
console.error(chalk_1.default.red(`❌ Component "${component}" not found`));
|
|
34
|
+
console.log(chalk_1.default.cyan('\nAvailable components:'));
|
|
35
|
+
Object.keys(COMPONENTS).forEach((key) => {
|
|
36
|
+
console.log(chalk_1.default.white(` - ${key}`));
|
|
37
|
+
});
|
|
38
|
+
process.exit(1);
|
|
39
|
+
}
|
|
40
|
+
const config = await (0, config_1.getConfig)();
|
|
41
|
+
if (!config) {
|
|
42
|
+
console.error(chalk_1.default.red('❌ Config not found. Run "audashai init" first'));
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
const spinner = (0, ora_1.default)('Copying files...').start();
|
|
46
|
+
try {
|
|
47
|
+
const componentConfig = COMPONENTS[component];
|
|
48
|
+
const targetDir = path_1.default.join(process.cwd(), config.componentsPath);
|
|
49
|
+
for (const file of componentConfig.files) {
|
|
50
|
+
await (0, copy_files_1.copyTemplate)(file, path_1.default.join(targetDir, file));
|
|
51
|
+
}
|
|
52
|
+
spinner.succeed('Files copied successfully');
|
|
53
|
+
console.log(chalk_1.default.green.bold('\n✅ Component added successfully!\n'));
|
|
54
|
+
console.log(chalk_1.default.cyan('Usage example:'));
|
|
55
|
+
console.log(chalk_1.default.white(`
|
|
56
|
+
import { AudashAIChatbot } from './${config.componentsPath}/components/AudashAIChatBot';
|
|
57
|
+
|
|
58
|
+
function App() {
|
|
59
|
+
return (
|
|
60
|
+
<AudashAIChatbot
|
|
61
|
+
apiKey={import.meta.env.VITE_SECRET_KEY_AUDASHAI}
|
|
62
|
+
apiUrl={import.meta.env.VITE_API_AI_AUDASHAI}
|
|
63
|
+
/>
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
`));
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
spinner.fail('Failed to add component');
|
|
70
|
+
console.error(chalk_1.default.red(error));
|
|
71
|
+
process.exit(1);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function initCommand(): Promise<void>;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.initCommand = initCommand;
|
|
7
|
+
const inquirer_1 = __importDefault(require("inquirer"));
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const ora_1 = __importDefault(require("ora"));
|
|
10
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
11
|
+
const path_1 = __importDefault(require("path"));
|
|
12
|
+
const execa_1 = require("execa");
|
|
13
|
+
async function initCommand() {
|
|
14
|
+
console.log(chalk_1.default.blue.bold('\n🚀 Initialize AudashAI in your project\n'));
|
|
15
|
+
const answers = await inquirer_1.default.prompt([
|
|
16
|
+
{
|
|
17
|
+
type: 'input',
|
|
18
|
+
name: 'componentsPath',
|
|
19
|
+
message: 'Where would you like to install components?',
|
|
20
|
+
default: 'src/components/audashai',
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
type: 'confirm',
|
|
24
|
+
name: 'installDeps',
|
|
25
|
+
message: 'Install dependencies (chart.js, react-chartjs-2)?',
|
|
26
|
+
default: true,
|
|
27
|
+
},
|
|
28
|
+
]);
|
|
29
|
+
const spinner = (0, ora_1.default)('Setting up AudashAI...').start();
|
|
30
|
+
try {
|
|
31
|
+
// Create directories
|
|
32
|
+
const componentsDir = path_1.default.join(process.cwd(), answers.componentsPath);
|
|
33
|
+
await fs_extra_1.default.ensureDir(componentsDir);
|
|
34
|
+
await fs_extra_1.default.ensureDir(path_1.default.join(componentsDir, 'context'));
|
|
35
|
+
await fs_extra_1.default.ensureDir(path_1.default.join(componentsDir, 'hooks'));
|
|
36
|
+
await fs_extra_1.default.ensureDir(path_1.default.join(componentsDir, 'types'));
|
|
37
|
+
await fs_extra_1.default.ensureDir(path_1.default.join(componentsDir, 'utils'));
|
|
38
|
+
// Create config file
|
|
39
|
+
const config = {
|
|
40
|
+
componentsPath: answers.componentsPath,
|
|
41
|
+
version: '1.0.0',
|
|
42
|
+
};
|
|
43
|
+
await fs_extra_1.default.writeJSON(path_1.default.join(process.cwd(), 'audashai.config.json'), config, { spaces: 2 });
|
|
44
|
+
spinner.succeed('Created directory structure');
|
|
45
|
+
// Install dependencies
|
|
46
|
+
if (answers.installDeps) {
|
|
47
|
+
spinner.start('Installing dependencies...');
|
|
48
|
+
await (0, execa_1.execa)('npm', ['install', 'chart.js', 'react-chartjs-2']);
|
|
49
|
+
spinner.succeed('Dependencies installed');
|
|
50
|
+
}
|
|
51
|
+
console.log(chalk_1.default.green.bold('\n✅ AudashAI initialized successfully!\n'));
|
|
52
|
+
console.log(chalk_1.default.cyan('Next steps:'));
|
|
53
|
+
console.log(chalk_1.default.white(' 1. Run: ') + chalk_1.default.yellow('audashai add chatbot'));
|
|
54
|
+
console.log(chalk_1.default.white(' 2. Import in your app'));
|
|
55
|
+
console.log(chalk_1.default.white(' 3. Configure your API keys\n'));
|
|
56
|
+
}
|
|
57
|
+
catch (error) {
|
|
58
|
+
spinner.fail('Failed to initialize');
|
|
59
|
+
console.error(chalk_1.default.red(error));
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const commander_1 = require("commander");
|
|
4
|
+
const init_1 = require("./commands/init");
|
|
5
|
+
const add_1 = require("./commands/add");
|
|
6
|
+
const program = new commander_1.Command();
|
|
7
|
+
program
|
|
8
|
+
.name('audashai')
|
|
9
|
+
.description('CLI to add AudashAI components to your project')
|
|
10
|
+
.version('1.0.0');
|
|
11
|
+
program.command('init').description('Initialize AudashAI in your project').action(init_1.initCommand);
|
|
12
|
+
program
|
|
13
|
+
.command('add <component>')
|
|
14
|
+
.description('Add a component to your project')
|
|
15
|
+
.action(add_1.addCommand);
|
|
16
|
+
program.parse();
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const AudashAIProvider_1 = require("../context/AudashAIProvider");
|
|
4
|
+
const AudashAIInput_1 = require("./AudashAIInput");
|
|
5
|
+
const AudashAIOutput_1 = require("./AudashAIOutput");
|
|
6
|
+
const AudashAIChatbot = ({ apiKey, apiUrl, dataApiUrl, endpoints, }) => {
|
|
7
|
+
return (<AudashAIProvider_1.AudashAIProvider config={{ apiKey, apiUrl, dataApiUrl, endpoints }}>
|
|
8
|
+
<div className="space-y-6 max-w-6xl mx-auto">
|
|
9
|
+
<AudashAIInput_1.AudashAIInput />
|
|
10
|
+
<AudashAIOutput_1.AudashAIOutput />
|
|
11
|
+
</div>
|
|
12
|
+
</AudashAIProvider_1.AudashAIProvider>);
|
|
13
|
+
};
|
|
14
|
+
exports.default = AudashAIChatbot;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const AudashAIInput: React.FC;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AudashAIInput = void 0;
|
|
4
|
+
const react_1 = require("react");
|
|
5
|
+
const useAudashAI_1 = require("../hooks/useAudashAI");
|
|
6
|
+
const AudashAIInput = () => {
|
|
7
|
+
const { config, setChartData, setDescData, setLoading, setErrorInfo, loading, refreshData, isRefreshing, } = (0, useAudashAI_1.useAudashAI)();
|
|
8
|
+
const [inputValue, setInputValue] = (0, react_1.useState)('');
|
|
9
|
+
const [error, setError] = (0, react_1.useState)('');
|
|
10
|
+
const handleSubmit = async () => {
|
|
11
|
+
const wordCount = inputValue.trim().split(/\s+/).length;
|
|
12
|
+
if (inputValue.trim() === '' || wordCount < 3) {
|
|
13
|
+
setError('Pesan harus terdiri dari minimal 3 kata.');
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
setLoading(true);
|
|
17
|
+
setChartData(null);
|
|
18
|
+
setDescData(null);
|
|
19
|
+
setErrorInfo(null);
|
|
20
|
+
try {
|
|
21
|
+
const response = await fetch(`${config.apiUrl}/query`, {
|
|
22
|
+
method: 'POST',
|
|
23
|
+
headers: {
|
|
24
|
+
'Content-Type': 'application/json',
|
|
25
|
+
},
|
|
26
|
+
body: JSON.stringify({
|
|
27
|
+
query: inputValue,
|
|
28
|
+
api_key: config.apiKey,
|
|
29
|
+
limit: 10,
|
|
30
|
+
}),
|
|
31
|
+
});
|
|
32
|
+
const result = await response.json();
|
|
33
|
+
if (result.response_type === 'visualization') {
|
|
34
|
+
setChartData(result.chart_config || null);
|
|
35
|
+
setDescData(null);
|
|
36
|
+
setErrorInfo(null);
|
|
37
|
+
}
|
|
38
|
+
else if (result.response_type === 'description') {
|
|
39
|
+
setDescData(result.text_response || null);
|
|
40
|
+
setChartData(null);
|
|
41
|
+
setErrorInfo(null);
|
|
42
|
+
}
|
|
43
|
+
else if (result.response_type === 'error') {
|
|
44
|
+
setChartData(null);
|
|
45
|
+
setDescData(null);
|
|
46
|
+
setErrorInfo({
|
|
47
|
+
error_type: result.processing_info?.error_type || 'unknown_error',
|
|
48
|
+
message: result.text_response || 'Terjadi kesalahan yang tidak diketahui',
|
|
49
|
+
reason: result.processing_info?.message,
|
|
50
|
+
suggestion: result.processing_info?.suggestion,
|
|
51
|
+
available_data_summary: result.processing_info?.available_data_summary,
|
|
52
|
+
documents_found: result.processing_info?.documents_found || 0,
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
catch (error) {
|
|
57
|
+
console.error('An error occurred:', error);
|
|
58
|
+
const reason = error instanceof Error
|
|
59
|
+
? error.message
|
|
60
|
+
: typeof error === 'string'
|
|
61
|
+
? error
|
|
62
|
+
: 'Network error occurred';
|
|
63
|
+
setChartData(null);
|
|
64
|
+
setDescData(null);
|
|
65
|
+
setErrorInfo({
|
|
66
|
+
error_type: 'network_error',
|
|
67
|
+
message: 'Terjadi kesalahan koneksi ke server',
|
|
68
|
+
reason,
|
|
69
|
+
suggestion: 'Silakan coba lagi dalam beberapa saat',
|
|
70
|
+
documents_found: 0,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
finally {
|
|
74
|
+
setLoading(false);
|
|
75
|
+
}
|
|
76
|
+
};
|
|
77
|
+
const handleInputChange = (event) => {
|
|
78
|
+
setInputValue(event.target.value);
|
|
79
|
+
if (error) {
|
|
80
|
+
setError('');
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
const handleKeyPress = (event) => {
|
|
84
|
+
if (event.key === 'Enter' && !event.shiftKey) {
|
|
85
|
+
event.preventDefault();
|
|
86
|
+
handleSubmit();
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
return (<div className="bg-white w-full rounded-2xl shadow-lg p-6">
|
|
90
|
+
<div className="flex justify-between items-center mb-4">
|
|
91
|
+
<h1 className="text-2xl font-bold">AudashAI Chatbot</h1>
|
|
92
|
+
{config.dataApiUrl && config.endpoints && config.endpoints.length > 0 && (<button onClick={refreshData} disabled={isRefreshing} className="border border-blue-400 px-5 py-3 text-blue-500 rounded-2xl hover:bg-blue-50 transition-colors duration-200 disabled:opacity-50 disabled:cursor-not-allowed">
|
|
93
|
+
{isRefreshing ? (<span className="flex items-center gap-2">
|
|
94
|
+
<svg className="animate-spin h-5 w-5" fill="none" viewBox="0 0 24 24">
|
|
95
|
+
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
|
|
96
|
+
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
|
97
|
+
</svg>
|
|
98
|
+
Refreshing...
|
|
99
|
+
</span>) : ('Refresh Data')}
|
|
100
|
+
</button>)}
|
|
101
|
+
</div>
|
|
102
|
+
|
|
103
|
+
<div className="flex flex-col">
|
|
104
|
+
<div className="flex gap-2">
|
|
105
|
+
<textarea rows={3} value={inputValue} onChange={handleInputChange} onKeyPress={handleKeyPress} className={`flex-grow border rounded-lg px-4 py-2 focus:outline-none focus:ring-2 ${error ? 'border-red-500 focus:ring-red-400' : 'border-gray-300 focus:ring-blue-400'}`} placeholder="Berikan perintah dengan spesifik..."/>
|
|
106
|
+
<button onClick={handleSubmit} className="bg-blue-500 text-white px-6 py-2 rounded-lg hover:bg-blue-600 disabled:bg-gray-400 cursor-pointer transition-colors duration-200" disabled={loading || !inputValue.trim()}>
|
|
107
|
+
{loading ? 'Loading...' : 'Kirim'}
|
|
108
|
+
</button>
|
|
109
|
+
</div>
|
|
110
|
+
{error && <p className="text-red-500 text-sm mt-1">{error}</p>}
|
|
111
|
+
</div>
|
|
112
|
+
</div>);
|
|
113
|
+
};
|
|
114
|
+
exports.AudashAIInput = AudashAIInput;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const AudashAIOutput: React.FC;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AudashAIOutput = void 0;
|
|
4
|
+
const useAudashAI_1 = require("../hooks/useAudashAI");
|
|
5
|
+
const BarChart_1 = require("./BarChart");
|
|
6
|
+
const ErrorDisplay_1 = require("./ErrorDisplay");
|
|
7
|
+
const LineChart_1 = require("./LineChart");
|
|
8
|
+
const AudashAIOutput = () => {
|
|
9
|
+
const { chartData, descData, loading, errorInfo } = (0, useAudashAI_1.useAudashAI)();
|
|
10
|
+
const renderContent = () => {
|
|
11
|
+
if (loading) {
|
|
12
|
+
return (<div className="w-full space-y-4">
|
|
13
|
+
<div className="animate-pulse rounded-md h-64 w-full bg-gray-200"></div>
|
|
14
|
+
<div className="animate-pulse rounded-md h-8 w-3/4 bg-gray-200"></div>
|
|
15
|
+
<div className="animate-pulse rounded-md h-8 w-1/2 bg-gray-200"></div>
|
|
16
|
+
</div>);
|
|
17
|
+
}
|
|
18
|
+
if (errorInfo) {
|
|
19
|
+
return <ErrorDisplay_1.ErrorDisplay errorInfo={errorInfo}/>;
|
|
20
|
+
}
|
|
21
|
+
if (descData) {
|
|
22
|
+
return (<div className="w-full">
|
|
23
|
+
<div className="p-6 bg-gradient-to-r from-blue-50 to-indigo-50 rounded-lg border border-blue-200">
|
|
24
|
+
<div className="flex items-start gap-3">
|
|
25
|
+
<div className="flex-shrink-0 mt-1">
|
|
26
|
+
<svg className="h-6 w-6 text-blue-600" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
27
|
+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M13 16h-1v-4h-1m1-4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
|
|
28
|
+
</svg>
|
|
29
|
+
</div>
|
|
30
|
+
<div className="flex-1">
|
|
31
|
+
<h3 className="text-lg font-semibold text-gray-800 mb-2">Hasil Analisis</h3>
|
|
32
|
+
<p className="text-slate-700 text-base leading-relaxed whitespace-pre-wrap">
|
|
33
|
+
{descData}
|
|
34
|
+
</p>
|
|
35
|
+
</div>
|
|
36
|
+
</div>
|
|
37
|
+
</div>
|
|
38
|
+
</div>);
|
|
39
|
+
}
|
|
40
|
+
if (chartData) {
|
|
41
|
+
return (<div className="w-full">
|
|
42
|
+
{chartData.visualization_type === 'bar' && (<BarChart_1.BarChart labels={chartData.labels} datasets={chartData.datasets}/>)}
|
|
43
|
+
{chartData.visualization_type === 'line' && (<LineChart_1.LineChart labels={chartData.labels} datasets={chartData.datasets}/>)}
|
|
44
|
+
</div>);
|
|
45
|
+
}
|
|
46
|
+
return (<div className="text-center text-gray-500 py-16">
|
|
47
|
+
<div className="mb-4">
|
|
48
|
+
<svg className="mx-auto h-16 w-16 text-gray-400" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
49
|
+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z"/>
|
|
50
|
+
</svg>
|
|
51
|
+
</div>
|
|
52
|
+
<h3 className="text-lg font-medium text-gray-900 mb-2">Belum Ada Data</h3>
|
|
53
|
+
<p className="text-sm text-gray-600 max-w-sm mx-auto">
|
|
54
|
+
Kirim query untuk melihat visualisasi atau deskripsi.
|
|
55
|
+
<br />
|
|
56
|
+
Mulai dengan <span className="font-semibold">"Tampilkan"</span> untuk visualisasi.
|
|
57
|
+
</p>
|
|
58
|
+
</div>);
|
|
59
|
+
};
|
|
60
|
+
return (<div className="bg-white min-h-[400px] rounded-2xl shadow-lg">
|
|
61
|
+
<div className="flex justify-center items-center h-full">
|
|
62
|
+
<div className="flex w-full items-center justify-center p-8">{renderContent()}</div>
|
|
63
|
+
</div>
|
|
64
|
+
</div>);
|
|
65
|
+
};
|
|
66
|
+
exports.AudashAIOutput = AudashAIOutput;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BarChart = void 0;
|
|
4
|
+
const react_chartjs_2_1 = require("react-chartjs-2");
|
|
5
|
+
const chart_js_1 = require("chart.js");
|
|
6
|
+
chart_js_1.Chart.register(chart_js_1.CategoryScale, chart_js_1.LinearScale, chart_js_1.PointElement, chart_js_1.LineElement, chart_js_1.BarElement, chart_js_1.Title, chart_js_1.Tooltip, chart_js_1.Legend, chart_js_1.Filler);
|
|
7
|
+
const BarChart = ({ labels, datasets }) => {
|
|
8
|
+
const options = {
|
|
9
|
+
responsive: true,
|
|
10
|
+
maintainAspectRatio: false,
|
|
11
|
+
scales: {
|
|
12
|
+
y: {
|
|
13
|
+
beginAtZero: true,
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
plugins: {
|
|
17
|
+
legend: {
|
|
18
|
+
position: 'bottom',
|
|
19
|
+
},
|
|
20
|
+
title: {
|
|
21
|
+
display: true,
|
|
22
|
+
text: 'Bar Chart',
|
|
23
|
+
position: 'bottom',
|
|
24
|
+
},
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
const barData = {
|
|
28
|
+
labels: labels,
|
|
29
|
+
datasets: datasets.map((dataset) => ({
|
|
30
|
+
label: dataset.label,
|
|
31
|
+
data: dataset.data,
|
|
32
|
+
backgroundColor: 'rgba(59, 130, 246, 0.5)',
|
|
33
|
+
borderColor: 'rgba(59, 130, 246, 1)',
|
|
34
|
+
borderWidth: 2,
|
|
35
|
+
})),
|
|
36
|
+
};
|
|
37
|
+
return (<div className="w-full h-72 flex justify-center items-center">
|
|
38
|
+
<react_chartjs_2_1.Bar options={options} data={barData}/>
|
|
39
|
+
</div>);
|
|
40
|
+
};
|
|
41
|
+
exports.BarChart = BarChart;
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ErrorDisplay = void 0;
|
|
4
|
+
const ErrorDisplay = ({ errorInfo }) => {
|
|
5
|
+
const getErrorIcon = (errorType) => {
|
|
6
|
+
switch (errorType) {
|
|
7
|
+
case 'data_not_found':
|
|
8
|
+
return (<svg className="h-12 w-12" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
9
|
+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M20 13V6a2 2 0 00-2-2H6a2 2 0 00-2 2v7m16 0v5a2 2 0 01-2 2H6a2 2 0 01-2-2v-5m16 0h-2.586a1 1 0 00-.707.293l-2.414 2.414a1 1 0 01-.707.293h-3.172a1 1 0 01-.707-.293l-2.414-2.414A1 1 0 006.586 13H4"/>
|
|
10
|
+
</svg>);
|
|
11
|
+
case 'data_not_available':
|
|
12
|
+
return (<svg className="h-12 w-12" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
13
|
+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z"/>
|
|
14
|
+
</svg>);
|
|
15
|
+
default:
|
|
16
|
+
return (<svg className="h-12 w-12" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
17
|
+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z"/>
|
|
18
|
+
</svg>);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
const getErrorColor = (errorType) => {
|
|
22
|
+
switch (errorType) {
|
|
23
|
+
case 'data_not_found':
|
|
24
|
+
return 'text-orange-600 bg-orange-50 border-orange-200';
|
|
25
|
+
case 'data_not_available':
|
|
26
|
+
return 'text-yellow-700 bg-yellow-50 border-yellow-200';
|
|
27
|
+
default:
|
|
28
|
+
return 'text-red-600 bg-red-50 border-red-200';
|
|
29
|
+
}
|
|
30
|
+
};
|
|
31
|
+
return (<div className={`w-full p-6 rounded-lg border-2 ${getErrorColor(errorInfo.error_type)}`}>
|
|
32
|
+
<div className="flex items-start gap-4">
|
|
33
|
+
<div className="flex-shrink-0">{getErrorIcon(errorInfo.error_type)}</div>
|
|
34
|
+
<div className="flex-1 space-y-3">
|
|
35
|
+
<div>
|
|
36
|
+
<h3 className="text-lg font-bold mb-1">{errorInfo.message}</h3>
|
|
37
|
+
{errorInfo.reason && (<p className="text-sm opacity-90">
|
|
38
|
+
<strong>Alasan:</strong> {errorInfo.reason}
|
|
39
|
+
</p>)}
|
|
40
|
+
</div>
|
|
41
|
+
|
|
42
|
+
{errorInfo.suggestion && (<div className="p-3 bg-white bg-opacity-50 rounded-md">
|
|
43
|
+
<p className="text-sm">
|
|
44
|
+
<strong>💡 Saran:</strong> {errorInfo.suggestion}
|
|
45
|
+
</p>
|
|
46
|
+
</div>)}
|
|
47
|
+
|
|
48
|
+
{errorInfo.available_data_summary && (<div className="p-3 bg-white bg-opacity-50 rounded-md">
|
|
49
|
+
<p className="text-sm">
|
|
50
|
+
<strong>📊 Data yang tersedia:</strong> {errorInfo.available_data_summary}
|
|
51
|
+
</p>
|
|
52
|
+
</div>)}
|
|
53
|
+
|
|
54
|
+
<div className="text-xs opacity-75">
|
|
55
|
+
<p>Dokumen ditemukan: {errorInfo.documents_found}</p>
|
|
56
|
+
</div>
|
|
57
|
+
</div>
|
|
58
|
+
</div>
|
|
59
|
+
</div>);
|
|
60
|
+
};
|
|
61
|
+
exports.ErrorDisplay = ErrorDisplay;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LineChart = void 0;
|
|
4
|
+
const react_chartjs_2_1 = require("react-chartjs-2");
|
|
5
|
+
const chart_js_1 = require("chart.js");
|
|
6
|
+
chart_js_1.Chart.register(chart_js_1.CategoryScale, chart_js_1.LinearScale, chart_js_1.PointElement, chart_js_1.LineElement, chart_js_1.Title, chart_js_1.Tooltip, chart_js_1.Legend, chart_js_1.Filler);
|
|
7
|
+
const LineChart = ({ labels, datasets }) => {
|
|
8
|
+
const options = {
|
|
9
|
+
responsive: true,
|
|
10
|
+
maintainAspectRatio: false,
|
|
11
|
+
scales: {
|
|
12
|
+
y: {
|
|
13
|
+
beginAtZero: true,
|
|
14
|
+
},
|
|
15
|
+
},
|
|
16
|
+
plugins: {
|
|
17
|
+
legend: {
|
|
18
|
+
position: 'bottom',
|
|
19
|
+
},
|
|
20
|
+
title: {
|
|
21
|
+
display: true,
|
|
22
|
+
text: 'Line Chart',
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
};
|
|
26
|
+
const lineData = {
|
|
27
|
+
labels: labels,
|
|
28
|
+
datasets: datasets.map((dataset) => ({
|
|
29
|
+
label: dataset.label,
|
|
30
|
+
data: dataset.data,
|
|
31
|
+
backgroundColor: 'rgba(16, 185, 129, 0.2)',
|
|
32
|
+
borderColor: 'rgba(16, 185, 129, 1)',
|
|
33
|
+
borderWidth: 2,
|
|
34
|
+
fill: true,
|
|
35
|
+
})),
|
|
36
|
+
};
|
|
37
|
+
return (<div className="w-full h-72 flex justify-center items-center">
|
|
38
|
+
<react_chartjs_2_1.Line data={lineData} options={options}/>
|
|
39
|
+
</div>);
|
|
40
|
+
};
|
|
41
|
+
exports.LineChart = LineChart;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const AudashAIContext: any;
|