fix contact form

Signed-off-by: Xe Iaso <me@xeiaso.net>
This commit is contained in:
Xe Iaso 2024-09-20 13:59:31 -04:00
parent b3d3443243
commit d85a29c15d
Signed by: xe
SSH Key Fingerprint: SHA256:7EWsWanxCI427bJ0t3CA6LyqXnkPajReCxkUhbpJULU
7 changed files with 220 additions and 164 deletions

10
actions/contact.ts Normal file
View File

@ -0,0 +1,10 @@
"use server";
export default async function contactForm(formData: FormData) {
const rawFormData = {
name: formData.get('name'),
email: formData.get('email'),
message: formData.get('message'),
};
console.log(rawFormData);
};

View File

@ -1,122 +0,0 @@
import React from 'react';
import { User, Award, Globe } from 'lucide-react';
import { Button } from '@/components/ui/Button';
import { allAuthors } from '@/.content-collections/generated';
import Image from 'next/image';
const TeamMember = ({ name, role, image }) => (
<div className="text-center">
<Image className="mx-auto h-40 w-40 rounded-full" width={256} height={256} src={image} alt={name} />
<div className="mt-4">
<h3 className="text-lg font-medium text-gray-900">{name}</h3>
<p className="text-sm text-gray-500">{role}</p>
</div>
</div>
);
function shuffle(array) {
let currentIndex = array.length;
// While there remain elements to shuffle...
while (currentIndex != 0) {
// Pick a remaining element...
let randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex--;
// And swap it with the current element.
[array[currentIndex], array[randomIndex]] = [
array[randomIndex], array[currentIndex]];
}
}
const AboutPage = () => {
const teamMembers = allAuthors.map(author => ({
name: author.displayName,
role: author.role,
image: author.avatarUrl,
}));
shuffle(teamMembers);
return (
<div className="bg-gray-100 min-h-screen">
<header className="bg-white shadow">
<div className="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">
<h1 className="text-3xl font-bold text-gray-900">About Us</h1>
</div>
</header>
<main>
<div className="max-w-7xl mx-auto py-6 sm:px-6 lg:px-8">
<div className="px-4 py-6 sm:px-0">
<div className="text-center mb-12">
<h2 className="text-3xl font-extrabold text-gray-900 sm:text-4xl">
Empowering Canadian Businesses with Innovative Technology
</h2>
<p className="mt-4 text-xl text-gray-500">
Techaro Computing Canada is at the forefront of digital transformation, helping businesses across the country leverage cutting-edge technology to drive growth and innovation.
</p>
</div>
<div className="bg-white shadow overflow-hidden sm:rounded-lg mb-12">
<div className="px-4 py-5 sm:px-6">
<h3 className="text-lg leading-6 font-medium text-gray-900">Our Mission</h3>
</div>
<div className="border-t border-gray-200">
<dl>
<div className="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt className="text-sm font-medium text-gray-500 flex items-center">
<User className="h-5 w-5 mr-2 text-blue-500" />
Client Focus
</dt>
<dd className="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
We are dedicated to understanding and meeting the unique needs of each client, ensuring their success in the digital landscape.
</dd>
</div>
<div className="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt className="text-sm font-medium text-gray-500 flex items-center">
<Award className="h-5 w-5 mr-2 text-blue-500" />
Innovation
</dt>
<dd className="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
We continuously explore and implement the latest technologies to provide cutting-edge solutions for our clients.
</dd>
</div>
<div className="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt className="text-sm font-medium text-gray-500 flex items-center">
<Globe className="h-5 w-5 mr-2 text-blue-500" />
Canadian Focus
</dt>
<dd className="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
We are committed to strengthening the Canadian tech ecosystem and helping local businesses compete on a global scale.
</dd>
</div>
</dl>
</div>
</div>
<div className="text-center mb-12">
<h3 className="text-2xl font-bold text-gray-900">Our Team</h3>
<div className="mt-10 grid grid-cols-1 gap-10 sm:grid-cols-2 lg:grid-cols-3">
{teamMembers.map((member, index) => (
<TeamMember key={index} {...member} />
))}
</div>
</div>
<div className="bg-blue-700 rounded-lg shadow-xl overflow-hidden">
<div className="px-4 py-5 sm:p-6 text-center">
<h3 className="text-2xl font-semibold text-white mb-4">Ready to Transform Your Business?</h3>
<p className="text-blue-100 mb-6">Let{"'"}s discuss how Techaro Computing Canada can help you achieve your technology goals.</p>
<Button className="bg-white text-blue-700 hover:bg-blue-50">
Schedule a Consultation
</Button>
</div>
</div>
</div>
</div>
</main>
</div>
);
};
export default AboutPage;

