File size: 4,150 Bytes
25f725f
 
 
 
 
 
e39f16e
25f725f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
885e104
 
1e73e88
 
 
 
25f725f
e39f16e
 
25f725f
885e104
25f725f
 
 
 
 
885e104
25f725f
 
e39f16e
25f725f
 
 
e39f16e
25f725f
 
 
 
 
 
 
 
 
e39f16e
 
25f725f
885e104
25f725f
 
 
 
 
 
 
 
 
 
 
e39f16e
25f725f
 
e39f16e
25f725f
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
import { useNavigate } from '@remix-run/react';
import React, { useState } from 'react';
import { toast } from 'react-toastify';
import { db, deleteById, getAll } from '~/lib/persistence';
import { classNames } from '~/utils/classNames';
import styles from '~/components/settings/Settings.module.scss';
import { logStore } from '~/lib/stores/logs'; // Import logStore for event logging

export default function ChatHistoryTab() {
  const navigate = useNavigate();
  const [isDeleting, setIsDeleting] = useState(false);
  const downloadAsJson = (data: any, filename: string) => {
    const blob = new Blob([JSON.stringify(data, null, 2)], { type: 'application/json' });
    const url = URL.createObjectURL(blob);
    const link = document.createElement('a');
    link.href = url;
    link.download = filename;
    document.body.appendChild(link);
    link.click();
    document.body.removeChild(link);
    URL.revokeObjectURL(url);
  };

  const handleDeleteAllChats = async () => {
    const confirmDelete = window.confirm('Are you sure you want to delete all chats? This action cannot be undone.');

    if (!confirmDelete) {
      return; // Exit if the user cancels
    }

    if (!db) {
      const error = new Error('Database is not available');
      logStore.logError('Failed to delete chats - DB unavailable', error);
      toast.error('Database is not available');

      return;
    }

    try {
      setIsDeleting(true);

      const allChats = await getAll(db);
      await Promise.all(allChats.map((chat) => deleteById(db!, chat.id)));
      logStore.logSystem('All chats deleted successfully', { count: allChats.length });
      toast.success('All chats deleted successfully');
      navigate('/', { replace: true });
    } catch (error) {
      logStore.logError('Failed to delete chats', error);
      toast.error('Failed to delete chats');
      console.error(error);
    } finally {
      setIsDeleting(false);
    }
  };

  const handleExportAllChats = async () => {
    if (!db) {
      const error = new Error('Database is not available');
      logStore.logError('Failed to export chats - DB unavailable', error);
      toast.error('Database is not available');

      return;
    }

    try {
      const allChats = await getAll(db);
      const exportData = {
        chats: allChats,
        exportDate: new Date().toISOString(),
      };

      downloadAsJson(exportData, `all-chats-${new Date().toISOString()}.json`);
      logStore.logSystem('Chats exported successfully', { count: allChats.length });
      toast.success('Chats exported successfully');
    } catch (error) {
      logStore.logError('Failed to export chats', error);
      toast.error('Failed to export chats');
      console.error(error);
    }
  };

  return (
    <>
      <div className="p-4">
        <h3 className="text-lg font-medium text-bolt-elements-textPrimary mb-4">Chat History</h3>
        <button
          onClick={handleExportAllChats}
          className={classNames(
            'bg-bolt-elements-button-primary-background',
            'rounded-lg px-4 py-2 mb-4 transition-colors duration-200',
            'hover:bg-bolt-elements-button-primary-backgroundHover',
            'text-bolt-elements-button-primary-text',
          )}
        >
          Export All Chats
        </button>

        <div
          className={classNames('text-bolt-elements-textPrimary rounded-lg py-4 mb-4', styles['settings-danger-area'])}
        >
          <h4 className="font-semibold">Danger Area</h4>
          <p className="mb-2">This action cannot be undone!</p>
          <button
            onClick={handleDeleteAllChats}
            disabled={isDeleting}
            className={classNames(
              'bg-bolt-elements-button-danger-background',
              'rounded-lg px-4 py-2 transition-colors duration-200',
              isDeleting ? 'opacity-50 cursor-not-allowed' : 'hover:bg-bolt-elements-button-danger-backgroundHover',
              'text-bolt-elements-button-danger-text',
            )}
          >
            {isDeleting ? 'Deleting...' : 'Delete All Chats'}
          </button>
        </div>
      </div>
    </>
  );
}