Rejoignez notre équipe d'excellence

Découvrez nos opportunités dans le conseil, l'ingénierie et l'exploitation, et contribuez à façonner la prochaine génération de solutions numériques intelligentes.

02 Postes ouverts
50+ Membres de l'équipe
100% Taux de rétention

Offres disponibles

Choisissez parmi les offres disponibles et rejoignez notre équipe

Fullstack Developer

Détails du poste:
We are looking for a Web Developer to join our team.

UI/UX Designer

Détails du poste:
We are looking for a Web Developer to join our team.

Product Designer

Détails du poste:
We are looking for a Web Developer to join our team.

UX Designer

Détails du poste:
We are looking for a Web Developer to join our team.

UI Designer

Détails du poste:
We are looking for a Web Developer to join our team.

Designer

Détails du poste:
We are looking for a Web Developer to join our team.

Pourquoi construire votre carrière avec nous ?

Hyper-croissance

Rejoignez une entreprise tech en forte expansion, impliquée dans des programmes numériques stratégiques.

Équipe internationale

Collaborez avec des ingénieurs, consultants et chefs de produit issus de plus de 10 pays.

Apprentissage continu

Accédez à des parcours de formation, du mentorat et des certifications reconnues.

Équilibre vie pro / perso

Horaires flexibles, options hybrides et initiatives bien-être.

Culture de reconnaissance

Entretiens de performance transparents et récompenses trimestrielles.

Exposition internationale

Intervenez auprès de clients en Arabie saoudite, dans le CCG, en Europe et aux États-Unis.

// Check if this is a custom job (has description but no requirements/benefits, or empty requirements/benefits) const isCustomJob = job.description && (!job.requirements || job.requirements === '') && (!job.benefits || job.benefits === ''); console.log('Creating card for job:', job.name, 'isCustomJob:', isCustomJob); // Escape HTML to prevent XSS const escapeHtml = (text) => { const div = document.createElement('div'); div.textContent = text; return div.innerHTML; }; return `

${escapeHtml(job.name)}

${isCustomJob ? `
Détails du poste:
${escapeHtml(job.description || '')}
` : `
Aperçu du poste

${escapeHtml(job.description || 'Aucune description disponible')}

Profil recherché
    ${job.requirements ? job.requirements.split('\n').map(req => `
  • ${escapeHtml(req)}
  • `).join('') : '
  • Aucune exigence spécifique
  • '}
Avantages
    ${job.benefits ? job.benefits.split('\n').map(b => `
  • ${escapeHtml(b)}
  • `).join('') : '
  • Avantages compétitifs
  • '}
`}
`; } function displayJobs(jobs) { const container = document.getElementById('jobsContainer'); console.log('=== displayJobs called ==='); console.log('Jobs to display:', jobs); console.log('Jobs count:', jobs.length); console.log('Container element:', container); if (!container) { console.error('❌ Jobs container not found!'); return; } if (!jobs || jobs.length === 0) { console.log('No jobs to display, showing empty state'); container.innerHTML = `

Aucune offre pour le moment

Revenez prochainement pour découvrir de nouvelles opportunités.

`; return; } console.log('Creating job cards...'); const jobsHTML = jobs.map((job, index) => { console.log(`Job ${index + 1}:`, job); const card = createJobCard(job); console.log(`Card ${index + 1} created, length:`, card.length); return card; }).join(''); console.log('All cards created, total HTML length:', jobsHTML.length); console.log('Setting container innerHTML...'); container.innerHTML = jobsHTML; console.log('✅ Jobs displayed successfully'); console.log('Container now has', container.children.length, 'children'); initializeJobApplicationModal(); } function showLoadingState() { document.getElementById('jobsContainer').innerHTML = `
Chargement...
Chargement des offres...

Merci de patienter

`; } function showErrorState(message) { document.getElementById('jobsContainer').innerHTML = `

Erreur lors du chargement des offres

${message}