155
app/about/page.tsx Normal file
View File

@ -0,0 +1,155 @@
import React from "react";
import { User, Award, Globe } from "lucide-react";
import { Button } from "@/components/ui/Button";
import { allAuthors } from "@/.content-collections/generated";
import Image from "next/image";
import Link from "next/link";
const TeamMember = ({
name,
role,
image,
}: {
name: string;
role: string;
image: string;
}) => (
<div className="text-center">
<Image
className="mx-auto h-40 w-40 rounded-full"
width={256}
height={256}
src={image}
alt={name}
/>
<div className="mt-4">
<h3 className="text-lg font-medium text-gray-900">{name}</h3>
<p className="text-sm text-gray-500">{role}</p>
</div>
</div>
);
function shuffle(array: any[]) {
let currentIndex = array.length;
// While there remain elements to shuffle...
while (currentIndex != 0) {
// Pick a remaining element...
let randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex--;
// And swap it with the current element.
[array[currentIndex], array[randomIndex]] = [
array[randomIndex],
array[currentIndex],
];
}
}
const AboutPage = () => {
const teamMembers = allAuthors.map((author) => ({
name: author.displayName,
role: author.role,
image: author.avatarUrl,
}));
shuffle(teamMembers);
return (
<div className="bg-gray-100 min-h-screen">
<header className="bg-white shadow">
<div className="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">
<h1 className="text-3xl font-bold text-gray-900">About Us</h1>
</div>
</header>
<main>
<div className="max-w-7xl mx-auto py-6 sm:px-6 lg:px-8">
<div className="px-4 py-6 sm:px-0">
<div className="text-center mb-12">
<h2 className="text-3xl font-extrabold text-gray-900 sm:text-4xl">
Empowering Canadian Businesses with Innovative Technology
</h2>
<p className="mt-4 text-xl text-gray-500">
Techaro Computing Canada is at the forefront of digital
transformation, helping businesses across the country leverage
cutting-edge technology to drive growth and innovation.
</p>
</div>
<div className="bg-white shadow overflow-hidden sm:rounded-lg mb-12">
<div className="px-4 py-5 sm:px-6">
<h3 className="text-lg leading-6 font-medium text-gray-900">
Our Mission
</h3>
</div>
<div className="border-t border-gray-200">
<dl>
<div className="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt className="text-sm font-medium text-gray-500 flex items-center">
<User className="h-5 w-5 mr-2 text-blue-500" />
Client Focus
</dt>
<dd className="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
We are dedicated to understanding and meeting the unique
needs of each client, ensuring their success in the
digital landscape.
</dd>
</div>
<div className="bg-white px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt className="text-sm font-medium text-gray-500 flex items-center">
<Award className="h-5 w-5 mr-2 text-blue-500" />
Innovation
</dt>
<dd className="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
We continuously explore and implement the latest
technologies to provide cutting-edge solutions for our
clients.
</dd>
</div>
<div className="bg-gray-50 px-4 py-5 sm:grid sm:grid-cols-3 sm:gap-4 sm:px-6">
<dt className="text-sm font-medium text-gray-500 flex items-center">
<Globe className="h-5 w-5 mr-2 text-blue-500" />
Canadian Focus
</dt>
<dd className="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
We are committed to strengthening the Canadian tech
ecosystem and helping local businesses compete on a global
scale.
</dd>
</div>
</dl>
</div>
</div>
<div className="text-center mb-12">
<h3 className="text-2xl font-bold text-gray-900">Our Team</h3>
<div className="mt-10 grid grid-cols-1 gap-10 sm:grid-cols-2 lg:grid-cols-3">
{teamMembers.map((member, index) => (
<TeamMember key={index} {...member} />
))}
</div>
</div>
<div className="bg-blue-700 rounded-lg shadow-xl overflow-hidden">
<div className="px-4 py-5 sm:p-6 text-center">
<h3 className="text-2xl font-semibold text-white mb-4">
Ready to Transform Your Business?
</h3>
<p className="text-blue-100 mb-6">
Let{"'"}s discuss how Techaro Computing Canada can help you
achieve your technology goals.
</p>
<Link href="/contact">
<Button className="bg-white text-blue-700 hover:bg-blue-50">
Schedule a Consultation
</Button>
</Link>
</div>
</div>
</div>
</div>
</main>
</div>
);
};
export default AboutPage;

View File

