Add terms of use translations, sync detection, and refactor book components

- Introduced new translations for terms of use in French and English locales.
- Added sync status detection logic for books in `BookList` and `BookCard` components.
- Refactored `BookCard` to handle additional props and improve layout flexibility.
- Enhanced `TermsOfUse` component with complete localization support and refuse functionality.
- Updated data decryption logic in Rust services to handle optional fields and additional metadata consistently.
- Improved offline/online synchronization workflows with extended context properties.
This commit is contained in:
natreex
2026-03-23 11:56:35 -04:00
parent 64ed90d993
commit a114592ac9
23 changed files with 588 additions and 438 deletions

View File

@@ -1,19 +1,29 @@
import React from 'react';
import {ExternalLink, FileText} from 'lucide-react';
import Button from '@/components/ui/Button';
import {AppRouterInstance, Link, useRouter} from '@/lib/navigation';
import {isDesktop} from '@/lib/configs';
import * as tauri from '@/lib/tauri';
import {useTranslations} from '@/lib/i18n';
interface TermsOfUseProps {
onAccept: () => void;
}
export default function TermsOfUse({onAccept}: TermsOfUseProps) {
const router: AppRouterInstance = useRouter();
const t = useTranslations();
function handleAcceptTerm(): void {
onAccept();
}
async function handleRefuse(): Promise<void> {
if (isDesktop) {
await tauri.logout();
} else {
window.location.href = 'https://eritors.com';
}
}
return (
<div
className="fixed inset-0 z-50 bg-darkest-background/90 backdrop-blur-sm flex items-center justify-center p-6 font-['Lora']">
@@ -25,9 +35,8 @@ export default function TermsOfUse({onAccept}: TermsOfUseProps) {
<FileText className="text-primary w-6 h-6" strokeWidth={1.75}/>
</div>
<div>
<h2 className="text-text-primary font-bold text-2xl">Termes d'utilisation</h2>
<p className="text-text-secondary text-sm mt-1">Acceptation requise pour accéder à ERitors
Scribe</p>
<h2 className="text-text-primary font-bold text-2xl">{t('terms.title')}</h2>
<p className="text-text-secondary text-sm mt-1">{t('terms.subtitle')}</p>
</div>
</div>
</div>
@@ -35,33 +44,21 @@ export default function TermsOfUse({onAccept}: TermsOfUseProps) {
<div className="space-y-6">
<div className="bg-primary/5 border border-primary/20 rounded-xl p-6">
<h3 className="text-text-primary font-semibold text-lg mb-4">
Acceptation obligatoire
{t('terms.mandatory')}
</h3>
<div className="text-text-secondary text-base leading-relaxed space-y-4">
<p>
Pour pouvoir utiliser nos services, tel qu'<strong className="text-primary">ERitors
Scribe</strong>,
vous devez accepter les termes d'utilisation en cliquant
sur <strong>J'accepte</strong>.
</p>
<p>
Veuillez lire attentivement la page détaillée des termes et conditions d'utilisation
avant de procéder à l'acceptation.
</p>
<p>
Si vous n'acceptez pas ces conditions, vous ne pourrez pas accéder à nos services
et serez redirigé vers la page d'accueil.
</p>
<p dangerouslySetInnerHTML={{__html: t('terms.mandatoryDesc1')}}/>
<p>{t('terms.mandatoryDesc2')}</p>
<p>{t('terms.mandatoryDesc3')}</p>
</div>
</div>
<div className="bg-tertiary border border-secondary rounded-xl p-6">
<h3 className="text-text-primary font-semibold text-lg mb-4">
Documentation complète
{t('terms.fullDoc')}
</h3>
<p className="text-text-secondary text-base leading-relaxed mb-4">
Pour consulter l'intégralité de nos termes et conditions d'utilisation,
veuillez visiter notre page dédiée :
{t('terms.fullDocDesc')}
</p>
<a
href="/terms"
@@ -69,11 +66,11 @@ export default function TermsOfUse({onAccept}: TermsOfUseProps) {
rel="noopener noreferrer"
className="inline-flex items-center space-x-2 text-primary hover:text-primary-light transition-colors duration-200 font-medium"
>
<span>Consulter les termes complets</span>
<span>{t('terms.fullDocLink')}</span>
<ExternalLink className="w-4 h-4" strokeWidth={1.75}/>
</a>
</div>
<div className="bg-warning/10 border border-warning/30 rounded-xl p-6">
<div className="flex items-start space-x-3">
<div className="bg-warning/20 p-2 rounded-lg mt-1">
@@ -81,12 +78,10 @@ export default function TermsOfUse({onAccept}: TermsOfUseProps) {
</div>
<div>
<h4 className="text-text-primary font-semibold text-base mb-2">
Importance capitale
{t('terms.importance')}
</h4>
<p className="text-text-secondary text-sm leading-relaxed">
Cette acceptation est obligatoire et constitue un prérequis légal
pour l'utilisation de nos services d'édition assistée par intelligence
artificielle.
{t('terms.importanceDesc')}
</p>
</div>
</div>
@@ -97,18 +92,18 @@ export default function TermsOfUse({onAccept}: TermsOfUseProps) {
<div className="flex items-center justify-between">
<div className="flex items-center space-x-2 text-text-secondary text-sm">
<FileText className="text-primary w-4 h-4" strokeWidth={1.75}/>
<span>Décision requise pour continuer</span>
<span>{t('terms.required')}</span>
</div>
<div className="flex items-center space-x-4">
<Link
href="https://eritors.com"
<button
onClick={handleRefuse}
className="text-muted hover:text-text-primary px-6 py-3 rounded-xl hover:bg-secondary transition-colors duration-150 text-sm font-medium"
type="button"
>
Refuser et quitter
</Link>
{t('terms.refuse')}
</button>
<Button variant="primary" size="lg" onClick={handleAcceptTerm}>
J'accepte les termes
{t('terms.accept')}
</Button>
</div>
</div>
@@ -116,4 +111,4 @@ export default function TermsOfUse({onAccept}: TermsOfUseProps) {
</div>
</div>
);
}
}