diff --git a/app/listen/page.tsx b/app/listen/page.tsx
index 4bcefaf..f547f0c 100644
--- a/app/listen/page.tsx
+++ b/app/listen/page.tsx
@@ -4,7 +4,6 @@ export default async function ListenIndex() {
return (
Listen
- {/* @ts-ignore server component */}
)
diff --git a/app/projects/[id]/page.tsx b/app/projects/[id]/page.tsx
deleted file mode 100644
index 7d44554..0000000
--- a/app/projects/[id]/page.tsx
+++ /dev/null
@@ -1,34 +0,0 @@
-// 'use client';
-import ProjectRepository from "@/server/actions/project.actions";
-import Image from "next/image";
-
-export default async function ProjectById(req: { params: any, searchParams: any }) {
- const projects = new ProjectRepository();
- const project = await projects.getProjectById(req.params.id);
-
- if (!project) {
- return (
-
-
Project not found!
-
- )
- }
-
- return (
-
-
- {project.name}
- Started: {project.created.toLocaleString()}
- {project.updated ? `Finished: ${project.updated.toLocaleDateString()}` : "(In progress)"}
-
-
-
-
{project.description}
-
-
- { project.media && project.media.map((link, idx) => {
- return
- })}
-
- )
-}
diff --git a/components/Navbar/index.tsx b/components/Navbar/index.tsx
index 2fed560..1189fd4 100644
--- a/components/Navbar/index.tsx
+++ b/components/Navbar/index.tsx
@@ -37,9 +37,6 @@ export default function Navbar() {
-
-
-
@@ -60,8 +57,8 @@ export default function Navbar() {
About
-
setMobileMenuOpen(false)} passHref href="/projects" className="w-auto px-2">
-
Projects
+
setMobileMenuOpen(false)} passHref href="/links" className="w-auto px-2">
+
Links
setMobileMenuOpen(false)} passHref href="/contact" className="w-auto px-2">
diff --git a/components/Resume/Experience.tsx b/components/Resume/Experience.tsx
index 1212934..249ff74 100644
--- a/components/Resume/Experience.tsx
+++ b/components/Resume/Experience.tsx
@@ -1,24 +1,42 @@
import Link from "next/link";
import Card from "../ui/Card";
-const Experience = () => {
+export default function Experience() {
return (
+
+ Vertafore
+ Software Engineer
+ May 2024 - present
+
+
+
+ Contributing as part of a development team building an insurance tech solution.
+
+
+
+ Epic Stock Media
+ Software Engineer
+ Dec 2023 - May 2024
+
+
+
+ Building a dedicated tool for sound design professionals to browse, stream, and download from a large library of audio assets in an on-premise managed cloud solution.
+
+
Dropper Studio
- Nashville, TN (hybrid) - Software Engineer
+ Software Engineer
March 2023 - present
Building a full-stack e-commerce platform for the music industry. Experience includes: producing a functional proof of concept from design specifications; constructing a scalable, performant full-stack architecture; and project/team management skills.
-
- Learn more about my work with Dropper
Dization, Inc.
- Pittsburgh, PA (remote) - Software Engineer (intern)
+ Software Engineer (intern)
October 2022 - March 2023
@@ -30,17 +48,13 @@ const Experience = () => {
Metazu Studio
- Nashville, TN (hybrid) - Software Engineer (consultant)
+ Software Engineer (consultant)
March 2022 - December 2022
Consulted on small teams for the design and engineering of full-stack web applications for clients. Used technologies including Node.js, React, MongoDB, and PostgreSQL.
-
- See more about my experience
)
}
-
-export default Experience;
diff --git a/components/Resume/Projects.tsx b/components/Resume/Projects.tsx
index df17cbb..a2d948d 100644
--- a/components/Resume/Projects.tsx
+++ b/components/Resume/Projects.tsx
@@ -13,9 +13,9 @@ const Projects = () => (
- Recipin
+ Unbinder
October 2022 - present
- React, Express, TypeScript, PostgreSQL
+ ASP.NET
diff --git a/components/Resume/Skills.tsx b/components/Resume/Skills.tsx
index b5f2e7d..d75b965 100644
--- a/components/Resume/Skills.tsx
+++ b/components/Resume/Skills.tsx
@@ -15,8 +15,8 @@ const Skills = () => (
-
+
@@ -53,7 +53,6 @@ const Skills = () => (
-
@@ -80,6 +79,7 @@ const Skills = () => (
+
@@ -125,24 +125,11 @@ const Skills = () => (
-
+
-
- {/*
-
-
- Natural Language Processing
-
-
-
-
- */}
diff --git a/env.mjs b/env.mjs
index e2ab82f..dfa965e 100644
--- a/env.mjs
+++ b/env.mjs
@@ -3,15 +3,17 @@ import { z } from 'zod';
const env = createEnv({
server: {
- POSTGRES_URL: z.string().url(),
- POSTGRES_USER: z.string(),
- POSTGRES_PASSWORD: z.string(),
+ SMTP_USER: z.string().optional(),
+ SMTP_PASS: z.string().optional(),
+ SMTP_TO: z.string().optional(),
+ SMTP_HOST: z.string().optional(),
},
runtimeEnv: {
- POSTGRES_URL: process.env.POSTGRES_URL,
- POSTGRES_USER: process.env.POSTGRES_USER,
- POSTGRES_PASSWORD: process.env.POSTGRES_PASSWORD,
- }
+ SMTP_USER: process.env.SMTP_USER,
+ SMTP_PASS: process.env.SMTP_PASS,
+ SMTP_TO: process.env.SMTP_TO,
+ SMTP_HOST: process.env.SMTP_HOST,
+ },
})
export { env }
diff --git a/next.config.js b/next.config.js
index fae793b..2dc614b 100644
--- a/next.config.js
+++ b/next.config.js
@@ -2,6 +2,9 @@
const nextConfig = {
pageExtensions: ['js', 'jsx', 'ts', 'tsx'],
reactStrictMode: true,
+ experimental: {
+ serverActions: true,
+ }
}
module.exports = nextConfig;
diff --git a/package.json b/package.json
index 08dc84e..94c5a74 100644
--- a/package.json
+++ b/package.json
@@ -15,7 +15,7 @@
"eslint": "^8.46.0",
"eslint-config-next": "^13.4.12",
"next": "^13.4.12",
- "pg": "^8.11.3",
+ "nodemailer": "^6.9.13",
"postcss": "^8.4.31",
"react": "18.2.0",
"react-dom": "18.2.0",
@@ -26,6 +26,7 @@
},
"devDependencies": {
"@types/node": "20.2.5",
+ "@types/nodemailer": "^6.4.15",
"@types/pg": "^8.10.3",
"@types/react": "18.2.7",
"@types/react-dom": "18.2.4",
diff --git a/server/actions/contact.actions.ts b/server/actions/contact.actions.ts
new file mode 100644
index 0000000..f73f3e1
--- /dev/null
+++ b/server/actions/contact.actions.ts
@@ -0,0 +1,32 @@
+'use server';
+import { createTransport } from "nodemailer";
+import SMTPTransport from "nodemailer/lib/smtp-transport";
+import { env } from "../../env.mjs"
+
+export async function submitMessage({ from, text }: { from: string, text: string }) {
+ const options = {
+ host: env.SMTP_HOST,
+ port: 587,
+ auth: {
+ user: env.SMTP_USER,
+ pass: env.SMTP_PASS,
+ },
+ } as SMTPTransport.Options;
+
+ // console.log({ options });
+
+ // const transport = createTransport(options);
+
+ // const result = await transport.sendMail({
+ // subject: "Contact Form Submission | mikayla.dev",
+ // to: env.SMTP_TO,
+ // from,
+ // text,
+ // });
+
+ // const failed = result.rejected.concat(result.pending).filter(Boolean);
+
+ // if (failed.length) {
+ // throw new Error("Failed to send email verification");
+ // }
+}
diff --git a/server/actions/project.actions.ts b/server/actions/project.actions.ts
deleted file mode 100644
index 8587e7c..0000000
--- a/server/actions/project.actions.ts
+++ /dev/null
@@ -1,56 +0,0 @@
-import { Project, isProject } from "../entities/project";
-import createClient from "../services/pg";
-
-export default class ProjectRepository {
- async createProject(data: Project) {
- const client = await createClient();
- if (!client) return null;
- await client.connect();
-
- const { rows } = await client.query(
- "INSERT INTO project (name, description, created, updated) VALUES ($1, $2, $3, $4) RETURNING *"
- , [
- data.name,
- data.description,
- data.created,
- data.updated,
- ]);
-
- await client.end();
-
- if (rows.every(row => isProject(row))) {
- return rows[0] as Project;
- }
-
- return null;
- }
-
- async getProjects() {
- const client = await createClient();
- if (!client) return null;
-
- const { rows } = await client.query("SELECT * FROM project");
- await client.end();
-
- if (rows.every(row => isProject(row))) {
- return rows as Project[];
- }
-
- return null;
- }
-
- async getProjectById(id: string) {
- const client = await createClient();
- if (!client) return null;
- await client.connect();
-
- const { rows } = await client.query("SELECT * FROM project WHERE id = $1", [id]);
- await client.end();
-
- if (rows.every(row => isProject(row))) {
- return rows[0] as Project;
- }
-
- return null;
- }
-}
diff --git a/server/services/pg.ts b/server/services/pg.ts
deleted file mode 100644
index dd2d9fb..0000000
--- a/server/services/pg.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import { env } from "@/env.mjs";
-import pg from 'pg';
-const { Client } = pg;
-
-export class PostgresError extends Error {
- constructor(message: string) {
- super(message);
- this.name = "PostgresError";
- }
-}
-
-export default async function createClient() {
- try {
- return new Client({
- connectionString: env.POSTGRES_URL,
- user: env.POSTGRES_USER,
- password: env.POSTGRES_PASSWORD,
- ssl: { rejectUnauthorized: false }
- });
- } catch(e) {
- console.log('error creating client', e);
- return null;
- }
-}