@ -36,10 +36,10 @@ export default async function Page({ params }: { params: PageParams }) {
</div>
</header>
<p className="text-muted-foreground pb-8 mt-4 text-sm max-w-[80ch] mx-auto">
<div className="text-muted-foreground pb-8 mt-4 text-sm max-w-[80ch] mx-auto">
<AuthorChip {...page.author!} />
{page.summary}
</p>
</div>
{page.image !== undefined && (
<Image

View File

@ -1,51 +1,62 @@
import React from 'react';
"use client";
import React, { useState } from 'react';
import contactForm from '@/actions/contact';
const ContactPage = () => {
async function contactForm(formData) {
"use server";
const rawFormData = {
name: formData.get('name'),
email: formData.get('email'),
message: formData.get('message'),
};
console.log(rawFormData);
};
const [message, setMessage] = useState(null);
const callback = async (formData) => {
await contactForm(formData);
setMessage("Our intrepid team of code monkeys will be looking at this as soon as possible!");
}
return (
<div className="bg-gray-100 mx-auto text-gray-900 px-4 pt-8">
<h1 className="text-3xl font-bold text-gray-900 mb-6">Contact Techaro Computing Canada</h1>
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
<div className="text-gray-900">
<h2 className="text-xl font-semibold mb-4">Get in Touch</h2>
<p className="mb-4">We would love to hear from you. Please fill out the form below or use our contact information.</p>
<h3 className="text-lg font-semibold mb-2">Contact Information</h3>
<p>Email: sales@techaro.lol</p>
<p>Phone: (123) 456-7890</p>
<p>Address: 123 Tech Street, Toronto, ON M5V 1J2</p>
<>
<header className="bg-white shadow">
<div className="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">
<h1 className="text-3xl font-bold text-gray-900">Contact Us</h1>
</div>
</header>
<div className="bg-gray-100 mx-auto text-gray-900 px-4 pt-8">
<div className="grid grid-cols-1 gap-8 max-w-3xl mx-auto">
<div className="text-gray-900">
<h2 className="text-xl font-semibold mb-4">Get in Touch</h2>
<p className="mb-4">We would love to hear from you. Please fill out the form below or use our contact information.</p>
<div className="pb-4">
<h2 className="text-xl font-semibold mb-4">Contact Form</h2>
<form className="space-y-4" action={contactForm}>
<div>
<label htmlFor="name" className="block mb-1">Name</label>
<input disabled type="text" id="name" name="name" className="w-full px-3 py-2 border rounded" required />
</div>
<div>
<label htmlFor="email" className="block mb-1">Email</label>
<input disabled type="email" id="email" name="email" className="w-full px-3 py-2 border rounded" required />
</div>
<div>
<label htmlFor="message" className="block mb-1">Message</label>
<textarea disabled id="message" name="message" rows="4" className="w-full px-3 py-2 border rounded" required></textarea>
</div>
<button type="submit" disabled className="bg-gray-500 text-white px-4 py-2 rounded hover:bg-gray-600">Send Message</button>
</form>
<h3 className="text-lg font-semibold mb-2">Contact Information</h3>
<p>Email: sales@techaro.lol</p>
</div>
<div className="pb-4">
<h2 className="text-xl font-semibold mb-4">Contact Form</h2>
<form className="space-y-4" action={callback}>
<div>
<label htmlFor="name" className="block mb-1">Name</label>
<input type="text" id="name" name="name" className="w-full px-3 py-2 border rounded" required />
</div>
<div>
<label htmlFor="email" className="block mb-1">Email</label>
<input type="email" id="email" name="email" className="w-full px-3 py-2 border rounded" required />
</div>
<div>
<label htmlFor="message" className="block mb-1">Message</label>
<textarea id="message" name="message" rows="4" className="w-full px-3 py-2 border rounded" required></textarea>
</div>
<button type="submit" className="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600">Send Message</button>
{message !== null && (
<>
<div className="p-4 bg-gray-200">
<p className="text-xl">Thanks!</p>
<p className="p-4">{message}</p>
</div>
</>
)}
</form>
</div>
</div>
</div>
</div>
</>
);
};

View File

@ -8,6 +8,7 @@ const authors = defineCollection({
schema: (z) => ({
name: z.string(),
displayName: z.string(),
active: z.boolean().default(true),
role: z.string(),
avatarUrl: z.string(),
bluesky: z.string().optional(),

View File

@ -4,4 +4,5 @@ displayName: "Mimi Yasomi"
role: "Member of Technical Staff"
avatarUrl: /img/avatars/mimi.webp
bluesky: yasomi.xeiaso.net
active: true
---