class SectionIntro extends Ophose.Component {constructor(props) {super(props);} style() {return ` %self { } ` } render() {return {_: 'div', className: 'w-full h-screen select-none', style: "background-image: url('/assets/img/bg.jpg'); background-size: cover; background-position: center; relative", children: [_('div', {className: 'container mx-auto h-full flex flex-col gap-4 justify-center items-center lg:items-end text-neutral-50 text-center lg:text-right relative'} , [_('h1', {className: 'font-extrabold lg:text-9xl text-5xl drop-shadow-lg'} , 'URDEVS'),_('h2', {className: 'font-bold lg:text-4xl text-xl drop-shadow-lg'} , 'PORTFOLIO'),_('p', {className: 'lg:text-2xl text-md lg:w-1/2 w-2/3'} , 'Bienvenue sur notre portfolio. Nous sommes une équipe de développeurs passionnés par la création de sites web modernes, fonctionnels et performants.')]),_('div', {className: 'absolute w-1 h-full bg-neutral-50 top-0 opacity-25 left-96 hidden lg:block'}),_('div', {className: 'absolute h-1 w-full bg-neutral-50 bottom-64 opacity-25 left-0 hidden lg:block'}),]} } } class SectionProjects extends Ophose.Component {constructor(props) {super(props);} style() {return ` %self { } ` } render() {let _project = (title, description, img, tags, link) => {return _('a', {href: link, className: 'w-full flex flex-col gap-2 relative'} , [_('img', {className: 'w-full aspect-video object-cover rounded-2xl shadow-sm', src: img}),_('h3', {className: 'font-bold text-2xl pt-2'} , title),_('p', {className: 'text-sm'} , description),_('div', {className: 'flex gap-2'} , tags.map(tag => _('span', {className: 'rounded-full bg-neutral-100 text-neutral-500 px-2 py-1'} , tag)))])} return {_: 'div', className: 'w-full select-none bg-white overflow-hidden border-t border-neutral-200 lg:border-0', children: [_('div', {className: 'container mx-auto flex flex-col gap-8 relative py-16 lg:py-32'} , [_('img', {className: 'absolute top-0 left-0 w-1/3 object-cover opacity-50', style: "transform: translate(-25%, -60%);", src: '/assets/img/planet.png'}),_('h1', {className: 'font-extrabold text-6xl text-center'} , 'Ils nous font confiance'),_('p', {className: 'font-light text-2xl text-center'} , 'Voici quelques projets sur lesquels j\'ai travaillé.'),_('div', {className: 'grid grid-cols-1 lg:grid-cols-4 gap-4 mx-auto'} ,_('div', {className: 'lg:block hidden'}), _project('MVMT-Online', 'Plateforme de suivi personnalisé - 2024', '/assets/img/portfolio/mvmt.jpg', ['React', 'Tailwind', 'Next.js'], "https://mvmtonline.ch/"), _project('Chill-Boost', 'Site de boosting pour World of Warcraft - 2024', '/assets/img/portfolio/cb.jpg', ['React', 'Tailwind', 'Next.js'], "https://chill-boost.com"),) ])]} } } class SectionAbout extends Ophose.Component {constructor(props) {super(props);} render() {return {_: 'div', className: 'w-full bg-neutral-50 relative', children: [_('div', {className: 'py-32 container mx-auto flex flex-col gap-4 justify-center items-start text-left relative'} , [_('h1', {className: 'font-extrabold text-5xl lg:text-9xl'} , 'À PROPOS'),_('h2', {className: 'font-bold lg:text-4xl text-xl'} , 'DE NOUS'),_('p', {className: 'font-normal text-md lg:w-2/3 text-neutral-500'} , "Nous sommes une équipe de développeurs passionnés spécialisée dans la création de sites web sur mesure pour entreprises et particuliers. Nous mettons notre expertise à votre service pour concevoir des sites fonctionnels, performants et esthétiquement attrayants, tout en restant à l'écoute de vos besoins spécifiques. Notre processus transparent assure votre implication à chaque étape, de la conception à la mise en ligne, garantissant ainsi que le produit final correspond parfaitement à vos attentes. Pour toute question ou pour commencer votre projet, n'hésitez pas à nous contacter."),_('p', {className: 'font-normal text-md lg:w-2/3 text-neutral-500'} , "Nous nous engageons à utiliser les technologies les plus avancées pour garantir que votre site soit optimisé pour les moteurs de recherche et offre une expérience utilisateur de premier plan. Grâce à notre approche personnalisée, nous développons des solutions qui maximisent la visibilité et la fonctionnalité de votre site. Avec une attention particulière à la qualité et aux détails, nous assurons un suivi continu et une maintenance efficace pour que votre site reste moderne et sécurisé. Ensemble, nous transformerons vos idées en une réalité digitale performante qui dépasse vos attentes."),]),_('div', {className: 'absolute w-1 h-full bg-neutral-600 bottom-0 opacity-25 right-96 lg:block hidden'}),]} } } class SectionContact extends Ophose.Component {constructor(props) {super(props);} style() {return ` %self { } ` } render() {return {_: 'div', className: 'w-full select-none bg-neutral-900 relative', children: [_('div', {className: 'container mx-auto py-32 flex flex-col gap-4 justify-center items-center lg:items-end text-neutral-50 text-center lg:text-right relative'} , [_('h1', {className: 'font-extrabold lg:text-9xl text-4xl'} , 'CONTACT'),_('a', {href: 'mailto:contact@urdevs.ch', className: 'font-bold lg:text-4xl text-xl'} , 'contact@urdevs.ch'),_('p', {className: 'font-light lg:text-neutral-50 text-neutral-500 text-xl lg:text-2xl lg:w-1/2'} , 'Une question, un projet ? N\'hésitez pas à nous contacter. Nous sommes à votre écoute pour répondre à vos besoins.'),]),_('div', {className: 'absolute w-1 h-full bg-neutral-50 top-0 opacity-25 left-96 hidden lg:block'}),]} } } class SectionServices extends Ophose.Component {constructor(props) {super(props);} render() {let _step = (icon, title, desc, color="indigo") => {return _('div', {className: 'flex flex-col gap-2 select-none lg:text-center lg:items-center hover:scale-105 transition-transform duration-300 ease-in-out'} , [_('div', {className: `w-20 h-20 bg-${color}-500 rounded-3xl flex items-center justify-center`} ,_('a', {className: 'text-white text-3xl bi bi-' + icon})),_('h3', {className: 'text-2xl font-bold'} , title),_('p', {className: 'text-neutral-500 text-sm'} , desc),])} let _separator = () => {return _('a', {className: 'hidden lg:block bi bi-chevron-double-right text-2xl text-neutral-400 lg:mt-8'})} let _button = (text, bgColor, textColor, icon, link) => {return _('a', {href: link, className: `bg-${bgColor} text-${textColor} text-xl font-bold py-3 rounded-full text-center duration-300 ease-in-out`} , [_('span', {className: 'mr-2 bi bi-' + icon}),text ])} return {_: 'div', className: 'w-full mx-auto container py-16 flex flex-col gap-8', children: [_('h1', {className: 'text-3xl lg:text-6xl font-bold text-neutral-800 lg:w-3/4 w-full'} , 'Comment nous travaillons ?'),_('p', {className: 'text-neutral-400 text-xl lg:text-3xl lg:w-3/4'} , "La création d'un site web est un processus complexe qui nécessite une bonne compréhension de vos besoins et de vos attentes. Nous vous accompagnons tout au long de votre projet pour vous garantir un résultat à la hauteur de vos attentes."),_('div', {className: 'lg:flex lg:items-start lg:flex-row lg:justify-between gap-8 lg:w-full mx-auto lg:mx-0 grid grid-cols-2 lg:mt-4'} , [_step('tools', 'Consultation', 'Nous discuterons de votre projet, de vos besoins et de vos objectifs. Nous vous fournirons des conseils et des recommandations pour vous aider à atteindre vos objectifs.'),_separator(),_step('pencil', 'Maquettage', 'Nous créons et établissons un cahier des charges de votre projet pour avoir une idée de son apparence et de ses fonctionnalités. Vous pourrez fournir des commentaires et apporter des modifications avant la version finale.'),_separator(),_step('code', 'Développement', "Nous développerons votre projet selon les spécifications. Nous utiliserons les dernières technologies et les meilleures pratiques pour s'assurer que le projet soit rapide, fiable et sécurisé."),_separator(),_step('check2', 'Tests', "Nous testons votre projet pour s'assurer qu'il fonctionne correctement sur différentes plates-formes et appareils. Nous corrigerons les éventuels problèmes trouvés et s'assurerons que votre projet soit prêt pour le lancement."),_separator(),_step('check-circle', 'Lancement', "Nous lançons enfin votre projet et le mettrons à la disposition du public. Nous vous fournirai un soutien et une assistance pour s'assurer que votre projet soit réussi et réponde à vos attentes.", 'green')]),_('p', {className: 'text-neutral-400 text-xl w-full lg:w-3/4 mt-8'} , "Comme chaque projet est unique, il est important de discuter de vos besoins et attentes avant de commencer le développement. Nous travailerons en étroite collaboration avec vous tout au long du processus."),_('div', {className: 'grid grid-cols-1 lg:grid-cols-2 gap-8'} ,_button('Travaillons ensemble', 'black', 'white', 'envelope-fill', 'mailto:contact@urdevs.ch'),_button('En savoir plus', 'gray-100', 'black', 'info-circle-fill', '/#about')),_('p', {className: 'text-neutral-300 text-sm w-3/4'} , "*Si vous avez des questions ou avez besoin de plus d'informations, n'hésitez pas à nous contacter.")]} } } class Header extends Ophose.Component {constructor(props) {super(props);this.showed = new Live(false);} onPlace(element) {let updateBgOnScroll = () => {if (window.scrollY > 0 && !this.showed.value) {element.classList.add('bg-white', 'text-neutral-900', 'shadow-md');element.classList.remove('bg-transparent', 'text-neutral-50');} else {element.classList.add('bg-transparent', 'text-neutral-50');element.classList.remove('bg-white', 'text-neutral-900', 'shadow-md');} } window.addEventListener('scroll', updateBgOnScroll);updateBgOnScroll();this.updateBgOnScroll = updateBgOnScroll;} render() {let _responsiveMenu = () => {let showed = this.showed;let toggleBgWhite = (s) => {if(!this.getNode()) return;if(s) this.getNode().classList.remove('bg-white','text-neutral-900') else this.getNode().classList.add('bg-white', 'text-neutral-900')} return _('div', {className: 'lg:hidden'} ,_('button', {className: 'text-2xl', onclick: () => {showed.set(!showed.value);} } , '☰'),new PlacedLive(showed, (s) => {toggleBgWhite(s);if(this.updateBgOnScroll) this.updateBgOnScroll();if(s) {return _('div', {className: 'fixed z-30 w-screen h-screen top-0 left-0 relative'} ,_('div', {className: 'fixed w-full h-full top-0 left-0 bg-neutral-900 bg-opacity-90', onclick: () => showed.set(false)}),_('div', {className: 'fixed w-64 h-full top-0 left-0 bg-white text-neutral-900 text-lg z-40'} ,_('a', {onclick: () => showed.set(false), className: 'absolute top-0 right-0 p-4 cursor-pointer'} , '✕'),_('div', {className: 'w-full h-full flex flex-col gap-4 p-8 font-bold'} ,_('h2', {className: 'text-sm text-neutral-300'} , 'URDEVS - Menu'),_('a', {href: '#home'} , 'Accueil'),_('a', {href: '#services'} , 'Services'),_('a', {href: '#projects'} , 'Projets'),_('a', {href: '#about'} , 'À propos'),_('a', {href: '#contact'} , 'Contact'),_('p', {className: 'mt-auto text-sm font-normal text-neutral-400'} , '© 2024 URDEVS - Tous droits réservés')) )) } })) } return {_: 'div', className: 'fixed z-20 w-full top-0 left-0 bg-transparent text-neutral-50 transition-all duration-300 ease-in-out', children: [_('nav', {className: 'container mx-auto flex justify-between items-center py-4 text-lg'} ,_('a', {className: 'font-bold text-lg hidden lg:block drop-shadow', href: '#home'} , 'URDEVS'),_('div', {className: 'hidden lg:flex gap-4 ml-auto text-sm font-extrabold uppercase'} , [_('a', {href: '#services'} , 'Services'),_('a', {href: '#projects'} , 'Projets'),_('a', {href: '#about'} , 'À propos'),_('a', {href: '#contact'} , 'Contact')]),_responsiveMenu(),_('h1', {className: 'font-bold text-lg lg:hidden'} , 'URDEVS')) ]} } } class Footer extends Ophose.Component {constructor(props) {super(props);} style() {return ` %self { } ` } render() {return {_: 'footer', className: 'w-full bg-neutral-900 border-t border-neutral-800', children: [_('div', {className: 'container mx-auto py-16 text-neutral-50 grid grid-cols-1 lg:grid-cols-2 gap-8'} , [_('div', {className: 'flex gap-4 flex-col'} , [_('h2', {className: 'font-bold text-lg'} , 'URDEVS'),_('p', {className: 'font-light text-sm'} , '© 2024 URDEVS - Tous droits réservés'),_('p', {className: 'font-light text-sm lg:w-2/3'} , 'Nous sommes une équipe de développeurs passionnés par la création de sites web modernes, fonctionnels et performants. Nous sommes spécialisés dans la création de sites web sur mesure pour les entreprises et les particuliers. Nous sommes à l\'écoute de vos besoins et nous vous accompagnons tout au long de votre projet.'),]),_('div', {className: 'flex gap-4 flex-col lg:text-right lg:items-end'} , [_('h2', {className: 'font-bold text-lg'} , 'CONTACT'),_('p', {className: 'font-light text-sm'} , 'contact@urdevs.ch'),_('p', {className: 'font-light text-sm lg:w-2/3'} , 'Une question, un projet ? N\'hésitez pas à nous contacter. Nous sommes à votre écoute pour répondre à vos besoins.'),]),])]} ;} } class SplashScreen extends Ophose.Component {constructor(props) {super(props);this.text = new Live("Chargement");setTimeout(() => {this.remove();} , 2000) setInterval(() => {this.text.set(this.text.get() + '.');} , 500)} style() {return ` %self { position: fixed; top: 0; left: 0; width: 100%; height: 100%; display: flex; justify-content: center; align-items: center; display: flex; background-color: #f1f1f1; z-index: 9999; flex-direction: column; gap: 1rem; } %self img { width: 100px; height: 100px; object-fit: contain; } %self p { font-size: 1rem; font-weight: bold; color: #777; } ` } render() {return {_: 'div', children: [_('img', {src: '/assets/img/ud logo.png', alt: 'UD Logo'}),_('p', this.text)]} } } class SEO {static info = {} /** * Update the SEO environment * * @param {Object} newInfo the new SEO information */ static update(newInfo) {let info = {...SEO.info, ...newInfo} for (let key in info) {switch(key) {case 'title': document.title = info.callbacks.title(info.title);break;case 'description': let metaDescription = document.querySelector('meta[name="description"]');if(!metaDescription) {metaDescription = document.createElement('meta');metaDescription.name = "description";document.head.appendChild(metaDescription);} metaDescription.content = info.description;break;case 'favicon': let linkFavicon = document.querySelector('link[rel="icon"]');if(!linkFavicon) {linkFavicon = document.createElement('link');linkFavicon.rel = 'icon';linkFavicon.href = '/favicon.ico';linkFavicon.type = 'image/x-icon';linkFavicon.id = 'favicon';document.head.appendChild(linkFavicon);} linkFavicon.href = info.favicon;break;case 'lang': document.documentElement.lang = info.lang;break;case 'callbacks': if(!SEO.info.callbacks) SEO.info.callbacks = {} ;for (let callback in info.callbacks) {SEO.info.callbacks[callback] = info.callbacks[callback];} break;default: if(!project.productionMode) {console.warn(`SEO: Unknown key ${key}`);} break;} } SEO.info = info;} } SEO.update({title: "Welcome",description: "Project description",favicon: '/favicon.ico',lang: "en",callbacks: {title: (title) => title + " | " + project.name,} });oimpc('base/Header');oimpc('base/Footer');oimpc('base/SplashScreen');oimpc('@/AH4/SEO/SEO');class Base extends Ophose.Base {constructor(props) {super(props);SEO.update({title: "Développeurs freelance spécialisés dans la création de sites web",description: "Nous sommes une équipe de développeurs freelance spécialisés dans la création de sites web. Nous utilisons les dernières technologies pour vous offrir des sites web rapides, sécurisés et modernes.",}) importScript('https://cdn.tailwindcss.com');} style() {return ` @import url("https://cdn.jsdelivr.net/npm/bootstrap-icons@1.11.3/font/bootstrap-icons.min.css"); .container { padding-left: 1rem; padding-right: 1rem; } * { scroll-behavior: smooth; scroll-margin-top: 4rem; } ` } render() {return _('main',new SplashScreen(),new Header(),this.props.children,new Footer()) } }