`; } // API endpoint - assurez-vous d'ouvrir le fichier via http://localhost et non file:// const JOBS_API_URL = 'jobs_db.php'; // Vérifier si nous sommes sur HTTP et non file:// if (window.location.protocol === 'file:') { console.error('⚠️ Le fichier doit être ouvert via un serveur HTTP: http://localhost/project/careers-fr.html'); } // Charger les emplois personnalisés depuis la base de données du serveur async function loadCustomJobs() { try { console.log('Récupération des emplois depuis:', JOBS_API_URL); const response = await fetch(JOBS_API_URL); console.log('Statut de la réponse:', response.status, response.statusText); if (!response.ok) { const errorText = await response.text(); console.error('Erreur de réponse:', errorText); throw new Error(`Échec de la récupération des emplois: ${response.status} ${response.statusText}`); } const contentType = response.headers.get('content-type'); if (!contentType || !contentType.includes('application/json')) { const text = await response.text(); console.error('Type de réponse inattendu:', contentType, 'Réponse:', text); throw new Error('Format de réponse invalide du serveur'); } const jobs = await response.json(); console.log('Emplois chargés depuis le serveur:', jobs); console.log('Nombre d\'emplois:', Array.isArray(jobs) ? jobs.length : 0); // Gérer le cas où la réponse pourrait être un objet d'erreur if (jobs && jobs.error) { console.error('Le serveur a retourné une erreur:', jobs.error); return []; } return Array.isArray(jobs) ? jobs : []; } catch (error) { console.error('Erreur lors du chargement des emplois personnalisés:', error); console.error('Détails de l\'erreur:', error.message, error.stack); return []; } } // Convertir un emploi personnalisé au format standard function convertCustomJob(customJob) { return { id: customJob.id, name: customJob.name, description: customJob.description, requirements: '', benefits: '', state: 'recruit' }; } async function loadJobs() { showLoadingState(); try { // Charger les emplois personnalisés depuis la base de données du serveur const customJobs = await loadCustomJobs(); console.log('Emplois personnalisés chargés:', customJobs); const convertedCustomJobs = customJobs.map(convertCustomJob); console.log('Emplois personnalisés convertis:', convertedCustomJobs); allJobs = convertedCustomJobs; console.log('Tous les emplois:', allJobs); console.log('Total des emplois:', allJobs.length); displayJobs(allJobs); updateJobCounts(); } catch (error) { console.error('Erreur lors du chargement des emplois:', error); showErrorState('Impossible de charger les emplois depuis la base de données.'); } } function updateJobCounts() { const total = allJobs.length; const active = allJobs.filter(job => job.state === 'recruit').length; const statNumbers = document.querySelectorAll('.stat-number'); if (statNumbers.length >= 2) { statNumbers[0].textContent = `${String(active).padStart(2,'0')}`; statNumbers[1].textContent = `${total}+`; } } function initializeJobApplicationModal() { document.querySelectorAll('.btn-apply').forEach(button => { button.addEventListener('click', function () { document.getElementById('jobPosition').value = this.getAttribute('data-job'); }); }); const applyModal = document.getElementById('applyModal'); applyModal.addEventListener('hidden.bs.modal', function () { document.getElementById('jobApplicationForm').reset(); }); } document.addEventListener('DOMContentLoaded', () => { // Load jobs from server database loadJobs(); // Initialize job application modal initializeJobApplicationModal(); // Add manual refresh button functionality const refreshBtn = document.getElementById('refreshJobsBtn'); if (refreshBtn) { refreshBtn.style.display = 'inline-block'; refreshBtn.addEventListener('click', function() { this.innerHTML = 'Actualisation...'; this.disabled = true; loadJobs(); setTimeout(() => { this.innerHTML = 'Actualiser les offres'; this.disabled = false; }, 2000); }); } });
نحن نستخدم ملفات تعريف الارتباط (Cookies) لتحسين تجربتك على موقعنا. باستخدامك للموقع، فإنك توافق على استخدامنا لملفات تعريف الارتباط وفقاً لـ شروطنا وأحكامنا.