⚖️ feat: Terms and Conditions Dialog (#3712)

* Added UI for Terms and Conditions Modal Dialogue

* Handled the logout on not accepting

* Added logic for terms acceptance

* Add terms and conditions modal

* Fixed bug on terms and conditions modal, clicking out of it won't close it now

* Added acceptance of Terms to Database

* Removed unnecessary api endpoints from index.js

* Added NPM script to reset terms acceptance

* Added translations, markdown terms and samples

* Merged terms and conditions modal feature

* feat/Modal Terms and Conditions Dialog

* Amendments as requested by maintainers

* Reset package-lock (again)
This commit is contained in:
Max Sanna 2024-08-31 22:08:04 +02:00 committed by GitHub
parent 79f9cd5a4d
commit 618be4bf2b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
35 changed files with 393 additions and 8 deletions

View file

@ -1,14 +1,18 @@
import { useState } from 'react';
import { Outlet } from 'react-router-dom';
import React, { useState, useEffect } from 'react';
import { Outlet, useNavigate } from 'react-router-dom';
import { useGetStartupConfig } from 'librechat-data-provider/react-query';
import { useUserTermsQuery } from '~/data-provider';
import type { ContextType } from '~/common';
import { useAuthContext, useAssistantsMap, useFileMap, useSearch } from '~/hooks';
import { AssistantsMapContext, FileMapContext, SearchContext } from '~/Providers';
import { Nav, MobileNav } from '~/components/Nav';
import TermsAndConditionsModal from '~/components/ui/TermsAndConditionsModal';
export default function Root() {
const { isAuthenticated } = useAuthContext();
const [navVisible, setNavVisible] = useState<boolean>(() => {
const { isAuthenticated, logout, token } = useAuthContext();
const navigate = useNavigate();
const [navVisible, setNavVisible] = useState(() => {
const savedNavVisible = localStorage.getItem('navVisible');
return savedNavVisible !== null ? JSON.parse(savedNavVisible) : true;
});
@ -17,6 +21,29 @@ export default function Root() {
const fileMap = useFileMap({ isAuthenticated });
const assistantsMap = useAssistantsMap({ isAuthenticated });
const [showTerms, setShowTerms] = useState(false);
const { data: config } = useGetStartupConfig();
const { data: termsData } = useUserTermsQuery({
enabled: isAuthenticated && !!config?.interface?.termsOfService?.modalAcceptance,
});
useEffect(() => {
if (termsData) {
setShowTerms(!termsData.termsAccepted);
}
}, [termsData]);
const handleAcceptTerms = () => {
setShowTerms(false);
};
const handleDeclineTerms = () => {
setShowTerms(false);
logout();
navigate('/login');
};
if (!isAuthenticated) {
return null;
}
@ -34,6 +61,16 @@ export default function Root() {
</div>
</div>
</div>
{config?.interface?.termsOfService?.modalAcceptance && (
<TermsAndConditionsModal
open={showTerms}
onOpenChange={setShowTerms}
onAccept={handleAcceptTerms}
onDecline={handleDeclineTerms}
title={config.interface.termsOfService.modalTitle}
modalContent={config.interface.termsOfService.modalContent}
/>
)}
</AssistantsMapContext.Provider>
</FileMapContext.Provider>
</SearchContext.Provider>