project setup

This commit is contained in:
Sone
2025-11-02 10:00:53 +01:00
parent 75bd171804
commit 7cb4c5345e
51 changed files with 3616 additions and 0 deletions
+111
View File
@@ -0,0 +1,111 @@
import Image from "next/image";
import aboutBg from "@/public/assets/images/our-mission-bg.png";
import avatar from "@/public/assets/avatars/avatar.png";
import avatar1 from "@/public/assets/avatars/avatar_1.png";
import avatar2 from "@/public/assets/avatars/avatar_2.png";
import avatar3 from "@/public/assets/avatars/avatar_3.png";
import TeamMemberCard from "@/components/about/TeamMemberCard";
const AboutPage = () => {
return (
<div>
<section className="relative overflow-hidden w-full min-h-[600px] sm:min-h-[700px] md:aspect-[5/3] md:max-h-[900px] -mt-[75px] pt-[75px]">
<div
className="absolute inset-0 sm:top-[-75px] top-[-35px] overflow-hidden"
style={{
WebkitMaskImage:
"linear-gradient(to bottom, rgba(0,0,0,0) 0%, rgba(0,0,0,1) 14%, rgba(0,0,0,1) 86%, rgba(0,0,0,0) 100%)",
maskImage:
"linear-gradient(to bottom, rgba(0,0,0,0) 0%, rgba(0,0,0,1) 14%, rgba(0,0,0,1) 86%, rgba(0,0,0,0) 100%)",
}}
>
<Image
src={aboutBg}
alt="About background"
fill
className="object-cover h-full"
style={{ objectPosition: "50% 20%" }}
priority
/>
{/* Mobile darkening overlay */}
<div className="absolute inset-0 bg-black/35 md:bg-black/0" />
<div className="pointer-events-none absolute left-1/2 top-[-36%] w-[260%] h-[62%] -translate-x-1/2 bg-[radial-gradient(circle_at_50%_-70%,rgba(127,19,236,0.88),rgba(127,19,236,0.52)_58%,rgba(25,16,34,0)_88%)] blur-[180px] opacity-95" />
<div className="pointer-events-none absolute left-1/2 bottom-[-18%] w-[240%] h-[36%] -translate-x-1/2 bg-[radial-gradient(circle_at_50%_135%,rgba(127,19,236,0.82),rgba(127,19,236,0.36)_46%,rgba(25,16,34,0)_86%)] blur-[140px] opacity-[0.9]" />
</div>
<div className="relative z-10 w-full h-full flex items-center justify-center px-6 py-12 sm:py-12 md:py-8">
<div className="max-w-4xl text-center">
<h1 className="text-3xl sm:text-4xl lg:text-6xl font-mono font-extrabold text-white drop-shadow-[0_0_20px_rgba(127,19,236,0.7)]">
Our Mission
</h1>
<p className="mt-4 sm:mt-6 text-sm sm:text-base font-mono leading-relaxed px-4">
Us as human, we better work as a collective no matter the language
or background we have. However we at LAN Codes believe we can
bring one more player to the team, AI. Acceleration of machine
learning language (MLL) models. "AI", is scary. In some way "I
Robot" it may seem more real to some. However, for players in LAN
Codes there is nothing that scares us. We are attempting to use
our critical thinking and MLL's efficiency to remove the busy work
and reduce human errors. While working on creating these systems
our results will produce cost effective security with
uncompromising safety. We believe that safety should not be a
privilege.
</p>
</div>
</div>
</section>
<section className="relative z-10 bg-[var(--color-1)]">
<div className="pointer-events-none absolute -top-16 left-0 right-0 h-16 bg-gradient-to-b from-transparent via-[var(--color-1)]/38 to-[var(--color-1)]" />
<div className="mx-auto px-4 sm:px-6 lg:px-8 pb-4 pt-4 max-w-[82.5%]">
<div className="text-center mb-4">
<h2 className="text-2xl sm:text-5xl font-mono">Founder</h2>
</div>
<div className="flex flex-col md:flex-row md:items-center md:justify-center gap-8 md:gap-12 max-w-3xl mx-auto">
<TeamMemberCard
avatar={avatar2}
name="Milan Vucetic"
position="Founder"
/>
<p className="font-mono text-sm sm:text-base leading-relaxed text-white/90 text-center md:max-w-xl">
I was always told you cannot reinvent the wheel, but you can make
it better. While working in reactive security prevention, then
moved towards proactive security prevention and a sprinkle of
inspiration, I managed to find a gap in many security doors, and
better yet a solution to tighten them up. With that goal I have
managed to organize the team of fearless people and with their
help LAN Codes became a reality from just an idea on a napkin.
</p>
</div>
<div className="mt-6 text-center">
<h3 className="text-xl sm:text-4xl font-mono">Meet the team</h3>
</div>
<div className="mt-4 grid grid-cols-1 sm:grid-cols-3 gap-6 sm:gap-12 max-w-3xl mx-auto justify-items-center">
<TeamMemberCard
avatar={avatar1}
name="Tevin Gary-Vincent"
position="Head of Cybersecurity"
/>
<TeamMemberCard
avatar={avatar}
name="Nenad Zivotic"
position="Front-end Developer"
/>
<TeamMemberCard
avatar={avatar3}
name="Stefan Djukelic"
position="Back-end Developer"
/>
</div>
</div>
</section>
</div>
);
};
export default AboutPage;
+41
View File
@@ -0,0 +1,41 @@
import { saveContact } from "@/lib/contactStore";
import { contactSchema } from "@/schemas/schemas";
export async function POST(req: Request) {
try {
const body = await req.json();
const {
firstName,
lastName,
companyName,
address,
email,
phone,
industry,
notes,
subscribe,
} = contactSchema.parse(body);
const saved = await saveContact({
firstName,
lastName,
companyName,
address,
email,
phone,
industry,
notes,
subscribe,
});
return Response.json({ success: true, id: saved.id });
} catch (err: any) {
if (err?.issues) {
return Response.json(
{ success: false, errors: err.issues },
{ status: 400 }
);
}
return Response.json({ success: false }, { status: 500 });
}
}
+33
View File
@@ -0,0 +1,33 @@
const ContactPage = () => {
return (
<div className="mx-auto w-full max-w-6xl px-4 sm:px-6 lg:px-8 py-16 md:py-32">
<div className="flex flex-col gap-16">
<div className="flex flex-col gap-10">
<p className="font-mono text-sm sm:text-base">
If you have any questions send us an email and we will be happy to
answer them.
<br />
You can expect our team to get back to your with in 24h-48h.
</p>
<p className="font-mono text-xl text-[var(--color-7)]">
<a href="mailto:service@lancodes.ca">service@lancodes.ca</a>
</p>
</div>
<div className="flex flex-col gap-10">
<p className="font-mono text-sm sm:text-base">
Looking for a job? Send us your resume and we will get back to you
when our next round of hiring starts.
</p>
<p className="font-mono text-xl text-[var(--color-10)]">
<a href="mailto:hireme@lancodes.ca">hireme@lancodes.ca</a>
</p>
</div>
</div>
</div>
);
};
export default ContactPage;
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

