export async function sendContactMessage(previous, formData) {
const text = (key) => String(formData.get(key) ?? "").trim();
const values = {
name: text("name"),
email: text("email"),
services: formData.getAll("services"),
message: text("message"),
};
const errors = {};
if (values.name.length < LIMITS.nameMin) errors.name = "Podaj swoje imię.";
if (!EMAIL_PATTERN.test(values.email)) errors.email = "Podaj poprawny e-mail.";
if (Object.keys(errors).length > 0) {
return { status: "error", errors, values };
}
const webhook = process.env.CONTACT_WEBHOOK_URL;
await fetch(webhook, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ ...values, sentAt: new Date() }),
});
return { status: "success" };
}
export async function sendContactMessage(previous, formData) {
const text = (key) => String(formData.get(key) ?? "").trim();
const values = {
name: text("name"),
email: text("email"),
services: formData.getAll("services"),
message: text("message"),
};
const errors = {};
if (values.name.length < LIMITS.nameMin) errors.name = "Podaj swoje imię.";
if (!EMAIL_PATTERN.test(values.email)) errors.email = "Podaj poprawny e-mail.";
if (Object.keys(errors).length > 0) {
return { status: "error", errors, values };
}
const webhook = process.env.CONTACT_WEBHOOK_URL;
await fetch(webhook, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ ...values, sentAt: new Date() }),
});
return { status: "success" };
}
export async function sendContactMessage(previous, formData) {
const text = (key) => String(formData.get(key) ?? "").trim();
const values = {
name: text("name"),
email: text("email"),
services: formData.getAll("services"),
message: text("message"),
};
const errors = {};
if (values.name.length < LIMITS.nameMin) errors.name = "Podaj swoje imię.";
if (!EMAIL_PATTERN.test(values.email)) errors.email = "Podaj poprawny e-mail.";
if (Object.keys(errors).length > 0) {
return { status: "error", errors, values };
}
const webhook = process.env.CONTACT_WEBHOOK_URL;
await fetch(webhook, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ ...values, sentAt: new Date() }),
});
return { status: "success" };
}
export async function sendContactMessage(previous, formData) {
const text = (key) => String(formData.get(key) ?? "").trim();
const values = {
name: text("name"),
email: text("email"),
services: formData.getAll("services"),
message: text("message"),
};
const errors = {};
if (values.name.length < LIMITS.nameMin) errors.name = "Podaj swoje imię.";
if (!EMAIL_PATTERN.test(values.email)) errors.email = "Podaj poprawny e-mail.";
if (Object.keys(errors).length > 0) {
return { status: "error", errors, values };
}
const webhook = process.env.CONTACT_WEBHOOK_URL;
await fetch(webhook, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ ...values, sentAt: new Date() }),
});
return { status: "success" };
}
export function Hero() {
return (
<section id="top" className="relative overflow-hidden">
<CodeBackdrop />
<h1 className="heading-xl">
<Line>Strony, które</Line>
<Line>zdobywają</Line>
<Line className="text-brand">klientów.</Line>
</h1>
<ButtonLink href="#contact" arrow>
Darmowa wycena
</ButtonLink>
</section>
);
}
const nextConfig = {
images: {
formats: ["image/avif", "image/webp"],
qualities: [70, 75, 82],
},
};
export function Hero() {
return (
<section id="top" className="relative overflow-hidden">
<CodeBackdrop />
<h1 className="heading-xl">
<Line>Strony, które</Line>
<Line>zdobywają</Line>
<Line className="text-brand">klientów.</Line>
</h1>
<ButtonLink href="#contact" arrow>
Darmowa wycena
</ButtonLink>
</section>
);
}
const nextConfig = {
images: {
formats: ["image/avif", "image/webp"],
qualities: [70, 75, 82],
},
};
export function Hero() {
return (
<section id="top" className="relative overflow-hidden">
<CodeBackdrop />
<h1 className="heading-xl">
<Line>Strony, które</Line>
<Line>zdobywają</Line>
<Line className="text-brand">klientów.</Line>
</h1>
<ButtonLink href="#contact" arrow>
Darmowa wycena
</ButtonLink>
</section>
);
}
const nextConfig = {
images: {
formats: ["image/avif", "image/webp"],
qualities: [70, 75, 82],
},
};
export function Hero() {
return (
<section id="top" className="relative overflow-hidden">
<CodeBackdrop />
<h1 className="heading-xl">
<Line>Strony, które</Line>
<Line>zdobywają</Line>
<Line className="text-brand">klientów.</Line>
</h1>
<ButtonLink href="#contact" arrow>
Darmowa wycena
</ButtonLink>
</section>
);
}
const nextConfig = {
images: {
formats: ["image/avif", "image/webp"],
qualities: [70, 75, 82],
},
};
@theme {
--color-canvas: #070b18;
--color-blue: #2f5cf0;
--color-cyan: #22d3ee;
--radius-card: 20px;
}
.code-drift {
animation: code-drift 90s linear infinite;
}
export const services = [
{ id: "design", title: "Projektowanie stron" },
{ id: "development", title: "Tworzenie stron" },
{ id: "wordpress", title: "WordPress" },
{ id: "redesign", title: "Redesign strony" },
{ id: "landing", title: "Landing page" },
{ id: "maintenance", title: "Opieka nad stroną" },
];
useEffect(() => {
const observer = new IntersectionObserver(reveal);
elements.forEach((element) => observer.observe(element));
return () => observer.disconnect();
}, []);
@theme {
--color-canvas: #070b18;
--color-blue: #2f5cf0;
--color-cyan: #22d3ee;
--radius-card: 20px;
}
.code-drift {
animation: code-drift 90s linear infinite;
}
export const services = [
{ id: "design", title: "Projektowanie stron" },
{ id: "development", title: "Tworzenie stron" },
{ id: "wordpress", title: "WordPress" },
{ id: "redesign", title: "Redesign strony" },
{ id: "landing", title: "Landing page" },
{ id: "maintenance", title: "Opieka nad stroną" },
];
useEffect(() => {
const observer = new IntersectionObserver(reveal);
elements.forEach((element) => observer.observe(element));
return () => observer.disconnect();
}, []);
@theme {
--color-canvas: #070b18;
--color-blue: #2f5cf0;
--color-cyan: #22d3ee;
--radius-card: 20px;
}
.code-drift {
animation: code-drift 90s linear infinite;
}
export const services = [
{ id: "design", title: "Projektowanie stron" },
{ id: "development", title: "Tworzenie stron" },
{ id: "wordpress", title: "WordPress" },
{ id: "redesign", title: "Redesign strony" },
{ id: "landing", title: "Landing page" },
{ id: "maintenance", title: "Opieka nad stroną" },
];
useEffect(() => {
const observer = new IntersectionObserver(reveal);
elements.forEach((element) => observer.observe(element));
return () => observer.disconnect();
}, []);
@theme {
--color-canvas: #070b18;
--color-blue: #2f5cf0;
--color-cyan: #22d3ee;
--radius-card: 20px;
}
.code-drift {
animation: code-drift 90s linear infinite;
}
export const services = [
{ id: "design", title: "Projektowanie stron" },
{ id: "development", title: "Tworzenie stron" },
{ id: "wordpress", title: "WordPress" },
{ id: "redesign", title: "Redesign strony" },
{ id: "landing", title: "Landing page" },
{ id: "maintenance", title: "Opieka nad stroną" },
];
useEffect(() => {
const observer = new IntersectionObserver(reveal);
elements.forEach((element) => observer.observe(element));
return () => observer.disconnect();
}, []);