Compare commits

..

7 Commits

Author SHA1 Message Date
600875ac73 meh 2026-08-08 09:12:52 +00:00
c0cf7f01ad fix mobile header: plain Promist image + working hamburger drawer
- Convert Promist CTA from button (.promist-btn + arrow) to a plain
  image link (.promist-link) — no button chrome, no hover transform
- Fix dead hamburger: React onClick handlers (idempotent add/remove of
  th-body-visible) on hamburger, close X, and overlay, so the drawer
  opens/closes regardless of the theme jQuery binding state
- Vertically center hamburger + Profen + Promist in one row on mobile
- Hide .menu-wrap SVG mask wings on mobile (they overlapped Promist)
- Show Promist column on mobile (d-block d-lg-none d-xl-block)
- All changes scoped to @media (max-width:767px) or the Promist link
  base styles; desktop (>=768px) untouched
2026-08-08 08:25:03 +00:00
037922795a final 2026-08-07 17:19:38 +00:00
4ccf898068 final promist link up 2026-07-23 09:43:04 +00:00
a3cb825878 mobile fixes 2026-07-21 09:52:29 +00:00
bab5f508fb most 2026-07-20 09:49:31 +00:00
5b31247e50 meh 2026-07-18 15:48:29 +00:00
22 changed files with 1276 additions and 294 deletions

3
.gitignore vendored
View File

@@ -2,3 +2,6 @@ node_modules/
dist/ dist/
.env .env
*.local *.local
CHANGES.md
deploy.yml

14
Dockerfile Normal file
View File

@@ -0,0 +1,14 @@
FROM node:22-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:22-alpine
WORKDIR /app
COPY --from=build /app/dist ./dist
RUN npm i -g serve
EXPOSE 3000
ENV NODE_ENV=production
CMD ["serve", "-s", "dist", "-l", "3000"]

View File

@@ -1,4 +1,9 @@
name: profen app: profen
type: node stack: dockerfile
start: npm run build && npx --yes -- serve -s dist -l $PORT build:
dev: ./node_modules/.bin/vite --port $PORT --host context: .
ports:
- container: 3000
host: 0
health:
path: /

View File

@@ -7,8 +7,56 @@
<link rel="preconnect" href="https://fonts.googleapis.com" /> <link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Exo:ital,wght@0,100..900;1,100..900&family=Inter:wght@100..900&display=swap" rel="stylesheet" /> <link href="https://fonts.googleapis.com/css2?family=Exo:ital,wght@0,100..900;1,100..900&family=Inter:wght@100..900&display=swap" rel="stylesheet" />
<style>
/* Preloader */
#preloader {
position: fixed;
inset: 0;
z-index: 999999;
background: #101840;
display: flex;
align-items: center;
justify-content: center;
transition: opacity 0.4s ease, visibility 0.4s ease;
}
#preloader.loaded {
opacity: 0;
visibility: hidden;
}
.preloader-inner {
text-align: center;
display: flex;
flex-direction: column;
align-items: center;
gap: 20px;
}
.preloader-logo {
height: 80px !important;
width: auto !important;
display: block;
}
.preloader-spinner {
width: 36px;
height: 36px;
border: 3px solid rgba(255, 255, 255, 0.15);
border-top: 3px solid #ED1C24;
border-radius: 50%;
box-sizing: border-box;
animation: preloader-spin 0.8s linear infinite;
}
@keyframes preloader-spin {
to { transform: rotate(360deg); }
}
</style>
</head> </head>
<body> <body>
<!-- Preloader -->
<div id="preloader">
<div class="preloader-inner">
<img src="/assets/images/logo_pe-Rd-Wh-70.png" alt="Profen" class="preloader-logo" width="249" height="80" />
<div class="preloader-spinner"></div>
</div>
</div>
<div id="root"></div> <div id="root"></div>
<script defer src="/wp-includes/js/jquery/jquery.min.js"></script> <script defer src="/wp-includes/js/jquery/jquery.min.js"></script>
<script defer src="/wp-content/themes/rakar/assets/js/bootstrap.min.js"></script> <script defer src="/wp-content/themes/rakar/assets/js/bootstrap.min.js"></script>

View File

