Compare commits

...

14 Commits

Author SHA1 Message Date
9639187067 feat: Deploy 2026-04-04 21:16:27 -05:00
cdf1c97fb8 Fix: added href link with whatsapp openner and fixed imgs to be in public routes 2026-04-04 21:15:47 -05:00
67d11380e2 Feature: added href link with a whatsapp opener with custom message 2026-04-04 21:14:58 -05:00
5c618d6663 Feature: Added custom message for whatsapp when clicking in the button 2026-04-04 21:13:21 -05:00
11ce73b5f9 Feature: added custom href to the button 2026-04-04 21:12:24 -05:00
1f88bdfe62 Fix: changed routes of images to public route 2026-04-04 21:11:10 -05:00
1a852f4f2b Fix: update images routes to public and added custom href to button linking whatsapp number 2026-04-04 21:10:25 -05:00
80f278d92b Fix: update imgs routes to public 2026-04-04 21:08:37 -05:00
1514303798 feat: Add Deploy 2026-04-04 19:45:01 -05:00
6084d6a092 Fix: added node adapter to the page 2026-04-04 19:15:15 -05:00
e9d72e4022 Update some dependencies 2026-04-04 19:06:16 -05:00
c22f5d722a fix: fixed script from lenis to smooth scrolling, moving it to body tag 2026-03-03 10:27:54 -05:00
ff26e3c329 Clean comments 2026-02-25 00:20:24 -05:00
2b694b2198 Merge pull request 'feat: implement email functionality for contact form' (#2) from SendEmailFeature into main
Reviewed-on: #2
2026-02-25 00:03:39 -05:00
18 changed files with 5136 additions and 5163 deletions

27
Dockerfile Normal file
View File

@@ -0,0 +1,27 @@
FROM node:22-alpine AS build
WORKDIR /web
COPY package.json ./
RUN npm install
COPY . .
RUN npm run build
FROM node:22-alpine AS runtime
WORKDIR /app
# Copiar archivos generados y dependencias necesarias
COPY --from=build /web/dist ./dist
COPY --from=build /web/node_modules ./node_modules
COPY --from=build /web/package.json ./package.json
# Configuración de red interna de Docker
ENV HOST=0.0.0.0
ENV PORT=4321
EXPOSE 4321
CMD ["node", "./dist/server/entry.mjs"]

View File

@@ -1,5 +1,13 @@
// @ts-check
import { defineConfig } from 'astro/config';
import { defineConfig } from "astro/config";
import node from "@astrojs/node";
// https://astro.build/config
export default defineConfig({});
export default defineConfig({
output: "server",
adapter: node({
mode: "standalone",
}),
});

5
docker-compose.yaml Normal file
View File

@@ -0,0 +1,5 @@
services:
web:
build:
context: .
dockerfile: Dockerfile

15
nginx.conf Normal file
View File

@@ -0,0 +1,15 @@
server {
listen 80;
server_name localhost;
location / {
root /usr/share/nginx/html;
index index.html index.htm;
try_files $uri $uri/ /index.html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root /usr/share/nginx/html;
}
}

10039
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,19 +1,20 @@
{
"name": "naliia-website",
"type": "module",
"version": "0.0.1",
"scripts": {
"dev": "astro dev",
"build": "astro build",
"preview": "astro preview",
"astro": "astro"
},
"dependencies": {
"astro": "^5.17.1",
"lenis": "^1.3.17",
"nodemailer": "^8.0.1"
},
"devDependencies": {
"@types/nodemailer": "^7.0.11"
}
"name": "naliia-website",
"type": "module",
"version": "0.0.1",
"scripts": {
"dev": "astro dev",
"build": "astro build",
"preview": "astro preview",
"astro": "astro"
},
"dependencies": {
"@astrojs/node": "^10.0.4",
"astro": "^6.1.3",
"lenis": "^1.3.17",
"nodemailer": "^8.0.1"
},
"devDependencies": {
"@types/nodemailer": "^7.0.11"
}
}

View File

Before

Width:  |  Height:  |  Size: 323 KiB

After

Width:  |  Height:  |  Size: 323 KiB

View File

Before

Width:  |  Height:  |  Size: 5.5 KiB

After

Width:  |  Height:  |  Size: 5.5 KiB

View File

Before

Width:  |  Height:  |  Size: 1.3 MiB

After

Width:  |  Height:  |  Size: 1.3 MiB

View File

Before

Width:  |  Height:  |  Size: 335 KiB

After

Width:  |  Height:  |  Size: 335 KiB

View File

@@ -11,6 +11,7 @@ export interface SectionProps {
mainTitle: string;
subtitle: string;
buttonText?: string;
customHref?: string;
autoHeight?: boolean;
}
@@ -27,6 +28,7 @@ const {
customXPosition,
customYPosition,
autoHeight = false,
customHref
} = Astro.props as SectionProps;
---
@@ -56,13 +58,9 @@ const {
{
buttonText && (
<div class="button-container">
<a href="#">
<button class="button call-to-action-button importantButton-hover-animation">
{buttonText}
</button>
<a href={customHref ? customHref : "#"} target="_blank" class="call-to-action-button">
{buttonText}
</a>
</div>
)
}
</div>
@@ -219,7 +217,7 @@ const {
.call-to-action-button {
height: 56px;
width: auto;
width: fit-content;
padding: var(--space-sm-8px) var(--space-lg-24px);
border: none;
border-radius: 16px;
@@ -232,10 +230,12 @@ const {
justify-content: center;
color: white;
cursor: pointer;
animation: fadeAndMoveFromLeft 1s ease-in-out forwards;
transition:
translate 1s ease-in-out,
opacity 1s ease-in-out;
opacity 1s ease-in-out,
transform 3s ease-in-out,
@media (max-width: 1023px) {
padding: var(--padding-sm-8px) var(--padding-lg-24px);
@@ -250,6 +250,7 @@ const {
}
.call-to-action-button:hover {
animation: heartBeat 1.2s infinite;
background-color: #d9436a;
transform: scale(1.02);
}
</style>

View File

@@ -1,6 +1,6 @@
---
export interface PricingCardProps {
planType: string;
planType: "basic" | "intermediate" | "advanced";
price: string;
description: string;
featuresTitle: string;
@@ -20,11 +20,38 @@ const {
isBestPlan,
class: className,
} = Astro.props as PricingCardProps;
function getPlanTypeText(planType: "basic" | "intermediate" | "advanced") {
switch (planType) {
case "basic":
return "Básico";
case "intermediate":
return "Intermedio";
case "advanced":
return "Avanzado";
default:
return planType;
}
}
function getPlanWhatsappMessage(planType: "basic" | "intermediate" | "advanced") {
switch (planType) {
case "basic":
return "Hola, estoy interesado en el Plan Básico de Naliia. ¿Podrían brindarme más información sobre este plan y cómo puedo adquirirlo?";
case "intermediate":
return "Hola, estoy interesado en el Plan Intermedio de Naliia. ¿Podrían brindarme más información sobre este plan y cómo puedo adquirirlo?";
case "advanced":
return "Hola, estoy interesado en el Plan Avanzado de Naliia. ¿Podrían brindarme más información sobre este plan y cómo puedo adquirirlo?";
default:
return "Hola, estoy interesado en uno de los planes de Naliia. ¿Podrían brindarme más información sobre los planes y cómo puedo adquirirlos?";
}
}
---
<div class:list={["pricing-card", className]} data-best-plan={isBestPlan}>
<div class="pricing-card-header">
<p class="plan-type">{`Plan ${planType}`}</p>
<p class="plan-type">{`Plan ${getPlanTypeText(planType)}`}</p>
<div class="price-and-description">
<h4 class="price">{price}</h4>
@@ -47,8 +74,8 @@ const {
</div>
</div>
<button class="button call-to-action-button button-hover-effect"
>{buttonText}</button
<a href={`https://wa.me/573001158180?text=${encodeURIComponent(getPlanWhatsappMessage(planType))}`} target="_blank" class="button call-to-action-button button-hover-effect"
>{buttonText}</a
>
</div>

View File

@@ -132,7 +132,7 @@ import "./footer.css";
<div class="social-media">
<div class="icons-social-media">
<a href="#" class="social-media-link whatsapp-link">
<a href="https://wa.me/573001158180?text=Hola,%20estoy%20interesado%20en%20obtener%20más%20información%20sobre%20Naliia." class="social-media-link whatsapp-link" target="_blank">
<svg
xmlns="http://www.w3.org/2000/svg"
width="28"
@@ -152,7 +152,7 @@ import "./footer.css";
>
</a>
<a href="" class="social-media-link instagram-link">
<!-- <a href="" class="social-media-link instagram-link">
<svg
xmlns="http://www.w3.org/2000/svg"
width="28"
@@ -164,9 +164,9 @@ import "./footer.css";
d="M7.8 2h8.4C19.4 2 22 4.6 22 7.8v8.4a5.8 5.8 0 0 1-5.8 5.8H7.8C4.6 22 2 19.4 2 16.2V7.8A5.8 5.8 0 0 1 7.8 2m-.2 2A3.6 3.6 0 0 0 4 7.6v8.8C4 18.39 5.61 20 7.6 20h8.8a3.6 3.6 0 0 0 3.6-3.6V7.6C20 5.61 18.39 4 16.4 4zm9.65 1.5a1.25 1.25 0 0 1 1.25 1.25A1.25 1.25 0 0 1 17.25 8A1.25 1.25 0 0 1 16 6.75a1.25 1.25 0 0 1 1.25-1.25M12 7a5 5 0 0 1 5 5a5 5 0 0 1-5 5a5 5 0 0 1-5-5a5 5 0 0 1 5-5m0 2a3 3 0 0 0-3 3a3 3 0 0 0 3 3a3 3 0 0 0 3-3a3 3 0 0 0-3-3"
></path></svg
>
</a>
</a> -->
<a href="#" class="social-media-link email-link">
<a href="mailto:proyectos@ausolutionsit.com" class="social-media-link email-link">
<svg
xmlns="http://www.w3.org/2000/svg"
width="28"

View File

@@ -24,6 +24,11 @@ const { pageTitle } = Astro.props;
<link rel="icon" href="/favicon.ico" />
<meta name="generator" content={Astro.generator} />
<title>{pageTitle ? `Naliia | ${pageTitle}` : "Naliia"}</title>
<link
rel="stylesheet"
href="https://unpkg.com/lenis@1.3.17/dist/lenis.css"
/>
</head>
<body>
@@ -33,7 +38,7 @@ const { pageTitle } = Astro.props;
<main>
<div class="floating-buttons">
<a href="#">
<a href="https://wa.me/573001158180?text=Hola,%20estoy%20interesado%20en%20obtener%20más%20información%20sobre%20Naliia." target="_blank">
<div class="floating-button whatsapp-floatingbutton">
<svg
xmlns="http://www.w3.org/2000/svg"
@@ -86,6 +91,22 @@ const { pageTitle } = Astro.props;
<footer class="footer">
<Footer />
</footer>
<script>
import Lenis from "lenis";
const lenis = new Lenis({
touchMultiplier: 2,
infinite: false,
});
function raf(time: number) {
lenis.raf(time);
requestAnimationFrame(raf);
}
requestAnimationFrame(raf);
</script>
</body>
</html>
@@ -100,47 +121,7 @@ const { pageTitle } = Astro.props;
}
</script>
<script>
import Lenis from "lenis";
// Inicialización de Lenis
const lenis = new Lenis({
duration: 1.2,
easing: (t) => Math.min(1, 1.001 - Math.pow(2, -10 * t)),
direction: "vertical",
gestureDirection: "vertical",
smoothHover: true,
// En móviles a veces es mejor dejarlo en false para no interferir con el scroll nativo
smoothTouch: false,
});
// Función de actualización (Raf)
function raf(time: number) {
lenis.raf(time);
requestAnimationFrame(raf);
}
requestAnimationFrame(raf);
</script>
<style>
/* Estilos base para Lenis */
html.lenis {
height: auto;
}
.lenis.lenis-smooth {
scroll-behavior: auto !important;
}
.lenis.lenis-smooth [data-lenis-prevent] {
overscroll-behavior: contain;
}
.lenis.lenis-stopped {
overflow: hidden;
}
/* Estilos globales */
html {
margin: 0;
@@ -161,10 +142,6 @@ const { pageTitle } = Astro.props;
display: flex;
flex-direction: column;
overflow-x: clip;
/* background-image: url("/src/assets/imgs/n-naliia-rosada-fondo.webp");
background-repeat: no-repeat;
background-position: top right; */
}
body::before {

View File

@@ -14,12 +14,12 @@ import "../styles/contactpage.css";
<Layout pageTitle="Contacto">
<section class="contact-page">
<InitialSection
imgSrc="/src/assets/imgs/chat_3d_illustration.svg"
imgSrc="/images/chat_3d_illustration.svg"
imgAlt="Ilustración 3D de unas burbujas de chat flotantes"
imgWidth={700}
customXPosition="-36%"
customYPosition="20%"
logoSrc="/src/assets/imgs/logo-naliia.svg"
logoSrc="/images/logo-naliia.svg"
logoAlt="Logo de Naliia"
mainTitle="Contáctanos"
autoHeight={true}
@@ -40,7 +40,7 @@ import "../styles/contactpage.css";
</div>
<div class="socialmedia-icons">
<a href="#" class="social-media-link whatsapp-link">
<a href="https://wa.me/573001158180?text=Hola,%20estoy%20interesado%20en%20obtener%20más%20información%20sobre%20Naliia." target="_blank" class="social-media-link whatsapp-link">
<svg
xmlns="http://www.w3.org/2000/svg"
width="48"
@@ -60,7 +60,7 @@ import "../styles/contactpage.css";
>
</a>
<a href="" class="social-media-link instagram-link">
<!-- <a href="" class="social-media-link instagram-link">
<svg
xmlns="http://www.w3.org/2000/svg"
width="48"
@@ -72,9 +72,9 @@ import "../styles/contactpage.css";
d="M7.8 2h8.4C19.4 2 22 4.6 22 7.8v8.4a5.8 5.8 0 0 1-5.8 5.8H7.8C4.6 22 2 19.4 2 16.2V7.8A5.8 5.8 0 0 1 7.8 2m-.2 2A3.6 3.6 0 0 0 4 7.6v8.8C4 18.39 5.61 20 7.6 20h8.8a3.6 3.6 0 0 0 3.6-3.6V7.6C20 5.61 18.39 4 16.4 4zm9.65 1.5a1.25 1.25 0 0 1 1.25 1.25A1.25 1.25 0 0 1 17.25 8A1.25 1.25 0 0 1 16 6.75a1.25 1.25 0 0 1 1.25-1.25M12 7a5 5 0 0 1 5 5a5 5 0 0 1-5 5a5 5 0 0 1-5-5a5 5 0 0 1 5-5m0 2a3 3 0 0 0-3 3a3 3 0 0 0 3 3a3 3 0 0 0 3-3a3 3 0 0 0-3-3"
></path></svg
>
</a>
</a> -->
<a href="#" class="social-media-link email-link">
<a href="mailto:proyectos@ausolutionsit.com" class="social-media-link email-link">
<svg
xmlns="http://www.w3.org/2000/svg"
width="48"

View File

@@ -116,8 +116,6 @@ const videosList = Object.keys(videoFiles).map((key) => {
const name = item.getAttribute("data-name");
const matches = name && name.includes(query);
// Usamos toggle: si matches es true, hidden es false (se muestra)
// Si matches es false, hidden es true (se oculta)
item.classList.toggle("hidden", !matches);
if (matches) {

View File

@@ -15,13 +15,14 @@ import "../styles/index.css";
<Layout pageTitle="Home page">
<section class="homepage">
<InitialSection
imgSrc="/src/assets/imgs/mujer-con-tablet.svg"
imgSrc="/images/mujer-con-tablet.svg"
imgAlt="Fotografía de una mujer sosteniendo una tablet"
logoSrc="/src/assets/imgs/logo-naliia.svg"
logoSrc="/images/logo-naliia.svg"
logoAlt="Logo de Naliia"
mainTitle="Transformamos el caos en claridad"
subtitle="Convertimos la complejidad de negocios completos en un ecosistema que respira orden, precisión y belleza."
buttonText="Comienza tu experiencia aquí"
customHref="https://wa.me/573001158180"
/>
<!-- ----- What we offer section ----- -->
@@ -260,11 +261,11 @@ import "../styles/index.css";
</div>
</div>
<button
class="calltoaction-button button-hover-effect importantButton-hover-animation"
>
Quiero obtener uno de los planes</button
<a href="https://wa.me/573001158180" target="_blank"
class="calltoaction-button button-hover-effect"
>
Quiero obtener uno de los planes
</a>
<p class="important-information">
Todos los planes incluyen soporte de lunes a viernes de 8am a

View File

@@ -10,11 +10,11 @@ import "../styles/pricingPage.css";
<Layout pageTitle="Precios y membresías">
<section class="pricing-page">
<InitialSection
imgSrc="/src/assets/imgs/phone_with-stats.svg"
imgSrc="/images/phone_with-stats.svg"
imgAlt="Fotografía de un dispositivo móvil flotante con gráficas y estadísticas en la pantalla y con un borde amarillo brillante"
imgWidth={520}
customXPosition="-52%"
logoSrc="/src/assets/imgs/logo-naliia.svg"
logoSrc="/images/logo-naliia.svg"
logoAlt="Logo de Naliia"
mainTitle="Elige tu plan, impulsa tu negocio"
subtitle="El siguiente nivel de tu negocio está a un clic. Elige, empieza y deja que los resultados hablen."
@@ -23,7 +23,7 @@ import "../styles/pricingPage.css";
<div slot="extraContent">
<div class="pricingcards">
<PricingCard
planType="sico"
planType="basic"
price="$100.000 COP"
description="¡Administra tu negocio desde el primer día!"
featuresTitle="Módulo administrativo"
@@ -33,7 +33,7 @@ import "../styles/pricingPage.css";
/>
<PricingCard
planType="Avanzado"
planType="advanced"
price="$500.000 COP"
description="El mejor plan todo en uno para el control total de tu negocio."
featuresTitle="Módulo administrativo + web app + Inteligencia artificial"
@@ -44,7 +44,7 @@ import "../styles/pricingPage.css";
/>
<PricingCard
planType="Intermedio"
planType="intermediate"
price="$300.000 COP"
description="Más control y colaboración con una web app para tu equipo de trabajo."
featuresTitle="Módulo administrativo + web app"