feat: Page signature-salarie adaptée pour contrats et avenants
- check-status: cherche dans cddu_contracts ET avenants
- verify-birthdate: cherche dans les deux tables
- Retourne documentType ('contrat' ou 'avenant')
- UI adaptée: AlreadySignedCard et ToSignCard affichent le type
- Titre dynamique: 'Contrat' ou 'Avenant' selon le document
- Textes adaptés: 'Voir et signer votre avenant/contrat'
This commit is contained in:
parent
3af6db788b
commit
58e8fa4584
6 changed files with 209 additions and 82 deletions
|
|
@ -4,8 +4,8 @@ import { createSbServiceRole } from '@/lib/supabaseServer';
|
|||
/**
|
||||
* GET /api/signature-salarie/check-status?docuseal_id=xxx
|
||||
*
|
||||
* Vérifie si un contrat est déjà signé par le salarié
|
||||
* Retourne les infos du contrat et l'URL de téléchargement si signé
|
||||
* Vérifie si un contrat OU un avenant est déjà signé par le salarié
|
||||
* Retourne les infos du document et l'URL de téléchargement si signé
|
||||
*/
|
||||
export async function GET(request: NextRequest) {
|
||||
console.log('=== API Check Signature Status ===');
|
||||
|
|
@ -27,9 +27,8 @@ export async function GET(request: NextRequest) {
|
|||
// Créer le client Supabase avec service role
|
||||
const supabase = createSbServiceRole();
|
||||
|
||||
// NOUVELLE APPROCHE: Chercher d'abord le contrat avec le slug dans employee_docuseal_slug
|
||||
console.log('Recherche du contrat par employee_docuseal_slug:', docuseal_id);
|
||||
|
||||
// ÉTAPE 1: Chercher d'abord dans les CONTRATS
|
||||
console.log('🔍 Recherche dans cddu_contracts...');
|
||||
const { data: contract, error: contractError } = await supabase
|
||||
.from('cddu_contracts')
|
||||
.select(`
|
||||
|
|
@ -55,37 +54,121 @@ export async function GET(request: NextRequest) {
|
|||
.eq('employee_docuseal_slug', docuseal_id)
|
||||
.maybeSingle();
|
||||
|
||||
if (contractError) {
|
||||
console.error('Erreur lors de la recherche du contrat:', contractError);
|
||||
return NextResponse.json(
|
||||
{ error: 'Erreur lors de la recherche du contrat' },
|
||||
{ status: 500 }
|
||||
);
|
||||
// ÉTAPE 2: Si pas trouvé dans contrats, chercher dans les AVENANTS
|
||||
let avenant = null;
|
||||
if (!contract) {
|
||||
console.log('🔍 Pas trouvé dans contrats, recherche dans avenants...');
|
||||
const { data: avenantData, error: avenantError } = await supabase
|
||||
.from('avenants')
|
||||
.select(`
|
||||
*,
|
||||
cddu_contracts (
|
||||
id,
|
||||
contract_number,
|
||||
employee_id,
|
||||
org_id,
|
||||
start_date,
|
||||
end_date,
|
||||
net,
|
||||
gross_pay,
|
||||
production_name,
|
||||
structure,
|
||||
profession,
|
||||
role,
|
||||
type_d_embauche,
|
||||
multi_mois
|
||||
)
|
||||
`)
|
||||
.eq('employee_docuseal_slug', docuseal_id)
|
||||
.maybeSingle();
|
||||
|
||||
if (avenantError) {
|
||||
console.error('❌ Erreur recherche avenant:', avenantError);
|
||||
} else if (avenantData) {
|
||||
console.log('✅ Avenant trouvé:', avenantData.numero_avenant);
|
||||
avenant = avenantData;
|
||||
}
|
||||
}
|
||||
|
||||
if (!contract) {
|
||||
console.error('Aucun contrat trouvé avec employee_docuseal_slug:', docuseal_id);
|
||||
// ÉTAPE 3: Si rien trouvé dans les deux tables
|
||||
if (!contract && !avenant) {
|
||||
console.error('❌ Aucun document trouvé avec employee_docuseal_slug:', docuseal_id);
|
||||
return NextResponse.json(
|
||||
{ error: 'Document introuvable' },
|
||||
{ status: 404 }
|
||||
);
|
||||
}
|
||||
|
||||
console.log('Contrat trouvé:', {
|
||||
id: contract.id,
|
||||
contract_number: contract.contract_number,
|
||||
docuseal_submission_id: contract.docuseal_submission_id
|
||||
// ÉTAPE 4: Déterminer le type de document et préparer les données
|
||||
const isAvenant = !!avenant;
|
||||
const documentType = isAvenant ? 'avenant' : 'contrat';
|
||||
console.log(`📄 Type de document: ${documentType}`);
|
||||
|
||||
let documentData: any;
|
||||
let employeeId: string;
|
||||
let orgId: string;
|
||||
let docusealSubmissionId: string | null;
|
||||
let pdfS3Key: string | null;
|
||||
let documentId: string;
|
||||
|
||||
if (isAvenant && avenant) {
|
||||
const contractData = avenant.cddu_contracts;
|
||||
documentData = {
|
||||
numero: avenant.numero_avenant,
|
||||
contract_number: contractData.contract_number,
|
||||
start_date: contractData.start_date,
|
||||
end_date: contractData.end_date,
|
||||
gross_amount: contractData.gross_pay || contractData.net || 0,
|
||||
production_name: contractData.production_name || contractData.structure,
|
||||
profession: contractData.profession || contractData.role,
|
||||
type_d_embauche: contractData.type_d_embauche,
|
||||
multi_mois: contractData.multi_mois,
|
||||
};
|
||||
employeeId = contractData.employee_id;
|
||||
orgId = contractData.org_id;
|
||||
docusealSubmissionId = avenant.docuseal_submission_id;
|
||||
pdfS3Key = avenant.pdf_s3_key;
|
||||
documentId = avenant.id;
|
||||
} else if (contract) {
|
||||
documentData = {
|
||||
numero: contract.contract_number,
|
||||
contract_number: contract.contract_number,
|
||||
start_date: contract.start_date,
|
||||
end_date: contract.end_date,
|
||||
gross_amount: contract.gross_pay || contract.net || 0,
|
||||
production_name: contract.production_name || contract.structure,
|
||||
profession: contract.profession || contract.role,
|
||||
type_d_embauche: contract.type_de_contrat,
|
||||
multi_mois: contract.multi_mois,
|
||||
};
|
||||
employeeId = contract.employee_id;
|
||||
orgId = contract.org_id;
|
||||
docusealSubmissionId = contract.docuseal_submission_id;
|
||||
pdfS3Key = contract.contract_pdf_s3_key;
|
||||
documentId = contract.id;
|
||||
} else {
|
||||
// Ne devrait jamais arriver ici car on a déjà vérifié plus haut
|
||||
return NextResponse.json(
|
||||
{ error: 'Document introuvable' },
|
||||
{ status: 404 }
|
||||
);
|
||||
}
|
||||
|
||||
console.log('📋 Document:', {
|
||||
type: documentType,
|
||||
numero: documentData.numero,
|
||||
docuseal_submission_id: docusealSubmissionId
|
||||
});
|
||||
|
||||
// Maintenant récupérer les infos de la submission DocuSeal si elle existe
|
||||
// ÉTAPE 5: Récupérer les infos de la submission DocuSeal si elle existe
|
||||
let submission: any = null;
|
||||
let employeeSubmitter: any = null;
|
||||
|
||||
if (contract.docuseal_submission_id) {
|
||||
if (docusealSubmissionId) {
|
||||
try {
|
||||
console.log('Récupération de la submission DocuSeal:', contract.docuseal_submission_id);
|
||||
console.log('🔍 Récupération de la submission DocuSeal:', docusealSubmissionId);
|
||||
const docusealResponse = await fetch(
|
||||
`${process.env.NEXT_PUBLIC_SITE_URL || 'http://localhost:3000'}/api/docuseal/submissions/${contract.docuseal_submission_id}`,
|
||||
`${process.env.NEXT_PUBLIC_SITE_URL || 'http://localhost:3000'}/api/docuseal/submissions/${docusealSubmissionId}`,
|
||||
{
|
||||
method: 'GET',
|
||||
cache: 'no-store',
|
||||
|
|
@ -94,95 +177,96 @@ export async function GET(request: NextRequest) {
|
|||
|
||||
if (docusealResponse.ok) {
|
||||
submission = await docusealResponse.json();
|
||||
console.log('Submission récupérée');
|
||||
console.log('✅ Submission récupérée');
|
||||
|
||||
// Trouver le submitter salarié avec ce slug
|
||||
const submitters = submission.submitters || [];
|
||||
employeeSubmitter = submitters.find((s: any) => s.slug === docuseal_id);
|
||||
|
||||
if (employeeSubmitter) {
|
||||
console.log('Statut signature salarié:', {
|
||||
console.log('📝 Statut signature salarié:', {
|
||||
status: employeeSubmitter.status,
|
||||
completed_at: employeeSubmitter.completed_at
|
||||
});
|
||||
}
|
||||
} else {
|
||||
console.warn('Impossible de récupérer la submission DocuSeal');
|
||||
console.warn('⚠️ Impossible de récupérer la submission DocuSeal');
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('Erreur lors de la récupération DocuSeal (non bloquant):', error);
|
||||
console.warn('⚠️ Erreur lors de la récupération DocuSeal (non bloquant):', error);
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Récupérer les infos du salarié
|
||||
// ÉTAPE 6: Récupérer les infos du salarié
|
||||
const { data: employee, error: employeeError } = await supabase
|
||||
.from('salaries')
|
||||
.select('prenom, nom, adresse_mail, date_naissance')
|
||||
.eq('id', contract.employee_id)
|
||||
.eq('id', employeeId)
|
||||
.maybeSingle();
|
||||
|
||||
if (employeeError || !employee) {
|
||||
console.error('Erreur lors de la récupération du salarié:', employeeError);
|
||||
console.error('❌ Erreur lors de la récupération du salarié:', employeeError);
|
||||
}
|
||||
|
||||
// 3. Récupérer les infos de l'organisation
|
||||
// ÉTAPE 7: Récupérer les infos de l'organisation
|
||||
const { data: organization, error: organizationError } = await supabase
|
||||
.from('organizations')
|
||||
.select('name')
|
||||
.eq('id', contract.org_id)
|
||||
.eq('id', orgId)
|
||||
.maybeSingle();
|
||||
|
||||
if (organizationError || !organization) {
|
||||
console.error('Erreur lors de la récupération de l organisation:', organizationError);
|
||||
console.error('❌ Erreur lors de la récupération de l\'organisation:', organizationError);
|
||||
}
|
||||
|
||||
// 4. Vérifier si le salarié a déjà signé
|
||||
// ÉTAPE 8: Vérifier si le salarié a déjà signé
|
||||
const isSigned = employeeSubmitter && employeeSubmitter.status === 'completed';
|
||||
console.log('Statut signature salarié:', {
|
||||
console.log('🖊️ Statut signature salarié:', {
|
||||
status: employeeSubmitter?.status,
|
||||
completed_at: employeeSubmitter?.completed_at,
|
||||
isSigned
|
||||
});
|
||||
|
||||
// 5. Si signé, récupérer l'URL de téléchargement du PDF
|
||||
// ÉTAPE 9: Si signé, récupérer l'URL de téléchargement du PDF
|
||||
let downloadUrl = null;
|
||||
if (isSigned && contract.contract_pdf_s3_key) {
|
||||
console.log('Génération URL pré-signée pour:', contract.contract_pdf_s3_key);
|
||||
if (isSigned && pdfS3Key) {
|
||||
console.log('🔗 Génération URL pré-signée pour:', pdfS3Key);
|
||||
|
||||
try {
|
||||
const { getS3SignedUrlIfExists } = await import('@/lib/aws-s3');
|
||||
downloadUrl = await getS3SignedUrlIfExists(contract.contract_pdf_s3_key, 3600);
|
||||
downloadUrl = await getS3SignedUrlIfExists(pdfS3Key, 3600);
|
||||
|
||||
if (downloadUrl) {
|
||||
console.log('URL pré-signée générée');
|
||||
console.log('✅ URL pré-signée générée');
|
||||
} else {
|
||||
console.warn('PDF non trouvé dans S3');
|
||||
console.warn('⚠️ PDF non trouvé dans S3');
|
||||
}
|
||||
} catch (s3Error) {
|
||||
console.error('Erreur lors de la génération de l URL S3:', s3Error);
|
||||
console.error('❌ Erreur lors de la génération de l\'URL S3:', s3Error);
|
||||
}
|
||||
}
|
||||
|
||||
// 6. Calculer le régime (comme dans /api/contrats/[id]/route.ts)
|
||||
const isMulti = contract.multi_mois === "Oui" || contract.multi_mois === true;
|
||||
const td = String(contract.type_d_embauche || "").toLowerCase();
|
||||
// ÉTAPE 10: Calculer le régime (comme dans /api/contrats/[id]/route.ts)
|
||||
const isMulti = documentData.multi_mois === "Oui" || documentData.multi_mois === true;
|
||||
const td = String(documentData.type_d_embauche || "").toLowerCase();
|
||||
const isRG = td.includes("régime général") || td.includes("regime general") || td === "rg";
|
||||
const regime = isRG ? "RG" : (isMulti ? "CDDU_MULTI" : "CDDU_MONO");
|
||||
|
||||
// 7. Retourner les infos
|
||||
// ÉTAPE 11: Retourner les infos
|
||||
return NextResponse.json({
|
||||
isSigned,
|
||||
documentType, // Nouveau: type de document (contrat ou avenant)
|
||||
employee_birthdate: employee?.date_naissance || null,
|
||||
contract: {
|
||||
contract_number: contract.contract_number,
|
||||
contract_number: documentData.contract_number,
|
||||
regime: regime,
|
||||
start_date: contract.start_date,
|
||||
end_date: contract.end_date,
|
||||
gross_amount: contract.gross_pay || contract.net || 0,
|
||||
start_date: documentData.start_date,
|
||||
end_date: documentData.end_date,
|
||||
gross_amount: documentData.gross_amount,
|
||||
employee_name: employee ? `${employee.prenom} ${employee.nom}` : null,
|
||||
organization_name: organization?.name || null,
|
||||
production_name: contract.production_name || contract.structure || null,
|
||||
profession: contract.profession || contract.role || null,
|
||||
production_name: documentData.production_name,
|
||||
profession: documentData.profession,
|
||||
},
|
||||
signed_at: employeeSubmitter?.completed_at || null,
|
||||
downloadUrl: isSigned ? downloadUrl : null,
|
||||
|
|
|
|||
|
|
@ -38,8 +38,8 @@ export async function POST(request: NextRequest) {
|
|||
// Créer le client Supabase avec service role
|
||||
const supabase = createSbServiceRole();
|
||||
|
||||
// NOUVELLE APPROCHE: Chercher d'abord le contrat avec le slug dans employee_docuseal_slug
|
||||
console.log('Recherche du contrat par employee_docuseal_slug:', docuseal_id);
|
||||
// ÉTAPE 1: Chercher d'abord dans les CONTRATS
|
||||
console.log('🔍 Recherche dans cddu_contracts...');
|
||||
|
||||
const { data: contract, error: contractError } = await supabase
|
||||
.from('cddu_contracts')
|
||||
|
|
@ -47,33 +47,66 @@ export async function POST(request: NextRequest) {
|
|||
.eq('employee_docuseal_slug', docuseal_id)
|
||||
.maybeSingle();
|
||||
|
||||
if (contractError) {
|
||||
console.error('Erreur lors de la recherche du contrat:', contractError);
|
||||
return NextResponse.json(
|
||||
{ error: 'Erreur lors de la recherche du contrat', verified: false },
|
||||
{ status: 500 }
|
||||
);
|
||||
// ÉTAPE 2: Si pas trouvé dans contrats, chercher dans les AVENANTS
|
||||
let avenant = null;
|
||||
let employeeId = null;
|
||||
|
||||
if (contract) {
|
||||
console.log('✅ Contrat trouvé:', {
|
||||
id: contract.id,
|
||||
employee_id: contract.employee_id,
|
||||
contract_number: contract.contract_number
|
||||
});
|
||||
employeeId = contract.employee_id;
|
||||
} else {
|
||||
console.log('🔍 Pas trouvé dans contrats, recherche dans avenants...');
|
||||
const { data: avenantData, error: avenantError } = await supabase
|
||||
.from('avenants')
|
||||
.select(`
|
||||
id,
|
||||
numero_avenant,
|
||||
employee_docuseal_slug,
|
||||
cddu_contracts!inner (
|
||||
employee_id,
|
||||
contract_number
|
||||
)
|
||||
`)
|
||||
.eq('employee_docuseal_slug', docuseal_id)
|
||||
.maybeSingle();
|
||||
|
||||
if (avenantError) {
|
||||
console.error('❌ Erreur recherche avenant:', avenantError);
|
||||
} else if (avenantData) {
|
||||
console.log('✅ Avenant trouvé:', avenantData.numero_avenant);
|
||||
avenant = avenantData;
|
||||
// cddu_contracts devient un objet unique avec !inner
|
||||
const contractData = avenantData.cddu_contracts as any;
|
||||
employeeId = contractData?.employee_id;
|
||||
}
|
||||
}
|
||||
|
||||
if (!contract) {
|
||||
console.error('Aucun contrat trouvé avec employee_docuseal_slug:', docuseal_id);
|
||||
// ÉTAPE 3: Si rien trouvé dans les deux tables
|
||||
if (!contract && !avenant) {
|
||||
console.error('❌ Aucun document trouvé avec employee_docuseal_slug:', docuseal_id);
|
||||
return NextResponse.json(
|
||||
{ error: 'Document introuvable', verified: false },
|
||||
{ status: 404 }
|
||||
);
|
||||
}
|
||||
|
||||
console.log('Contrat trouvé:', {
|
||||
id: contract.id,
|
||||
employee_id: contract.employee_id,
|
||||
contract_number: contract.contract_number
|
||||
});
|
||||
if (!employeeId) {
|
||||
console.error('❌ employee_id non trouvé');
|
||||
return NextResponse.json(
|
||||
{ error: 'Erreur de récupération du salarié', verified: false },
|
||||
{ status: 500 }
|
||||
);
|
||||
}
|
||||
|
||||
// Récupérer les infos du salarié depuis la table salaries
|
||||
const { data: salarie, error: salarieError } = await supabase
|
||||
.from('salaries')
|
||||
.select('date_naissance, prenom, nom, adresse_mail')
|
||||
.eq('id', contract.employee_id)
|
||||
.eq('id', employeeId)
|
||||
.maybeSingle();
|
||||
|
||||
if (salarieError) {
|
||||
|
|
@ -85,7 +118,7 @@ export async function POST(request: NextRequest) {
|
|||
}
|
||||
|
||||
if (!salarie) {
|
||||
console.error('Salarié introuvable pour employee_id:', contract.employee_id);
|
||||
console.error('Salarié introuvable pour employee_id:', employeeId);
|
||||
return NextResponse.json(
|
||||
{ error: 'Salarié introuvable', verified: false },
|
||||
{ status: 404 }
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ export async function POST(request: NextRequest) {
|
|||
}
|
||||
|
||||
// 3. Préparer les données pour l'email
|
||||
const signatureLink = `https://paie.odentas.fr/odentas-sign?docuseal_id=${employeeSlug}`;
|
||||
const signatureLink = `https://paie.odentas.fr/signature-salarie/?docuseal_id=${employeeSlug}`;
|
||||
|
||||
// Formater la date de manière sécurisée
|
||||
const formatDate = (dateStr?: string) => {
|
||||
|
|
|
|||
|
|
@ -16,9 +16,11 @@ interface AlreadySignedCardProps {
|
|||
};
|
||||
signed_at: string | null;
|
||||
downloadUrl: string | null;
|
||||
documentType?: 'contrat' | 'avenant'; // Nouveau: type de document
|
||||
}
|
||||
|
||||
export default function AlreadySignedCard({ contract, signed_at, downloadUrl }: AlreadySignedCardProps) {
|
||||
export default function AlreadySignedCard({ contract, signed_at, downloadUrl, documentType = 'contrat' }: AlreadySignedCardProps) {
|
||||
const documentLabel = documentType === 'avenant' ? 'Avenant' : 'Contrat';
|
||||
const formatDate = (dateString: string) => {
|
||||
const date = new Date(dateString);
|
||||
return date.toLocaleDateString('fr-FR', {
|
||||
|
|
@ -85,9 +87,9 @@ export default function AlreadySignedCard({ contract, signed_at, downloadUrl }:
|
|||
<CheckCircle2 className="w-8 h-8" />
|
||||
</div>
|
||||
<div>
|
||||
<h1 className="text-2xl font-bold">Contrat signé</h1>
|
||||
<h1 className="text-2xl font-bold">{documentLabel} signé</h1>
|
||||
<p className="text-green-50 text-sm mt-1">
|
||||
Vous avez signé électroniquement ce contrat.
|
||||
Vous avez signé électroniquement ce {documentLabel.toLowerCase()}.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -24,12 +24,14 @@ export default function SignatureSalarieContent() {
|
|||
contract: any;
|
||||
signed_at: string | null;
|
||||
downloadUrl: string | null;
|
||||
documentType?: 'contrat' | 'avenant'; // Nouveau: type de document
|
||||
} | null>(null);
|
||||
const [showSignatureModal, setShowSignatureModal] = useState(false);
|
||||
const [skipBirthdateCheck, setSkipBirthdateCheck] = useState(false);
|
||||
|
||||
// Définir le titre de la page
|
||||
usePageTitle("Signature électronique");
|
||||
// Définir le titre de la page dynamiquement
|
||||
const documentTypeLabel = signatureData?.documentType === 'avenant' ? 'Avenant' : 'Contrat';
|
||||
usePageTitle(`Signature électronique - ${documentTypeLabel}`);
|
||||
|
||||
// Vérifier si le contrat est déjà signé
|
||||
const checkSignatureStatus = async () => {
|
||||
|
|
@ -44,20 +46,22 @@ export default function SignatureSalarieContent() {
|
|||
console.log('📊 Statut reçu:', data);
|
||||
|
||||
if (data.isSigned) {
|
||||
console.log('✅ Contrat déjà signé');
|
||||
console.log('✅ Document déjà signé');
|
||||
setAlreadySigned(true);
|
||||
setSignatureData({
|
||||
contract: data.contract,
|
||||
signed_at: data.signed_at,
|
||||
downloadUrl: data.downloadUrl
|
||||
downloadUrl: data.downloadUrl,
|
||||
documentType: data.documentType || 'contrat' // Par défaut "contrat" si non spécifié
|
||||
});
|
||||
} else {
|
||||
console.log('📝 Contrat pas encore signé');
|
||||
console.log('📝 Document pas encore signé');
|
||||
setAlreadySigned(false);
|
||||
setSignatureData({
|
||||
contract: data.contract,
|
||||
signed_at: null,
|
||||
downloadUrl: null
|
||||
downloadUrl: null,
|
||||
documentType: data.documentType || 'contrat'
|
||||
});
|
||||
}
|
||||
} else {
|
||||
|
|
@ -146,6 +150,7 @@ export default function SignatureSalarieContent() {
|
|||
contract={signatureData.contract}
|
||||
signed_at={signatureData.signed_at}
|
||||
downloadUrl={signatureData.downloadUrl}
|
||||
documentType={signatureData.documentType}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
@ -157,6 +162,7 @@ export default function SignatureSalarieContent() {
|
|||
<ToSignCard
|
||||
contract={signatureData.contract}
|
||||
onSignClick={() => setShowSignatureModal(true)}
|
||||
documentType={signatureData.documentType}
|
||||
/>
|
||||
|
||||
<DocuSealSignatureModal
|
||||
|
|
|
|||
|
|
@ -15,9 +15,11 @@ interface ToSignCardProps {
|
|||
profession: string | null;
|
||||
};
|
||||
onSignClick: () => void;
|
||||
documentType?: 'contrat' | 'avenant'; // Nouveau: type de document
|
||||
}
|
||||
|
||||
export default function ToSignCard({ contract, onSignClick }: ToSignCardProps) {
|
||||
export default function ToSignCard({ contract, onSignClick, documentType = 'contrat' }: ToSignCardProps) {
|
||||
const documentLabel = documentType === 'avenant' ? 'Avenant' : 'Contrat';
|
||||
const formatDate = (dateString: string) => {
|
||||
const date = new Date(dateString);
|
||||
return date.toLocaleDateString('fr-FR', {
|
||||
|
|
@ -79,10 +81,10 @@ export default function ToSignCard({ contract, onSignClick }: ToSignCardProps) {
|
|||
<AlertCircle className="w-5 h-5 text-blue-600 flex-shrink-0 mt-0.5" />
|
||||
<div>
|
||||
<p className="text-sm font-medium text-blue-900">
|
||||
Contrat en attente de signature
|
||||
{documentLabel} en attente de signature
|
||||
</p>
|
||||
<p className="text-sm text-blue-700 mt-1">
|
||||
Merci de bien vouloir prendre connaissance du contrat et de le signer électroniquement.
|
||||
Merci de bien vouloir prendre connaissance {documentType === 'avenant' ? 'de l\'avenant' : 'du contrat'} et de le signer électroniquement.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -92,7 +94,7 @@ export default function ToSignCard({ contract, onSignClick }: ToSignCardProps) {
|
|||
<div className="space-y-4">
|
||||
<h2 className="text-lg font-semibold text-slate-900 flex items-center gap-2">
|
||||
<FileText className="w-5 h-5 text-indigo-600" />
|
||||
Détails du contrat
|
||||
Détails {documentType === 'avenant' ? 'de l\'avenant' : 'du contrat'}
|
||||
</h2>
|
||||
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 gap-4">
|
||||
|
|
@ -188,7 +190,7 @@ export default function ToSignCard({ contract, onSignClick }: ToSignCardProps) {
|
|||
className="w-full inline-flex items-center justify-center gap-3 px-6 py-4 text-base font-semibold text-white bg-gradient-to-r from-blue-600 to-indigo-600 hover:from-blue-700 hover:to-indigo-700 rounded-xl transition-all duration-200 shadow-lg hover:shadow-xl transform hover:-translate-y-0.5"
|
||||
>
|
||||
<FileSignature className="w-5 h-5" />
|
||||
Voir et signer votre contrat
|
||||
Voir et signer votre {documentLabel.toLowerCase()}
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
Loading…
Reference in a new issue