@@ -471,6 +471,8 @@ function rakar_content_load_scripts() {
// Window Load // Window Load
$(window).on('load', function () { $(window).on('load', function () {
if (window.__rakarInit) return;
window.__rakarInit = true;
rakar_content_load_scripts(); rakar_content_load_scripts();
}); });

View File

@@ -1,3 +1,4 @@
import { useEffect } from 'react'
import { BrowserRouter, Routes, Route, Link } from 'react-router-dom' import { BrowserRouter, Routes, Route, Link } from 'react-router-dom'
import Layout from './components/Layout' import Layout from './components/Layout'
import ErrorBoundary from './components/ErrorBoundary' import ErrorBoundary from './components/ErrorBoundary'
@@ -8,6 +9,8 @@ import ServiceDetail from './pages/ServiceDetail'
import Project from './pages/Project' import Project from './pages/Project'
import Contact from './pages/Contact' import Contact from './pages/Contact'
const PAGE_LOAD = performance.now()
function NotFound() { function NotFound() {
return ( return (
<div style={{ padding: '120px 24px', textAlign: 'center' }}> <div style={{ padding: '120px 24px', textAlign: 'center' }}>
@@ -19,6 +22,20 @@ function NotFound() {
} }
export default function App() { export default function App() {
useEffect(() => {
const el = document.getElementById("preloader")
if (!el) return
const elapsed = performance.now() - PAGE_LOAD
const minShow = 1500 // ms — let user perceive the brand
const delay = Math.max(0, minShow - elapsed)
setTimeout(() => {
el.classList.add("loaded")
setTimeout(() => el.remove(), 500)
}, delay)
}, [])
return ( return (
<BrowserRouter> <BrowserRouter>
<ErrorBoundary> <ErrorBoundary>

View File

@@ -22,17 +22,19 @@ export default function WhatsAppButton() {
position: fixed; position: fixed;
bottom: 24px; bottom: 24px;
right: 24px; right: 24px;
z-index: 9999; z-index: 9999999;
width: 56px; width: 56px;
height: 56px; height: 56px;
border-radius: 50%; border-radius: 50%;
background: #ffffff; background: #ffffff;
display: flex; display: flex !important;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
box-shadow: 0 4px 12px rgba(0,0,0,0.25); box-shadow: 0 4px 12px rgba(0,0,0,0.25);
transition: transform 0.2s, box-shadow 0.2s; transition: transform 0.2s, box-shadow 0.2s;
cursor: pointer; cursor: pointer;
visibility: visible !important;
opacity: 1 !important;
} }
.whatsapp-float:hover { .whatsapp-float:hover {
transform: scale(1.08); transform: scale(1.08);
@@ -48,6 +50,23 @@ export default function WhatsAppButton() {
background: #ff3b30; background: #ff3b30;
border: 2px solid #ffffff; border: 2px solid #ffffff;
} }
@media (max-width: 767px) {
.whatsapp-float {
bottom: calc(16px + env(safe-area-inset-bottom, 0px)) !important;
right: calc(16px + env(safe-area-inset-right, 0px)) !important;
width: 52px !important;
height: 52px !important;
z-index: 9999999 !important;
display: flex !important;
visibility: visible !important;
opacity: 1 !important;
}
.whatsapp-float svg {
width: 26px !important;
height: 26px !important;
}
}
`}</style> `}</style>
</> </>
); );

View File

@@ -63,7 +63,7 @@ export default function AboutExpertise() {
<img decoding="async" src="/assets/images/choose_feature_2.svg" alt="choose_feature_2" /> <img decoding="async" src="/assets/images/choose_feature_2.svg" alt="choose_feature_2" />
</div> </div>
<h3 className="box-title"><a href="../about/index.html">OUR VISION</a></h3> <h3 className="box-title"><a href="../about/index.html">OUR VISION</a></h3>
<p className="box-text">Be a top engineering solutions provider in the UAE, known for innovation and quality.heating, and misting systems.</p> <p className="box-text">Be a top engineering solutions provider in the UAE, known for innovation and quality. Heating, and misting systems.</p>
<a href="../about/index.html" className="th-btn btn-sm th_btn"> <a href="../about/index.html" className="th-btn btn-sm th_btn">
Read More<i className="far fa-arrow-right ms-2"></i> Read More<i className="far fa-arrow-right ms-2"></i>
</a> </a>

View File

@@ -59,7 +59,7 @@ export default function AboutIntro() {
<div className="checklist"> <div className="checklist">
<ul> <ul>
<li>Professional &amp; Certified</li> <li>Professional &amp; Certified</li>
<li>Uncompromized Quality Check</li> <li>Uncompromised Quality Check</li>
</ul> </ul>
</div> </div>
</div> </div>

View File

@@ -22,9 +22,9 @@ export default function HomeClients() {
data-slider-options={JSON.stringify({ data-slider-options={JSON.stringify({
spaceBetween: 30, spaceBetween: 30,
breakpoints: { breakpoints: {
0: { slidesPerView: 1 }, 0: { slidesPerView: 3 },
576: { slidesPerView: 2 }, 576: { slidesPerView: 4 },
768: { slidesPerView: 3 }, 768: { slidesPerView: 5 },
992: { slidesPerView: 4 }, 992: { slidesPerView: 4 },
1200: { slidesPerView: 4 }, 1200: { slidesPerView: 4 },
1300: { slidesPerView: 5 }, 1300: { slidesPerView: 5 },

View File

@@ -5,7 +5,7 @@ export default function HomeHero() {
<div className="swiper th-slider" id="heroSlide5" data-slider-options={JSON.stringify({effect: "fade", autoHeight: true})}> <div className="swiper th-slider" id="heroSlide5" data-slider-options={JSON.stringify({effect: "fade", autoHeight: true})}>
<div className="swiper-wrapper"> <div className="swiper-wrapper">
<div className="swiper-slide"> <div className="swiper-slide">
<div className="hero-inner" data-bg-src="/assets/images/img-14filt.jpg"> <div className="hero-inner hero-promist" data-bg-src="/assets/images/img-14filt.jpg">
<div className="container"> <div className="container">
<div className="hero-style5"> <div className="hero-style5">
<span className="sub-title2 sub"><span className="line"></span>Welcome To Profen</span> <span className="sub-title2 sub"><span className="line"></span>Welcome To Profen</span>
@@ -15,14 +15,14 @@ export default function HomeHero() {
</h1> </h1>
<p className="hero-text">Promist is a specialized brand, dedicated to delivering innovative, high-performance misting and evaporative cooling solutions.</p> <p className="hero-text">Promist is a specialized brand, dedicated to delivering innovative, high-performance misting and evaporative cooling solutions.</p>
<div className="btn-group"> <div className="btn-group">
<Link to="/service/misting-solutions" className="th-btn rounded-12 style2 th_btn">Our All Services<i className="fas fa-arrow-right ms-2"></i></Link> <Link to="/service/misting-solutions" className="th-btn rounded-12 style2 th_btn">View the service<i className="fas fa-arrow-right ms-2"></i></Link>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div className="swiper-slide"> <div className="swiper-slide">
<div className="hero-inner" data-bg-src="/assets/images/adiabatic-cool.jpg"> <div className="hero-inner hero-heating" data-bg-src="/assets/images/adiabatic-cool.jpg">
<div className="container"> <div className="container">
<div className="hero-style5"> <div className="hero-style5">
<span className="sub-title2 sub"><span className="line"></span>Welcome To Profen</span> <span className="sub-title2 sub"><span className="line"></span>Welcome To Profen</span>
@@ -32,14 +32,14 @@ export default function HomeHero() {
</h1> </h1>
<p className="hero-text">Designed for extreme climatic conditions, PRO-SHIELD enhances system efficiency while significantly reducing energy consumption.</p> <p className="hero-text">Designed for extreme climatic conditions, PRO-SHIELD enhances system efficiency while significantly reducing energy consumption.</p>
<div className="btn-group"> <div className="btn-group">
<Link to="/service/adiabatic-pre-cooling-system" className="th-btn rounded-12 style2 th_btn">Our All Services<i className="fas fa-arrow-right ms-2"></i></Link> <Link to="/service/adiabatic-pre-cooling-system" className="th-btn rounded-12 style2 th_btn">View the service<i className="fas fa-arrow-right ms-2"></i></Link>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<div className="swiper-slide"> <div className="swiper-slide">
<div className="hero-inner" data-bg-src="/assets/images/img-13filter.jpg"> <div className="hero-inner hero-ac" data-bg-src="/assets/images/img-13filter.jpg">
<div className="container"> <div className="container">
<div className="hero-style5"> <div className="hero-style5">
<span className="sub-title2 sub"><span className="line"></span>Welcome To Profen</span> <span className="sub-title2 sub"><span className="line"></span>Welcome To Profen</span>
@@ -47,9 +47,9 @@ export default function HomeHero() {
<span className="title1">Chill Out or Heat Up</span> <span className="title1">Chill Out or Heat Up</span>
<span className="title2"><span className="text-theme">We've got Your </span> Perfect Solution</span> <span className="title2"><span className="text-theme">We've got Your </span> Perfect Solution</span>
</h1> </h1>
<p className="hero-text">Our Heat and Chill pump can be used for heating or cooling swimming pool. spa or other tank water cooling System.</p> <p className="hero-text">Our Heat and Chill pump can be used for heating or cooling swimming pool, spa or other tank water cooling system.</p>
<div className="btn-group"> <div className="btn-group">
<Link to="/service/chiller-hot-cool-solutions" className="th-btn rounded-12 style2 th_btn">Our All Services<i className="fas fa-arrow-right ms-2"></i></Link> <Link to="/service/chiller-hot-cool-solutions" className="th-btn rounded-12 style2 th_btn">View the service<i className="fas fa-arrow-right ms-2"></i></Link>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -28,8 +28,9 @@ export default function HomePartners() {
loop: true, loop: true,
speed: 800, speed: 800,
breakpoints: { breakpoints: {
0: { slidesPerView: 2 }, 0: { slidesPerView: 3 },
640: { slidesPerView: 3 }, 480: { slidesPerView: 4 },
640: { slidesPerView: 5 },
992: { slidesPerView: 5 } 992: { slidesPerView: 5 }
} }
})} })}

View File

@@ -2,9 +2,9 @@ import { Link } from "react-router-dom";
const SERVICES = [ const SERVICES = [
{ slug: "adiabatic-pre-cooling-system", title: "Adiabatic Pre-Cooling System", img: "/assets/images/img-1.jpg", icon: "/assets/images/service_block_4.svg" }, { slug: "adiabatic-pre-cooling-system", title: "Adiabatic Pre-Cooling System", img: "/assets/images/img-1.jpg", icon: "/assets/images/service_block_4.svg" },
{ slug: "misting-solutions", title: "Promist Misting Solutions", img: "/assets/images/IMG-9.jpg", icon: "/assets/images/why_feature_6.svg" }, { slug: "misting-solutions", title: "Promist Misting Solutions", img: "/assets/images/IMG-9.jpg", icon: "/assets/images/why_feature_6.svg", external: true },
{ slug: "chiller-hot-cool-solutions", title: "Chiller Hot &amp; Cool Solution", img: "/assets/images/IMG-4.jpg", icon: "/assets/images/title_icon2.svg" }, { slug: "chiller-hot-cool-solutions", title: "Chiller Hot &amp; Cool Solution", img: "/assets/images/IMG-4.jpg", icon: "/assets/images/title_icon2.svg" },
{ slug: "building-management-system", title: "Building Mngmt System", img: "/assets/images/bms.jpg", icon: "/assets/images/why_feature_2.svg" }, { slug: "building-management-system", title: "Building Management System", img: "/assets/images/bms.jpg", icon: "/assets/images/why_feature_2.svg" },
{ slug: "interior-fit-out-works", title: "Interior &amp; Fit-Out Work", img: "/assets/images/IMG-6.jpg", icon: "/assets/images/why_feature_1.svg" }, { slug: "interior-fit-out-works", title: "Interior &amp; Fit-Out Work", img: "/assets/images/IMG-6.jpg", icon: "/assets/images/why_feature_1.svg" },
{ slug: "building-contracting-works", title: "Building Contracting Works", img: "/assets/images/IMG-3.jpg", icon: "/assets/images/why_feature_3.svg" }, { slug: "building-contracting-works", title: "Building Contracting Works", img: "/assets/images/IMG-3.jpg", icon: "/assets/images/why_feature_3.svg" },
{ slug: "metal-construction-fabrications", title: "Metal Construction &amp; Fabrications", img: "/assets/images/IMG-2.jpg", icon: "/assets/images/why_feature_5.svg" }, { slug: "metal-construction-fabrications", title: "Metal Construction &amp; Fabrications", img: "/assets/images/IMG-2.jpg", icon: "/assets/images/why_feature_5.svg" },
@@ -14,18 +14,23 @@ const SERVICES = [
export default function HomeServicesSection() { export default function HomeServicesSection() {
return ( return (
<div <div
id="services"
className="elementor-element elementor-element-fb76345 e-flex e-con-boxed e-con e-parent" className="elementor-element elementor-element-fb76345 e-flex e-con-boxed e-con e-parent"
data-id="fb76345" data-id="fb76345"
data-element_type="container" data-element_type="container"
data-e-type="container" data-e-type="container"
data-settings={JSON.stringify({ background_background: "classic" })} data-settings={JSON.stringify({ background_background: "classic" })}
style={{ scrollMarginTop: 96 }}
> >
<div className="e-con-inner"> <div className="e-con-inner">
<div <div
className="elementor-element elementor-element-7f99e6d e-con-full e-flex e-con e-child" id="services"
data-id="7f99e6d" className="elementor-element elementor-element-fb76345 e-flex e-con-boxed e-con e-parent"
data-id="fb76345"
data-element_type="container" data-element_type="container"
data-e-type="container" data-e-type="container"
data-settings={JSON.stringify({ background_background: "classic" })}
style={{ scrollMarginTop: 96 }}
> >
<div <div
className="elementor-element elementor-element-5ab397b elementor-widget__width-initial elementor-widget elementor-widget-rakarsectiontitle" className="elementor-element elementor-element-5ab397b elementor-widget__width-initial elementor-widget elementor-widget-rakarsectiontitle"
@@ -44,19 +49,6 @@ export default function HomeServicesSection() {
</div> </div>
</div> </div>
</div> </div>
<div
className="elementor-element elementor-element-521e1f7 elementor-widget elementor-widget-rakarbutton"
data-id="521e1f7"
data-element_type="widget"
data-e-type="widget"
data-widget_type="rakarbutton.default"
>
<div className="elementor-widget-container">
<div className="btn-wrapper">
<Link className="th-btn th_btn style2 rounded-12" to="/contact">View All Services<i className="far fa-arrow-right"></i></Link>
</div>
</div>
</div>
</div> </div>
<div <div
className="elementor-element elementor-element-148606f elementor-widget elementor-widget-rakarservice" className="elementor-element elementor-element-148606f elementor-widget elementor-widget-rakarservice"
@@ -68,13 +60,19 @@ export default function HomeServicesSection() {
<div className="elementor-widget-container"> <div className="elementor-widget-container">
<div className="row gy-4"> <div className="row gy-4">
{SERVICES.map((s) => ( {SERVICES.map((s) => (
<div key={s.slug} className="col-xxl-3 col-lg-4 col-md-6"> <div key={s.slug} className="col-6 col-xxl-3 col-lg-4 col-md-6">
<div className="service-block"> <div className="service-block-new">
<div className="box-img"><img decoding="async" src={s.img} alt={s.title} /></div> <div className="service-media">
<Link to={`/service/${s.slug}`} className="icon-btn"><i className="far fa-arrow-up-right"></i></Link> <img className="service-bg" decoding="async" src={s.img} alt={s.title} />
<div className="box-content"> </div>
<div className="box-icon"><img decoding="async" src={s.icon} alt="" /></div> <div className="service-content">
<h3 className="box-title"><Link to={`/service/${s.slug}`}>{s.title}</Link></h3> <h3 className="service-title">
{s.external ? (
<a href="http://promist.profen.openexplorer.xyz" target="_blank" rel="noopener noreferrer">{s.title}</a>
) : (
<Link to={`/service/${s.slug}`}>{s.title}</Link>
)}
</h3>
</div> </div>
</div> </div>
</div> </div>

View File

@@ -1,30 +1,65 @@
import { useState } from 'react'
export default function ContactForm({ heading, subtitle, style = 'default' }) { export default function ContactForm({ heading, subtitle, style = 'default' }) {
const light = style === 'light' const light = style === 'light'
const wrapperClass = light const [form, setForm] = useState({ name: '', email: '', phone: '', subject: '', message: '' })
? 'input-light ajax-contact pb-30 pb-md-0'
: 'ajax-contact' const handleChange = (e) => {
setForm(prev => ({ ...prev, [e.target.name]: e.target.value }))
}
const handleSubmit = (e) => {
e.preventDefault()
const { name, email, phone, subject, message } = form
const body = encodeURIComponent(
`Name: ${name}\nEmail: ${email}\nPhone: ${phone}\nSubject: ${subject}\n\n${message}`
)
const mailto = `mailto:info@profeng.ae?subject=${encodeURIComponent(subject || 'Contact Form')}&body=${body}`
window.location.href = mailto
}
return ( return (
<div className={wrapperClass}> <div className={light ? 'input-light ajax-contact pb-30 pb-md-0' : 'ajax-contact'}>
{heading && <h2 className="sec-title">{heading}</h2>} {heading && <h2 className="sec-title">{heading}</h2>}
<div className="wpcf7 no-js" id="wpcf7-f523-p48-o1" lang="en-US" dir="ltr" data-wpcf7-id="523"> <form onSubmit={handleSubmit}>
<div className="screen-reader-response"><p role="status" aria-live="polite" aria-atomic="true"></p><ul></ul></div>
<form action="/contact" method="post" className="wpcf7-form init" aria-label="Contact form" noValidate="noValidate" data-status="init">
<div className="row"> <div className="row">
<div className="form-group col-md-6"> <div className="form-group col-md-6">
<span className="wpcf7-form-control-wrap"><input size="40" maxLength="400" className="wpcf7-form-control wpcf7-text wpcf7-validates-as-required form-control" aria-required="true" aria-invalid="false" placeholder="Your Name" type="text" name="name" /></span> <span className="wpcf7-form-control-wrap">
<input
className="wpcf7-form-control wpcf7-text wpcf7-validates-as-required form-control"
aria-required="true" placeholder="Your Name" type="text" name="name"
value={form.name} onChange={handleChange} required
/>
</span>
{light ? <i className="fas fa-user"></i> : <i className="fal fa-user"></i>} {light ? <i className="fas fa-user"></i> : <i className="fal fa-user"></i>}
</div> </div>
<div className="form-group col-md-6"> <div className="form-group col-md-6">
<span className="wpcf7-form-control-wrap"><input size="40" maxLength="400" className="wpcf7-form-control wpcf7-email wpcf7-validates-as-required wpcf7-text wpcf7-validates-as-email form-control" aria-required="true" aria-invalid="false" placeholder="Email Address" type="email" name="email" /></span> <span className="wpcf7-form-control-wrap">
<input
className="wpcf7-form-control wpcf7-email wpcf7-validates-as-required wpcf7-text wpcf7-validates-as-email form-control"
aria-required="true" placeholder="Email Address" type="email" name="email"
value={form.email} onChange={handleChange} required
/>
</span>
{light ? <i className="fas fa-envelope"></i> : <i className="fal fa-envelope"></i>} {light ? <i className="fas fa-envelope"></i> : <i className="fal fa-envelope"></i>}
</div> </div>
<div className="form-group col-md-6"> <div className="form-group col-md-6">
<span className="wpcf7-form-control-wrap"><input className="wpcf7-form-control wpcf7-number wpcf7-validates-as-required wpcf7-validates-as-number form-control" aria-required="true" aria-invalid="false" placeholder="Phone Number" type="number" name="phone" /></span> <span className="wpcf7-form-control-wrap">
<input
className="wpcf7-form-control wpcf7-number wpcf7-validates-as-required wpcf7-validates-as-number form-control"
aria-required="true" placeholder="Phone Number" type="tel" name="phone"
value={form.phone} onChange={handleChange} required
/>
</span>
{light ? <i className="fas fa-phone"></i> : <i className="fal fa-phone"></i>} {light ? <i className="fas fa-phone"></i> : <i className="fal fa-phone"></i>}
</div> </div>
<div className="form-group col-md-6"> <div className="form-group col-md-6">
<span className="wpcf7-form-control-wrap"> <span className="wpcf7-form-control-wrap">
<select className="wpcf7-form-control wpcf7-select wpcf7-validates-as-required form-select nice-select" aria-required="true" aria-invalid="false" name="subject"> <select
className="wpcf7-form-control wpcf7-select wpcf7-validates-as-required form-select nice-select"
aria-required="true" name="subject"
value={form.subject} onChange={handleChange} required
>
<option value="">Select Subject</option> <option value="">Select Subject</option>
<option value="General Query">General Query</option> <option value="General Query">General Query</option>
<option value="Help Support">Help Support</option> <option value="Help Support">Help Support</option>
@@ -34,15 +69,21 @@ export default function ContactForm({ heading, subtitle, style = 'default' }) {
{light ? <i className="fas fa-chevron-down"></i> : <i className="fal fa-chevron-down"></i>} {light ? <i className="fas fa-chevron-down"></i> : <i className="fal fa-chevron-down"></i>}
</div> </div>
<div className="form-group col-12"> <div className="form-group col-12">
<span className="wpcf7-form-control-wrap"><textarea cols="40" rows="10" maxLength="2000" className="wpcf7-form-control wpcf7-textarea wpcf7-validates-as-required form-control" aria-required="true" aria-invalid="false" placeholder="Your Message" name="message"></textarea></span> <span className="wpcf7-form-control-wrap">
<textarea
cols="40" rows="10" maxLength="2000"
className="wpcf7-form-control wpcf7-textarea wpcf7-validates-as-required form-control"
aria-required="true" placeholder="Your Message" name="message"
value={form.message} onChange={handleChange} required
></textarea>
</span>
{light ? <i className="fas fa-pencil"></i> : <i className="fal fa-pencil"></i>} {light ? <i className="fas fa-pencil"></i> : <i className="fal fa-pencil"></i>}
</div> </div>
<div className="form-btn col-12"> <div className="form-btn col-12">
<button className="th-btn">Send Message Now<i className="far fa-arrow-right ms-2"></i></button> <button className="th-btn" type="submit">Send Message Now<i className="far fa-arrow-right ms-2"></i></button>
</div> </div>
</div> </div>
</form> </form>
</div> </div>
</div>
) )
} }

View File

@@ -17,7 +17,7 @@ const CONTACT_INFO = [
const FOOTER_LINKS = [ const FOOTER_LINKS = [
{ label: 'About Profen Engineering', path: '/about' }, { label: 'About Profen Engineering', path: '/about' },
{ label: 'Our Services', path: '/service' }, { label: 'Our Services', path: '/service/electro-mechanical-works' },
{ label: 'Our Projects', path: '/project' }, { label: 'Our Projects', path: '/project' },
{ label: 'Reach Us', path: '/contact' }, { label: 'Reach Us', path: '/contact' },
] ]
@@ -97,6 +97,21 @@ export default function Footer() {
max-width:none !important; max-width:none !important;
width:100% !important; width:100% !important;
} }
.pf-footer .th-widget-about{
max-width:none !important;
}
/* ── FOOTER MOBILE RESPONSIVE ── */
@media (max-width: 991px){
.pf-footer .pf-contact-divider{ display:none !important; }
}
@media (max-width:767px){
.pf-footer .pf-contact-wrap{ flex-direction:column !important; padding:16px !important; gap:12px !important; }
.pf-footer .pf-contact-cell{ flex:none !important; width:100% !important; padding:0 !important; justify-content:flex-start !important; }
.pf-footer .pf-widgets-row{ flex-direction:column !important; padding:40px 24px 32px !important; gap:24px !important; }
.pf-footer .pf-about-col,
.pf-footer .pf-links-col{ flex:none !important; width:100% !important; }
.pf-footer .pf-copyright-inner{ text-align:center !important; }
}
`}</style> `}</style>
{/* Contact bar — white rounded card, own classes for guaranteed 3-cell centering */} {/* Contact bar — white rounded card, own classes for guaranteed 3-cell centering */}
@@ -161,6 +176,7 @@ export default function Footer() {
<div className="pf-copyright-line"> <div className="pf-copyright-line">
<div className="pf-copyright-inner"> <div className="pf-copyright-inner">
<p className="copyright-text">Copyright <i className="fas fa-copyright"></i> 2026 <a href="/">Profen Engineering LLC</a>. All Rights Reserved.</p> <p className="copyright-text">Copyright <i className="fas fa-copyright"></i> 2026 <a href="/">Profen Engineering LLC</a>. All Rights Reserved.</p>
<p className="copyright-text" style={{ color: 'rgba(255,255,255,0.7)' }}>Maintained and built by OpenXpert Solutions LLC.</p>
</div> </div>
</div> </div>
</footer> </footer>

View File

@@ -12,9 +12,9 @@ const NAV_ITEMS = [
const SERVICE_SUBITEMS = [ const SERVICE_SUBITEMS = [
{ label: 'Adiabatic Pre-Cooling System', slug: 'adiabatic-pre-cooling-system' }, { label: 'Adiabatic Pre-Cooling System', slug: 'adiabatic-pre-cooling-system' },
{ label: 'Promist Misting Solutions', slug: 'misting-solutions' }, { label: 'Promist Misting Solutions', slug: 'misting-solutions', external: true },
{ label: 'Chiller Hot & Cool Solution', slug: 'chiller-hot-cool-solutions' }, { label: 'Chiller Hot & Cool Solution', slug: 'chiller-hot-cool-solutions' },
{ label: 'Building Mngmt System', slug: 'building-management-system' }, { label: 'Building Management System', slug: 'building-management-system' },
{ label: 'Interior & Fit-Out Work', slug: 'interior-fit-out-works' }, { label: 'Interior & Fit-Out Work', slug: 'interior-fit-out-works' },
{ label: 'Building Contracting Works', slug: 'building-contracting-works' }, { label: 'Building Contracting Works', slug: 'building-contracting-works' },
{ label: 'Metal Construction & Fabrications', slug: 'metal-construction-fabrications' }, { label: 'Metal Construction & Fabrications', slug: 'metal-construction-fabrications' },
@@ -34,6 +34,15 @@ export default function Header() {
return pathname.startsWith(path) return pathname.startsWith(path)
} }
// Drawer control — idempotent add/remove so it never double-toggles
// even if the theme's jQuery thmobilemenu binding also fires.
const openMobileMenu = () => {
document.querySelector('.th-menu-wrapper')?.classList.add('th-body-visible')
}
const closeMobileMenu = () => {
document.querySelector('.th-menu-wrapper')?.classList.remove('th-body-visible')
}
return ( return (
<header ref={ref}> <header ref={ref}>
<style id="elementor-post-945" dangerouslySetInnerHTML={{ __html: ELEMENTOR_945_CSS }}></style> <style id="elementor-post-945" dangerouslySetInnerHTML={{ __html: ELEMENTOR_945_CSS }}></style>
@@ -43,11 +52,11 @@ export default function Header() {
<div className="elementor-widget-container"> <div className="elementor-widget-container">
{/* Mobile Menu */} {/* Mobile Menu */}
<div className="th-menu-wrapper"> <div className="th-menu-wrapper" onClick={closeMobileMenu}>
<div className="th-menu-area text-center"> <div className="th-menu-area text-center" onClick={(e) => e.stopPropagation()}>
<button className="th-menu-toggle"><i className="fas fa-times"></i></button> <button className="th-menu-toggle" onClick={closeMobileMenu}><i className="fas fa-times"></i></button>
<div className="mobile-logo"> <div className="mobile-logo">
<a href="/"><img alt="logo" src="/assets/images/logo_pe-Rd-Wh-001.svg" /></a> <a href="/"><img alt="logo" src="/assets/images/logo_pe-new-bk-70.png" /></a>
</div> </div>
<div className="th-mobile-menu"> <div className="th-mobile-menu">
<ul> <ul>
@@ -55,14 +64,18 @@ export default function Header() {
if (item.label === 'SERVICES') { if (item.label === 'SERVICES') {
return ( return (
<li key={item.path} className={`menu-item menu-item-type-post_type menu-item-object-page menu-item-has-children${mobileServicesOpen ? ' th-active' : ''}${pathname.startsWith('/service') ? ' current-menu-item' : ''}`}> <li key={item.path} className={`menu-item menu-item-type-post_type menu-item-object-page menu-item-has-children${mobileServicesOpen ? ' th-active' : ''}${pathname.startsWith('/service') ? ' current-menu-item' : ''}`}>
<a href="/service" onClick={(e) => { e.preventDefault(); setMobileServicesOpen(o => !o) }}> <a href="#" onClick={(e) => { e.preventDefault(); setMobileServicesOpen(o => !o) }}>
SERVICES SERVICES
<span className="th-mean-expand"></span> <span className="th-mean-expand"></span>
</a> </a>
<ul className="sub-menu" style={{ display: mobileServicesOpen ? 'block' : 'none' }}> <ul className="sub-menu" style={{ display: mobileServicesOpen ? 'block' : 'none' }}>
{SERVICE_SUBITEMS.map(s => ( {SERVICE_SUBITEMS.map(s => (
<li key={s.slug} className={`menu-item${pathname === `/service/${s.slug}` ? ' current-menu-item' : ''}`}> <li key={s.slug} className={`menu-item${pathname === `/service/${s.slug}` ? ' current-menu-item' : ''}`}>
{s.external ? (
<a href="http://promist.profen.openexplorer.xyz" target="_blank" rel="noopener noreferrer">{s.label}</a>
) : (
<Link to={`/service/${s.slug}`}>{s.label}</Link> <Link to={`/service/${s.slug}`}>{s.label}</Link>
)}
</li> </li>
))} ))}
</ul> </ul>
@@ -116,19 +129,24 @@ export default function Header() {
{/* Sticky Nav */} {/* Sticky Nav */}
<div className="sticky-wrapper"> <div className="sticky-wrapper">
<div className="container"> <div className="container px-3 px-sm-4 px-lg-0">
<div className="menu-area"> <div className="menu-area">
<div className="row align-items-start justify-content-between"> <div className="row align-items-start justify-content-between">
<div className="col-auto d-none d-lg-block"> <div className="col-auto d-none d-lg-block">
<div className="header-logo"> <div className="header-logo">
<a href="/"><img alt="logo_pe Rd Wh 70" src="/assets/images/logo_pe-Rd-Wh-70.png" /></a> <a href="/"><img alt="logo Pe Rd Wh 70" src="/assets/images/logo_pe-Rd-Wh-70.png" className="logo-top" /></a>
<a href="/"><img alt="logo_pe new bk 70" src="/assets/images/logo_pe-new-bk-70.png" className="logo-sticky" /></a>
</div> </div>
</div> </div>
<div className="col"> <div className="col">
<div className="menu-wrap"> <div className="menu-wrap">
<button className="th-menu-toggle d-block d-lg-none ms-0" type="button" onClick={openMobileMenu}><i className="far fa-bars"></i></button>
<div className="header-logo d-block d-lg-none"> <div className="header-logo d-block d-lg-none">
<a href="/"><img alt="logo_pe new bk 70" src="/assets/images/logo_pe-new-bk-70.png" /></a> <a href="/"><img alt="logo_pe new bk 70" src="/assets/images/logo_pe-new-bk-70.png" /></a>
</div> </div>
<a href="https://promist.openexplorer.xyz" target="_blank" rel="noopener noreferrer" className="promist-link d-lg-none ms-auto">
<img src="/assets/images/Promist-Logo-1.png" alt="Promist" />
</a>
<nav className="main-menu d-none d-lg-inline-block"> <nav className="main-menu d-none d-lg-inline-block">
<ul className="rakar-menu"> <ul className="rakar-menu">
{NAV_ITEMS.map(item => { {NAV_ITEMS.map(item => {
@@ -136,11 +154,15 @@ export default function Header() {
const isServiceActive = pathname.startsWith('/service') const isServiceActive = pathname.startsWith('/service')
return ( return (
<li key={item.path} className={`menu-item menu-item-type-post_type menu-item-object-page menu-item-has-children${isServiceActive ? ' current-menu-item' : ''}`}> <li key={item.path} className={`menu-item menu-item-type-post_type menu-item-object-page menu-item-has-children${isServiceActive ? ' current-menu-item' : ''}`}>
<a href="/service" onClick={e => e.preventDefault()}>SERVICES</a> <a href="#services" onClick={(e) => { e.preventDefault(); if (window.location.pathname !== '/' && !window.location.pathname.endsWith('/')) { window.location.href = '/#services'; } else { document.getElementById('services')?.scrollIntoView({ behavior: 'smooth' }); } }}>SERVICES</a>
<ul className="sub-menu"> <ul className="sub-menu">
{SERVICE_SUBITEMS.map(s => ( {SERVICE_SUBITEMS.map(s => (
<li key={s.slug} className={`menu-item${pathname === `/service/${s.slug}` ? ' current-menu-item' : ''}`}> <li key={s.slug} className={`menu-item${pathname === `/service/${s.slug}` ? ' current-menu-item' : ''}`}>
{s.external ? (
<a href="http://promist.profen.openexplorer.xyz" target="_blank" rel="noopener noreferrer">{s.label}</a>
) : (
<Link to={`/service/${s.slug}`}>{s.label}</Link> <Link to={`/service/${s.slug}`}>{s.label}</Link>
)}
</li> </li>
))} ))}
</ul> </ul>
@@ -155,14 +177,12 @@ export default function Header() {
})} })}
</ul> </ul>
</nav> </nav>
<button className="th-menu-toggle d-block d-lg-none" type="button"><i className="far fa-bars"></i></button>
</div> </div>
</div> </div>
<div className="col-auto d-none d-xl-block"> <div className="col-auto d-none d-xl-block">
<div className="header-button"> <div className="header-button">
<a className="th-btn rounded-12 th_btn promist-btn" href="/" target="_blank" rel="noopener noreferrer" style={{ background: '#fff', border: '1px solid #e0e0e0', padding: '12px 28px', display: 'inline-flex', alignItems: 'center', gap: '10px' }}> <a href="https://promist.openexplorer.xyz" target="_blank" rel="noopener noreferrer" className="promist-link">
<img src="/assets/images/Promist-Logo-1.png" alt="Promist" style={{ height: '32px' }} className="promist-logo" /> <img src="/assets/images/Promist-Logo-1.png" alt="Promist" />
<i className="fas fa-arrow-right" style={{ fontSize: '14px' }}></i>
</a> </a>
</div> </div>
</div> </div>

View File

@@ -1,158 +0,0 @@
import { Link } from "react-router-dom"
export default function ServicesHero() {
return (
<div
className="elementor-element elementor-element-e471ccf e-flex e-con-boxed e-con e-parent"
data-id="e471ccf"
data-element_type="container"
data-e-type="container"
>
<div className="e-con-inner">
{/* Section Title */}
<div
className="elementor-element elementor-element-58994a2 elementor-widget__width-initial elementor-widget elementor-widget-rakarsectiontitle"
data-id="58994a2"
data-element_type="widget"
data-e-type="widget"
data-widget_type="rakarsectiontitle.default"
>
<div className="elementor-widget-container">
<div className="title-area text-center">
<span className="sub-title">
<img decoding="async" src="/assets/images/title_icon.svg" alt="Shape" />
Our Services
</span>
<h2 className="sec-title">What Services We Offer</h2>
<p>Welcome to Rakar renovation, we provide a robust synopsis for high level overviews. Organically grow the holistic world view of disruptive innovation via workplace diversity and empowerment.</p>
</div>
</div>
</div>
{/* Service Cards Grid */}
<div
className="elementor-element elementor-element-97218ac elementor-widget elementor-widget-rakarservice"
data-id="97218ac"
data-element_type="widget"
data-e-type="widget"
data-widget_type="rakarservice.default"
>
<div className="elementor-widget-container">
<div className="row gy-4">
<div className="col-xxl-3 col-lg-4 col-md-6">
<div className="service-card">
<div className="box-number">08</div>
<div className="box-icon">
<img decoding="async" src="/assets/images/price_1_3.svg" alt="price_1_3" />
</div>
<p className="box-subtitle">Service And Repairs</p>
<h3 className="box-title"><Link to="/service/adiabatic-pre-cooling-system">Adiabatic Pre-Cooling System</Link></h3>
<p className="box-text">Designed to optimize your cooling efficiency while reducing energy consumption.</p>
<Link to="/service/adiabatic-pre-cooling-system" className="th-btn btn-sm th_btn">Read More<i className="far fa-arrow-right ms-2"></i></Link>
</div>
</div>
<div className="col-xxl-3 col-lg-4 col-md-6">
<div className="service-card">
<div className="box-number">07</div>
<div className="box-icon">
<img decoding="async" src="/assets/images/price_1_1.svg" alt="price_1_1" />
</div>
<p className="box-subtitle">Service And Repairs</p>
<h3 className="box-title"><Link to="/service/misting-solutions">Misting Solutions</Link></h3>
<p className="box-text">We specialize in providing high-performance misting solutions designed to keep you cool.</p>
<Link to="/service/misting-solutions" className="th-btn btn-sm th_btn">Read More<i className="far fa-arrow-right ms-2"></i></Link>
</div>
</div>
<div className="col-xxl-3 col-lg-4 col-md-6">
<div className="service-card">
<div className="box-number">01</div>
<div className="box-icon">
<img decoding="async" src="/assets/images/service_card_2.svg" alt="service_card_2" />
</div>
<p className="box-subtitle">Service And Repairs</p>
<h3 className="box-title"><Link to="/service/electro-mechanical-works">Electro-Mechanical Works</Link></h3>
<p className="box-text">We, at Profen, specialize in comprehensive electro-mechanical solutions,..</p>
<Link to="/service/electro-mechanical-works" className="th-btn btn-sm th_btn">Read More<i className="far fa-arrow-right ms-2"></i></Link>
</div>
</div>
<div className="col-xxl-3 col-lg-4 col-md-6">
<div className="service-card">
<div className="box-number">02</div>
<div className="box-icon">
<img decoding="async" src="/assets/images/service_grid_1.svg" alt="service_grid_1" />
</div>
<p className="box-subtitle">Service And Repairs</p>
<h3 className="box-title"><Link to="/service/landscaping-fencing-works">Landscaping &amp; Fencing</Link></h3>
<p className="box-text">Our expert team ensures exceptional design, durable materials,..</p>
<Link to="/service/landscaping-fencing-works" className="th-btn btn-sm th_btn">Read More<i className="far fa-arrow-right ms-2"></i></Link>
</div>
</div>
<div className="col-xxl-3 col-lg-4 col-md-6">
<div className="service-card">
<div className="box-number">03</div>
<div className="box-icon">
<img decoding="async" src="/assets/images/service_card_4.svg" alt="service_card_4" />
</div>
<p className="box-subtitle">Service And Repairs</p>
<h3 className="box-title"><Link to="/service/metal-construction-fabrications">Metal Construction &amp; Fabrications</Link></h3>
<p className="box-text">We ensure superior craftsmanship, strength, and reliability in every...</p>
<Link to="/service/metal-construction-fabrications" className="th-btn btn-sm th_btn">Read More<i className="far fa-arrow-right ms-2"></i></Link>
</div>
</div>
<div className="col-xxl-3 col-lg-4 col-md-6">
<div className="service-card">
<div className="box-number">04</div>
<div className="box-icon">
<img decoding="async" src="/assets/images/service_card_7.svg" alt="service_card_7" />
</div>
<p className="box-subtitle">Service And Repairs</p>
<h3 className="box-title"><Link to="/service/building-contracting-works">Building Contracting Works</Link></h3>
<p className="box-text">We provide comprehensive building contracting services, delivering..</p>
<Link to="/service/building-contracting-works" className="th-btn btn-sm th_btn">Read More<i className="far fa-arrow-right ms-2"></i></Link>
</div>
</div>
<div className="col-xxl-3 col-lg-4 col-md-6">
<div className="service-card">
<div className="box-number">05</div>
<div className="box-icon">
<img decoding="async" src="/assets/images/service_card_3.svg" alt="service_card_3" />
</div>
<p className="box-subtitle">Service And Repairs</p>
<h3 className="box-title"><Link to="/service/interior-fit-out-works">Interior &amp; Fit-Out Works</Link></h3>
<p className="box-text">You are looking to revamp a home, office, or commercial space,..</p>
<Link to="/service/interior-fit-out-works" className="th-btn btn-sm th_btn">Read More<i className="far fa-arrow-right ms-2"></i></Link>
</div>
</div>
<div className="col-xxl-3 col-lg-4 col-md-6">
<div className="service-card">
<div className="box-number">06</div>
<div className="box-icon">
<img decoding="async" src="/assets/images/service_card_8.svg" alt="service_card_8" />
</div>
<p className="box-subtitle">Service And Repairs</p>
<h3 className="box-title"><Link to="/service/chiller-hot-cool-solutions">Chiller Hot &amp; Cool Solutions</Link></h3>
<p className="box-text">We specialize in providing advanced chiller systems for both heating and cooling</p>
<Link to="/service/chiller-hot-cool-solutions" className="th-btn btn-sm th_btn">Read More<i className="far fa-arrow-right ms-2"></i></Link>
</div>
</div>
</div>
</div>
</div>
{/* Divider */}
<div
className="elementor-element elementor-element-72617d9 elementor-widget-divider--view-line elementor-widget elementor-widget-divider"
data-id="72617d9"
data-element_type="widget"
data-e-type="widget"
data-widget_type="divider.default"
>
<div className="elementor-widget-container">
<div className="elementor-divider">
<span className="elementor-divider-separator"></span>
</div>
</div>
</div>
</div>
</div>
)
}

View File

@@ -31,7 +31,7 @@ export default function Lightbox({ images, index, onClose }) {
style={{ style={{
position: 'absolute', top: 20, right: 24, position: 'absolute', top: 20, right: 24,
background: 'none', border: 'none', color: '#fff', background: 'none', border: 'none', color: '#fff',
fontSize: 32, cursor: 'pointer', zIndex: 1 fontSize: 32, cursor: "pointer", zIndex: 1, padding: "10px", lineHeight: 1
}} }}
aria-label="Close" aria-label="Close"
>&times;</button> >&times;</button>

File diff suppressed because it is too large Load Diff

View File

@@ -1,17 +1,26 @@
import { useEffect } from 'react' import { useEffect, useRef } from 'react'
import { useLocation } from 'react-router-dom'
export default function useLayoutInit() { export default function useLayoutInit() {
const { pathname } = useLocation() const initialized = useRef(false)
useEffect(() => { useEffect(() => {
// Dual guard: useRef + window.__rakarInit
// useRef protects against re-renders in same mount cycle
// window.__rakarInit protects against React 19 strict mode
// unmount/remount cycle where useRef may be reset
if (initialized.current) return
initialized.current = true
if (window.__rakarInit) return
let destroyed = false let destroyed = false
let rafId = null let rafId = null
function tryInit() { function tryInit() {
if (destroyed) return false if (destroyed) return false
if (typeof window.rakar_content_load_scripts === 'function') { if (typeof window.rakar_content_load_scripts === 'function') {
if (!window.__rakarInit) {
window.__rakarInit = true
window.rakar_content_load_scripts() window.rakar_content_load_scripts()
}
window.__layoutReady = true window.__layoutReady = true
window.dispatchEvent(new Event('layout-ready')) window.dispatchEvent(new Event('layout-ready'))
return true return true
@@ -45,5 +54,5 @@ export default function useLayoutInit() {
if (rafId) cancelAnimationFrame(rafId) if (rafId) cancelAnimationFrame(rafId)
clearTimeout(fallback) clearTimeout(fallback)
} }
}, [pathname]) }, [])
} }