+47
View File
@@ -0,0 +1,47 @@
@font-face {
font-family: 'Fira Code';
src: url('/assets/fonts/static/FiraCode-Regular.ttf') format('truetype');
font-weight: 400;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Fira Code';
src: url('/assets/fonts/static/FiraCode-Medium.ttf') format('truetype');
font-weight: 500;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Fira Code';
src: url('/assets/fonts/static/FiraCode-SemiBold.ttf') format('truetype');
font-weight: 600;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Fira Code';
src: url('/assets/fonts/static/FiraCode-Bold.ttf') format('truetype');
font-weight: 700;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Fira Code';
src: url('/assets/fonts/static/FiraCode-Light.ttf') format('truetype');
font-weight: 300;
font-style: normal;
font-display: swap;
}
@font-face {
font-family: 'Fira Code VF';
src: url('/assets/fonts/FiraCode-VariableFont_wght.ttf') format('truetype-variations');
font-weight: 300 700;
font-style: normal;
font-display: swap;
}
+218
View File
@@ -0,0 +1,218 @@
"use client";
import { useForm, SubmitHandler } from "react-hook-form";
import { z } from "zod";
import { zodResolver } from "@hookform/resolvers/zod";
import { contactSchema } from "@/schemas/schemas";
import { toast } from "react-toastify";
type FormValues = z.infer<typeof contactSchema>;
const GetStartedPage = () => {
const {
register,
handleSubmit,
formState: { errors, isSubmitting },
reset,
watch,
setValue,
} = useForm<FormValues>({ resolver: zodResolver(contactSchema) });
const onSubmit: SubmitHandler<FormValues> = async (data) => {
try {
const res = await fetch("/api/contact", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(data),
});
if (!res.ok) throw new Error("Request failed");
toast.success("Thank you! We'll be in touch.");
reset();
} catch (e) {
toast.error("Failed to save contact. Please try again.");
}
};
return (
<div className="mx-auto w-full max-w-6xl px-4 sm:px-6 lg:px-8 py-6 sm:py-12">
<div className="text-center mb-6">
<h1 className="text-2xl md:text-3xl font-mono font-extrabold">
Join Us on This Journey
</h1>
<p className="mt-4 mb-4 max-w-4xl mx-auto text-sm sm:text-base font-mono">
Be a part of something innovative. As our early adapters, you will be
one of the key players making a change in how staying safe online is
important yet effortless. You will get exclusive early access to our
newest solutions and influence the development, while staying
protected in the process.
</p>
</div>
<div className="relative rounded-3xl border-4 border-[var(--color-3)] px-10 sm:px-14 py-8 shadow-[0_0_20px_rgba(255,255,255,0.5)]">
<form
onSubmit={handleSubmit(onSubmit)}
className="relative z-10 space-y-4"
>
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label className="sr-only">First name</label>
<input
placeholder="First name"
{...register("firstName")}
className="w-full border border-[var(--color-3)] outline-none rounded-sm px-3 py-0.5 text-sm"
/>
{errors.firstName && (
<p className="!text-[var(--color-8)] opacity-100 text-xs mt-1">
{errors.firstName.message}
</p>
)}
</div>
<div>
<label className="sr-only">Last name</label>
<input
placeholder="Last name"
{...register("lastName")}
className="w-full border border-[var(--color-3)] outline-none rounded-sm px-3 py-0.5 text-sm"
/>
{errors.lastName && (
<p className="!text-[var(--color-8)] opacity-100 text-xs mt-1">
{errors.lastName.message}
</p>
)}
</div>
<div>
<label className="sr-only">Company name</label>
<input
placeholder="Company name"
{...register("companyName")}
className="w-full border border-[var(--color-3)] outline-none rounded-sm px-3 py-0.5 text-sm"
/>
{errors.companyName && (
<p className="!text-[var(--color-8)] opacity-100 text-xs mt-1">
{errors.companyName.message}
</p>
)}
</div>
<div>
<label className="sr-only">Address</label>
<input
placeholder="Address"
{...register("address")}
className="w-full border border-[var(--color-3)] outline-none rounded-sm px-3 py-0.5 text-sm"
/>
{errors.address && (
<p className="!text-[var(--color-8)] opacity-100 text-xs mt-1">
{errors.address.message}
</p>
)}
</div>
<div>
<label className="sr-only">Email</label>
<input
placeholder="Email"
type="email"
{...register("email")}
className="w-full border border-[var(--color-3)] outline-none rounded-sm px-3 py-0.5 text-sm"
/>
{errors.email && (
<p className="!text-[var(--color-8)] opacity-100 text-xs mt-1">
{errors.email.message}
</p>
)}
</div>
<div>
<label className="sr-only">Phone number</label>
<input
placeholder="Phone number"
{...register("phone")}
className="w-full border border-[var(--color-3)] outline-none rounded-sm px-3 py-0.5 text-sm"
/>
{errors.phone && (
<p className="!text-[var(--color-8)] opacity-100 text-xs mt-1">
{errors.phone.message}
</p>
)}
</div>
</div>
<div>
<label className="sr-only">Industry type</label>
<input
placeholder="Industry type"
{...register("industry")}
className="w-full border border-[var(--color-3)] outline-none rounded-sm px-3 py-0.5 text-sm"
/>
{errors.industry && (
<p className="!text-[var(--color-8)] opacity-100 text-xs mt-1">
{errors.industry.message}
</p>
)}
</div>
<div>
<label className="sr-only">Additional notes</label>
<textarea
placeholder="Additional notes"
rows={8}
{...register("notes")}
className="w-full border border-[var(--color-3)] outline-none rounded-sm px-3 py-1 text-sm"
/>
</div>
<div className="flex items-center gap-2 ml-6">
<div className="relative">
<input
type="checkbox"
id="subscribe"
{...register("subscribe")}
className="sr-only"
/>
<div
className={`w-4 h-4 border-2 border-[var(--color-3)] cursor-pointer flex items-center justify-center transition-colors shadow-[0_0_10px_rgba(255,255,255,0.2)] ${
watch("subscribe") ? "bg-[var(--color-3)]" : "bg-transparent"
}`}
onClick={() => setValue("subscribe", !watch("subscribe"))}
>
{watch("subscribe") && (
<svg
className="w-3 h-3 text-white"
fill="currentColor"
viewBox="0 0 20 20"
>
<path
fillRule="evenodd"
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
clipRule="evenodd"
/>
</svg>
)}
</div>
</div>
<label
htmlFor="subscribe"
className="text-xs sm:text-sm font-mono cursor-pointer"
>
Sign up for our email list for updates, promotions, and more.
</label>
</div>
<div className="flex justify-center pt-2">
<button
type="submit"
disabled={isSubmitting}
className="px-6 py-3 font-mono text-sm text-white bg-[var(--color-3)] rounded-xl disabled:opacity-50 cursor-pointer"
>
{isSubmitting ? "Sending..." : "Send"}
</button>
</div>
</form>
{/* White glow */}
<div className="pointer-events-none absolute inset-0 rounded-3xl shadow-[0_0_5px_rgba(255,255,255,0.4)] z-0"></div>
</div>
</div>
);
};
export default GetStartedPage;
+44
View File
@@ -0,0 +1,44 @@
@import "tailwindcss";
@import "./fonts.css";
:root {
/* Base colors */
--white: #ffffff;
--black: #000000;
/* Custom color palette */
--color-1: #191022;
--color-2: #2d114a;
--color-3: #7f13ec;
--color-4: #cfa5e0;
--color-5: #3cf61a;
--color-6: #4ee871;
--color-7: #34d399;
--color-8: #ff007f;
--color-9: #ff31b5;
--color-10: #ec4899;
}
@theme inline {
--color-background: var(--color-1);
--color-foreground: var(--color-2);
--font-sans: var(--font-geist-sans);
--font-mono: "Fira Code", monospace;
--color-primary: var(--color-3);
--color-secondary: var(--color-7);
--color-accent: var(--color-8);
}
code,
pre {
font-family: "Fira Code", monospace;
}
body {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
background: var(--color-background);
color: var(--color-white);
font-family: var(--font-mono);
}
+33
View File
@@ -0,0 +1,33 @@
import type { Metadata } from "next";
import favicon from "@/public/assets/Logo_Pin_-_with_no_background.ico";
import Navbar from "@/components/navigation/Navbar";
import Footer from "@/components/Footer";
import ToastProvider from "@/components/providers/ToastProvider";
import "./globals.css";
export const metadata: Metadata = {
title: "Lan Codes",
description: "Lan Codes",
icons: {
icon: favicon.src,
},
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body className="bg-[var(--color-1)] min-h-screen flex flex-col overflow-x-hidden">
<Navbar />
<main className="flex-1">{children}</main>
<Footer />
<ToastProvider />
</body>
</html>
);
}
+112
View File
@@ -0,0 +1,112 @@
import Image from "next/image";
import { LockKeyhole, RotateCcw, Shield } from "lucide-react";
import heroBanner from "@/public/assets/images/homescreen_bg.png";
import FeatureCard from "@/components/FeatureCard";
import GetStartedButton from "@/components/navigation/GetStartedButton";
const HomePage = () => {
return (
<div>
<main>
<div>
<section className="relative overflow-hidden w-full min-h-[500px] sm:min-h-[600px] md:aspect-[16/9] md:max-h-[900px] -mt-[75px] pt-[75px] md:pt-[75px]">
{/* Background image */}
<div
className="absolute inset-0 top-[-75px] overflow-hidden"
style={{
WebkitMaskImage:
"linear-gradient(to bottom, rgba(0,0,0,0) 10%, rgba(0,0,0,0.3) 12%, rgba(0,0,0,1) 16%, rgba(0,0,0,1) 88%, rgba(0,0,0,0) 100%)",
maskImage:
"linear-gradient(to bottom, rgba(0,0,0,0) 10%, rgba(0,0,0,0.3) 12%, rgba(0,0,0,1) 16%, rgba(0,0,0,1) 88%, rgba(0,0,0,0) 100%)",
}}
>
<Image
src={heroBanner}
alt="Hero background"
fill
priority
className="object-cover h-full"
style={{ objectPosition: "50% 42.5%" }}
/>
<div className="absolute inset-0 bg-gradient-to-b from-black/3 via-black/6 to-black/9" />
<div className="absolute inset-0 bg-[radial-gradient(circle_at_50%_35%,rgba(127,19,236,0.03),rgba(16,0,40,0.06)_58%,rgba(0,0,0,0.12))]" />
{/* Mobile darkening overlay */}
<div className="absolute inset-0 bg-black/30 md:bg-black/0" />
</div>
<div className="relative z-10 w-full h-full flex items-center px-6 sm:px-10 md:pl-16 lg:pl-24 py-12 sm:py-12 md:py-8">
<div>
<h1 className="text-2xl sm:text-3xl md:text-4xl lg:text-6xl">
<span className="font-mono font-semibold w-[100px]">
Cost-Effective{" "}
</span>
<span className="text-[var(--color-8)] font-semibold">
Security
</span>
<br />
<span className="font-mono font-semibold w-[100px]">
Uncompromising{" "}
</span>
<span className="text-[var(--color-5)] font-semibold">
Safety
</span>
</h1>
<p className="mt-2 font-bold max-w-4xl text-lg sm:text-xl md:text-2xl">
Security that is{" "}
<span className="text-[var(--color-9)]">tailored</span>
</p>
<p className="mb-2 font-bold max-w-4xl text-lg sm:text-xl md:text-2xl">
for{" "}
<span className="text-[var(--color-5)]">your business</span>{" "}
needs
</p>
<GetStartedButton />
</div>
</div>
</section>
</div>
<section id="services" className="relative z-10 bg-[var(--color-1)]">
<div className="pointer-events-none absolute -top-16 left-0 right-0 h-16 bg-gradient-to-b from-transparent via-[var(--color-1)]/38 to-[var(--color-1)]" />
<div className="mx-auto w-full max-w-6xl px-4 sm:px-6 lg:px-8 py-6 sm:py-16 md:py-20">
<div className="text-center">
<h2 className="text-2xl sm:text-3xl font-extrabold font-mono">
Comprehensive Cybersecurity Services
</h2>
<p className="mt-3 max-w-3xl mx-auto text-md sm:text-lg font-mono">
Lan Codes offers a range of services in one simple package
designed to protect your business from cyber threats, ensuring
data security and operational continuity.
</p>
</div>
<div className="mt-6 sm:mt-10 grid grid-cols-1 md:grid-cols-3 gap-4">
<FeatureCard
icon={<Shield color="green" size={30} />}
title="Risk Detection"
description="Be on top of your end users and ensure there are no weak links in the chain. Have active reminders on your high risk users."
/>
<FeatureCard
icon={<LockKeyhole color="red" size={30} />}
title="Data Encryption & Security"
description="Robust data encryption and security measures to protect sensitive information and ensure compliance with industry standard."
/>
<FeatureCard
icon={<RotateCcw color="purple" size={30} />}
title="24/7 Monitoring & Assistance"
description="Round-the-clock monitoring and assistance to address and resolve any security incidents, minimizing downtime and potential damage."
/>
</div>
</div>
</section>
</main>
</div>
);
};
export default HomePage;
+100
View File
@@ -0,0 +1,100 @@
"use client";
import { useState } from "react";
import ProjectItems from "@/components/services/ProjectItems";
import GetStartedButton from "@/components/navigation/GetStartedButton";
import { projectItemsData } from "@/data/StaticData";
const ServicesPage = () => {
const [activeIndex, setActiveIndex] = useState(-1);
return (
<div className="mx-auto w-full max-w-6xl px-4 sm:px-6 lg:px-8 py-8 sm:pt-32 sm:pb-16">
<div className="grid grid-cols-1 md:grid-cols-12 gap-6 md:gap-0">
<div className="md:col-span-6">
<div className="flex items-center gap-3 mb-3 ml-2">
<span className="inline-block w-6 h-6 rotate-45 bg-[var(--color-7)]" />
<h1 className="text-2xl sm:text-3xl font-mono ml-2">
Bird eye view
</h1>
</div>
<div
className="md:w-3/4 w-full h-[3px] mb-4"
style={{ background: "var(--color-2)" }}
/>
<ProjectItems
items={projectItemsData}
activeIndex={activeIndex}
setActiveIndex={setActiveIndex}
/>
</div>
<div className="md:col-span-6">
<div
className={`bg-[var(--color-2)] p-6 md:p-8 md:min-h-[510px] flex items-start relative
${
activeIndex === projectItemsData.length - 1
? "rounded-tl-lg rounded-tr-lg"
: "rounded-lg"
}
`}
>
{activeIndex === -1 ? (
<>
<div className="w-full text-center pb-16">
<h3 className="text-xl sm:text-2xl font-mono font-extrabold">
Boost Your Security.
<br />
Simplify Your Workflow.
</h3>
<p className="mt-4 max-w-2xl mx-auto text-sm sm:text-base font-mono leading-relaxed">
LAN Codes is designed for organizations that want a smarter,
faster way to strengthen their security posture. Our custom
LLM automatically detects vulnerabilities and unusual
patternsremoving the tedious manual work so your team can
focus on what truly matters: investigating threats and
finding solutions.
</p>
<p className="mt-4 max-w-2xl mx-auto text-sm sm:text-base font-mono leading-relaxed">
Even if a breach occurs, your critical data stays encrypted
and protected, giving you the confidence and time to respond
effectively and prevent future incidents.
</p>
</div>
<div className="absolute bottom-6 left-0 right-0 flex justify-center">
<GetStartedButton />
</div>
</>
) : (
<div className="w-full text-center pb-16">
<p className="font-mono text-sm sm:text-base">
{projectItemsData[activeIndex]?.content}
</p>
</div>
)}
</div>
</div>
</div>
<div className="mt-10">
<div className="relative rounded-lg bg-[var(--color-2)] ring-1 ring-white/10 px-6 py-8 shadow-[0_0_16px_rgba(255,255,255,0.5)]">
<h2 className="text-center text-xl md:text-2xl font-mono mb-4">
Affordable Security for Everyone
</h2>
<p className="text-center mx-auto text-sm sm:text-base font-mono mb-6">
We believe cybersecurity should be accessible to all businesses,
regardless of size. Our solutions are designed to be cost effective
without compromising on security
</p>
<div className="flex justify-center">
<GetStartedButton />
</div>
</div>
</div>
</div>
);
};
export default ServicesPage;