Updates
This commit is contained in:
+15
-15
@@ -1,15 +1,15 @@
|
||||
import "../styles/main.css";
|
||||
import "../styles/tw_main.css";
|
||||
import { Fragment } from "react";
|
||||
|
||||
import type { AppProps } from "next/app";
|
||||
|
||||
function MyApp({ Component, pageProps }: AppProps) {
|
||||
return (
|
||||
<Fragment>
|
||||
<Component {...pageProps} />
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
export default MyApp;
|
||||
import "../styles/main.css";
|
||||
import "../styles/tw_main.css";
|
||||
import { Fragment } from "react";
|
||||
|
||||
import type { AppProps } from "next/app";
|
||||
|
||||
function MyApp({ Component, pageProps }: AppProps) {
|
||||
return (
|
||||
<Fragment>
|
||||
<Component {...pageProps} />
|
||||
</Fragment>
|
||||
);
|
||||
}
|
||||
|
||||
export default MyApp;
|
||||
|
||||
+19
-19
@@ -1,19 +1,19 @@
|
||||
import React from "react";
|
||||
import { Html, Head, Main, NextScript } from "next/document";
|
||||
|
||||
export default function Document() {
|
||||
return (
|
||||
<Html>
|
||||
<Head>
|
||||
<script
|
||||
src="/scripts/main.js"
|
||||
defer
|
||||
></script>
|
||||
</Head>
|
||||
<body className="w-full">
|
||||
<Main />
|
||||
<NextScript />
|
||||
</body>
|
||||
</Html>
|
||||
);
|
||||
}
|
||||
import React from "react";
|
||||
import { Html, Head, Main, NextScript } from "next/document";
|
||||
|
||||
export default function Document() {
|
||||
return (
|
||||
<Html>
|
||||
<Head>
|
||||
<script
|
||||
src="/scripts/main.js"
|
||||
defer
|
||||
></script>
|
||||
</Head>
|
||||
<body className="w-full">
|
||||
<Main />
|
||||
<NextScript />
|
||||
</body>
|
||||
</Html>
|
||||
);
|
||||
}
|
||||
|
||||
+49
-49
@@ -1,49 +1,49 @@
|
||||
/**
|
||||
* Imports
|
||||
*/
|
||||
const fs = require("fs");
|
||||
const sanitizeHtml = require("sanitize-html");
|
||||
const nodemailer = require("nodemailer");
|
||||
|
||||
import sanitizeHtmlOptions from "../../functions/backend/sanitizeHtmlOptions";
|
||||
import { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
let transporter = nodemailer.createTransport({
|
||||
host: process.env.TBENMAIL_HOST,
|
||||
port: 587,
|
||||
auth: {
|
||||
user: process.env.TBENMAIL_EMAIL,
|
||||
pass: process.env.TBENMAIL_EMAIL_PASSWORD,
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* API handler
|
||||
*
|
||||
*/
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
if (req.method === "POST") {
|
||||
let name = req.body.name;
|
||||
let email = req.body.email;
|
||||
let message = req.body.message;
|
||||
|
||||
const html = `<h1>Message from ${name} | ${email}</h1><h4>Name:</h4><p>${name}</p><h4>Email:</h4><p>${email}</p><h4>Message:</h4><p>${message}</p>`;
|
||||
const sanitizedHtml = sanitizeHtml(html, sanitizeHtmlOptions);
|
||||
|
||||
try {
|
||||
let info = await transporter.sendMail({
|
||||
from: `"Tben.me" <${process.env.TBENMAIL_EMAIL}>`,
|
||||
to: "benoti.san@gmail.com, benoti.sanchez@gmail.com",
|
||||
subject: "Tben.me | Client Message",
|
||||
text: "Hello from tben",
|
||||
html: sanitizedHtml,
|
||||
});
|
||||
|
||||
console.log("Message sent: %s", info.messageId);
|
||||
res.json({ msg: "Success", info: info });
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
res.json({ msg: "Failed" });
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Imports
|
||||
*/
|
||||
const fs = require("fs");
|
||||
const sanitizeHtml = require("sanitize-html");
|
||||
const nodemailer = require("nodemailer");
|
||||
|
||||
import sanitizeHtmlOptions from "../../functions/backend/sanitizeHtmlOptions";
|
||||
import { NextApiRequest, NextApiResponse } from "next";
|
||||
|
||||
let transporter = nodemailer.createTransport({
|
||||
host: process.env.TBENMAIL_HOST,
|
||||
port: 587,
|
||||
auth: {
|
||||
user: process.env.TBENMAIL_EMAIL,
|
||||
pass: process.env.TBENMAIL_EMAIL_PASSWORD,
|
||||
},
|
||||
});
|
||||
|
||||
/**
|
||||
* API handler
|
||||
*
|
||||
*/
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
if (req.method === "POST") {
|
||||
let name = req.body.name;
|
||||
let email = req.body.email;
|
||||
let message = req.body.message;
|
||||
|
||||
const html = `<h1>Message from ${name} | ${email}</h1><h4>Name:</h4><p>${name}</p><h4>Email:</h4><p>${email}</p><h4>Message:</h4><p>${message}</p>`;
|
||||
const sanitizedHtml = sanitizeHtml(html, sanitizeHtmlOptions);
|
||||
|
||||
try {
|
||||
let info = await transporter.sendMail({
|
||||
from: `"Tben.me" <${process.env.TBENMAIL_EMAIL}>`,
|
||||
to: "benoti.san@gmail.com, benoti.sanchez@gmail.com",
|
||||
subject: "Tben.me | Client Message",
|
||||
text: "Hello from tben",
|
||||
html: sanitizedHtml,
|
||||
});
|
||||
|
||||
console.log("Message sent: %s", info.messageId);
|
||||
res.json({ msg: "Success", info: info });
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
res.json({ msg: "Failed" });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+45
-45
@@ -1,45 +1,45 @@
|
||||
import { NextApiHandler, NextApiRequest, NextApiResponse } from "next";
|
||||
import Cors from "cors";
|
||||
|
||||
const cors = Cors({
|
||||
methods: ["GET"],
|
||||
origin: "*",
|
||||
});
|
||||
|
||||
// Helper method to wait for a middleware to execute before continuing
|
||||
// And to throw an error when an error happens in a middleware
|
||||
function runMiddleware(req: NextApiRequest, res: NextApiResponse, fn: Function) {
|
||||
return new Promise((resolve, reject) => {
|
||||
fn(req, res, (result: any) => {
|
||||
if (result instanceof Error) {
|
||||
return reject(result);
|
||||
}
|
||||
|
||||
return resolve(result);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {NextApiHandler}
|
||||
*/
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
// res.setHeader("Access-Control-Allow-Credentials", "true");
|
||||
// res.setHeader("Access-Control-Allow-Origin", "*");
|
||||
// res.setHeader("Access-Control-Allow-Methods", "*");
|
||||
// res.setHeader("Access-Control-Allow-Headers", "*");
|
||||
|
||||
res.setHeader("Access-Control-Allow-Credentials", "true");
|
||||
res.setHeader("Access-Control-Allow-Origin", "*");
|
||||
// another common pattern
|
||||
// res.setHeader('Access-Control-Allow-Origin', req.headers.origin);
|
||||
res.setHeader("Access-Control-Allow-Methods", "GET,OPTIONS,PATCH,DELETE,POST,PUT");
|
||||
res.setHeader("Access-Control-Allow-Headers", "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version");
|
||||
|
||||
// await runMiddleware(req, res, cors);
|
||||
|
||||
res.json({
|
||||
title: "Hello There",
|
||||
message: "General Kenobi",
|
||||
});
|
||||
}
|
||||
import { NextApiHandler, NextApiRequest, NextApiResponse } from "next";
|
||||
import Cors from "cors";
|
||||
|
||||
const cors = Cors({
|
||||
methods: ["GET"],
|
||||
origin: "*",
|
||||
});
|
||||
|
||||
// Helper method to wait for a middleware to execute before continuing
|
||||
// And to throw an error when an error happens in a middleware
|
||||
function runMiddleware(req: NextApiRequest, res: NextApiResponse, fn: Function) {
|
||||
return new Promise((resolve, reject) => {
|
||||
fn(req, res, (result: any) => {
|
||||
if (result instanceof Error) {
|
||||
return reject(result);
|
||||
}
|
||||
|
||||
return resolve(result);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {NextApiHandler}
|
||||
*/
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
// res.setHeader("Access-Control-Allow-Credentials", "true");
|
||||
// res.setHeader("Access-Control-Allow-Origin", "*");
|
||||
// res.setHeader("Access-Control-Allow-Methods", "*");
|
||||
// res.setHeader("Access-Control-Allow-Headers", "*");
|
||||
|
||||
res.setHeader("Access-Control-Allow-Credentials", "true");
|
||||
res.setHeader("Access-Control-Allow-Origin", "*");
|
||||
// another common pattern
|
||||
// res.setHeader('Access-Control-Allow-Origin', req.headers.origin);
|
||||
res.setHeader("Access-Control-Allow-Methods", "GET,OPTIONS,PATCH,DELETE,POST,PUT");
|
||||
res.setHeader("Access-Control-Allow-Headers", "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version");
|
||||
|
||||
// await runMiddleware(req, res, cors);
|
||||
|
||||
res.json({
|
||||
title: "Hello There",
|
||||
message: "General Kenobi",
|
||||
});
|
||||
}
|
||||
|
||||
+178
-178
@@ -1,178 +1,178 @@
|
||||
/**
|
||||
* ==============================================================================
|
||||
* Imports
|
||||
* ==============================================================================
|
||||
*/
|
||||
import React from "react";
|
||||
import Head from "next/head";
|
||||
import type { InferGetStaticPropsType, GetStaticProps, GetStaticPaths } from "next";
|
||||
const datasquirel = require("datasquirel");
|
||||
|
||||
/** ********************************************** */
|
||||
/** ********************************************** */
|
||||
/** ********************************************** */
|
||||
|
||||
import GeneralLayout from "../../layouts/general_layout/GeneralLayout";
|
||||
import TextShuffler from "../../components/actions/TextShuffler";
|
||||
|
||||
/** ****************************************************************************** */
|
||||
/** ****************************************************************************** */
|
||||
/** ****************************************************************************** */
|
||||
/** ****************************************************************************** */
|
||||
/** ****************************************************************************** */
|
||||
/** ****************************************************************************** */
|
||||
|
||||
/**
|
||||
* ==============================================================================
|
||||
* Main Component { Functional }
|
||||
* ==============================================================================
|
||||
* @param {Object} props - Server props
|
||||
*/
|
||||
export default function BlogIndex({ blogPost }: InferGetStaticPropsType<typeof getStaticProps>) {
|
||||
// ## Get Contexts
|
||||
|
||||
/** ********************************************** */
|
||||
/** ********************************************** */
|
||||
/** ********************************************** */
|
||||
|
||||
// ## Javascript Variables
|
||||
|
||||
/** ********************************************** */
|
||||
/** ********************************************** */
|
||||
/** ********************************************** */
|
||||
|
||||
// ## React Hooks { useState, useEffect, useRef, etc ... }
|
||||
|
||||
/** ********************************************** */
|
||||
/** ********************************************** */
|
||||
/** ********************************************** */
|
||||
|
||||
// ## Function Return
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Head>
|
||||
<title>{blogPost.title} | Tben.me Blog</title>
|
||||
<meta
|
||||
name="description"
|
||||
content={blogPost.excerpt}
|
||||
/>
|
||||
</Head>
|
||||
<GeneralLayout>
|
||||
<div className="flex flex-col items-start gap-2 mb-8 max-w-6xl w-full">
|
||||
<button
|
||||
className="bg-transparent text-white/50 border-2 border-solid border-white/20"
|
||||
onClick={(e) => {
|
||||
window.history.back();
|
||||
}}
|
||||
>
|
||||
Back
|
||||
</button>
|
||||
<h1 className="m-0">
|
||||
<TextShuffler textInput={blogPost.title} />
|
||||
</h1>
|
||||
<span className="text-lg">
|
||||
<TextShuffler textInput={blogPost.excerpt} />
|
||||
</span>
|
||||
<span className="text-base opacity-50">
|
||||
<TextShuffler textInput={blogPost.date_created.substring(0, 24)} />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<span
|
||||
className="flex flex-col items-start max-w-6xl w-full gap-4 text-xl"
|
||||
dangerouslySetInnerHTML={{ __html: blogPost.body }}
|
||||
></span>
|
||||
</GeneralLayout>
|
||||
</React.Fragment>
|
||||
);
|
||||
/** ********************************************** */
|
||||
/** ********************************************** */
|
||||
/** ********************************************** */
|
||||
}
|
||||
|
||||
/** ****************************************************************************** */
|
||||
/** ****************************************************************************** */
|
||||
/** ****************************************************************************** */
|
||||
/** ****************************************************************************** */
|
||||
/** ****************************************************************************** */
|
||||
/** ****************************************************************************** */
|
||||
|
||||
/**
|
||||
* Server Side Props or Static Props
|
||||
* ==============================================================================
|
||||
*/
|
||||
export const getStaticProps: GetStaticProps = async ({ params }) => {
|
||||
// ## Environment processes
|
||||
|
||||
/** ********************************************** */
|
||||
/** ********************************************** */
|
||||
/** ********************************************** */
|
||||
|
||||
// ## User Authentication
|
||||
|
||||
/** ********************************************** */
|
||||
/** ********************************************** */
|
||||
/** ********************************************** */
|
||||
|
||||
// ## Page/Site Data Data Fetching
|
||||
const postsResponse = await datasquirel.get({
|
||||
key: process.env.DATASQUIREL_API_KEY,
|
||||
db: "tbenme",
|
||||
query: `select * from blog_posts WHERE slug='${params?.single}'`,
|
||||
});
|
||||
|
||||
const post = postsResponse.payload[0];
|
||||
|
||||
/** ********************************************** */
|
||||
/** ********************************************** */
|
||||
/** ********************************************** */
|
||||
|
||||
// ## Server Props Return
|
||||
return {
|
||||
props: {
|
||||
blogPost: post,
|
||||
},
|
||||
revalidate: 3600,
|
||||
};
|
||||
|
||||
/** ********************************************** */
|
||||
/** ********************************************** */
|
||||
/** ********************************************** */
|
||||
};
|
||||
|
||||
/** ****************************************************************************** */
|
||||
/** ****************************************************************************** */
|
||||
/** ****************************************************************************** */
|
||||
/** ****************************************************************************** */
|
||||
/** ****************************************************************************** */
|
||||
/** ****************************************************************************** */
|
||||
|
||||
/**
|
||||
* Server Side Props or Static Props
|
||||
* ==============================================================================
|
||||
*/
|
||||
export const getStaticPaths: GetStaticPaths = async () => {
|
||||
/**
|
||||
* Data fetching
|
||||
*
|
||||
* @abstract fetch date from the server or externnal source
|
||||
*/
|
||||
const postsResponse = await datasquirel.get({
|
||||
key: process.env.DATASQUIREL_API_KEY,
|
||||
db: "tbenme",
|
||||
query: `select slug from blog_posts`,
|
||||
});
|
||||
|
||||
const posts: { slug: string }[] | null = postsResponse.payload;
|
||||
|
||||
const paths = posts?.map((entry) => {
|
||||
return {
|
||||
params: { single: entry.slug },
|
||||
};
|
||||
});
|
||||
|
||||
return {
|
||||
paths: paths ? paths : [],
|
||||
fallback: "blocking",
|
||||
};
|
||||
};
|
||||
/**
|
||||
* ==============================================================================
|
||||
* Imports
|
||||
* ==============================================================================
|
||||
*/
|
||||
import React from "react";
|
||||
import Head from "next/head";
|
||||
import type { InferGetStaticPropsType, GetStaticProps, GetStaticPaths } from "next";
|
||||
const datasquirel = require("datasquirel");
|
||||
|
||||
/** ********************************************** */
|
||||
/** ********************************************** */
|
||||
/** ********************************************** */
|
||||
|
||||
import GeneralLayout from "../../layouts/general_layout/GeneralLayout";
|
||||
import TextShuffler from "../../components/actions/TextShuffler";
|
||||
|
||||
/** ****************************************************************************** */
|
||||
/** ****************************************************************************** */
|
||||
/** ****************************************************************************** */
|
||||
/** ****************************************************************************** */
|
||||
/** ****************************************************************************** */
|
||||
/** ****************************************************************************** */
|
||||
|
||||
/**
|
||||
* ==============================================================================
|
||||
* Main Component { Functional }
|
||||
* ==============================================================================
|
||||
* @param {Object} props - Server props
|
||||
*/
|
||||
export default function BlogIndex({ blogPost }: InferGetStaticPropsType<typeof getStaticProps>) {
|
||||
// ## Get Contexts
|
||||
|
||||
/** ********************************************** */
|
||||
/** ********************************************** */
|
||||
/** ********************************************** */
|
||||
|
||||
// ## Javascript Variables
|
||||
|
||||
/** ********************************************** */
|
||||
/** ********************************************** */
|
||||
/** ********************************************** */
|
||||
|
||||
// ## React Hooks { useState, useEffect, useRef, etc ... }
|
||||
|
||||
/** ********************************************** */
|
||||
/** ********************************************** */
|
||||
/** ********************************************** */
|
||||
|
||||
// ## Function Return
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Head>
|
||||
<title>{blogPost.title} | Tben.me Blog</title>
|
||||
<meta
|
||||
name="description"
|
||||
content={blogPost.excerpt}
|
||||
/>
|
||||
</Head>
|
||||
<GeneralLayout>
|
||||
<div className="flex flex-col items-start gap-2 mb-8 max-w-6xl w-full">
|
||||
<button
|
||||
className="bg-transparent text-white/50 border-2 border-solid border-white/20"
|
||||
onClick={(e) => {
|
||||
window.history.back();
|
||||
}}
|
||||
>
|
||||
Back
|
||||
</button>
|
||||
<h1 className="m-0">
|
||||
<TextShuffler textInput={blogPost.title} />
|
||||
</h1>
|
||||
<span className="text-lg">
|
||||
<TextShuffler textInput={blogPost.excerpt} />
|
||||
</span>
|
||||
<span className="text-base opacity-50">
|
||||
<TextShuffler textInput={blogPost.date_created.substring(0, 24)} />
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<span
|
||||
className="flex flex-col items-start max-w-6xl w-full gap-4 text-xl"
|
||||
dangerouslySetInnerHTML={{ __html: blogPost.body }}
|
||||
></span>
|
||||
</GeneralLayout>
|
||||
</React.Fragment>
|
||||
);
|
||||
/** ********************************************** */
|
||||
/** ********************************************** */
|
||||
/** ********************************************** */
|
||||
}
|
||||
|
||||
/** ****************************************************************************** */
|
||||
/** ****************************************************************************** */
|
||||
/** ****************************************************************************** */
|
||||
/** ****************************************************************************** */
|
||||
/** ****************************************************************************** */
|
||||
/** ****************************************************************************** */
|
||||
|
||||
/**
|
||||
* Server Side Props or Static Props
|
||||
* ==============================================================================
|
||||
*/
|
||||
export const getStaticProps: GetStaticProps = async ({ params }) => {
|
||||
// ## Environment processes
|
||||
|
||||
/** ********************************************** */
|
||||
/** ********************************************** */
|
||||
/** ********************************************** */
|
||||
|
||||
// ## User Authentication
|
||||
|
||||
/** ********************************************** */
|
||||
/** ********************************************** */
|
||||
/** ********************************************** */
|
||||
|
||||
// ## Page/Site Data Data Fetching
|
||||
const postsResponse = await datasquirel.get({
|
||||
key: process.env.DATASQUIREL_API_KEY,
|
||||
db: "tbenme",
|
||||
query: `select * from blog_posts WHERE slug='${params?.single}'`,
|
||||
});
|
||||
|
||||
const post = postsResponse.payload[0];
|
||||
|
||||
/** ********************************************** */
|
||||
/** ********************************************** */
|
||||
/** ********************************************** */
|
||||
|
||||
// ## Server Props Return
|
||||
return {
|
||||
props: {
|
||||
blogPost: post,
|
||||
},
|
||||
revalidate: 3600,
|
||||
};
|
||||
|
||||
/** ********************************************** */
|
||||
/** ********************************************** */
|
||||
/** ********************************************** */
|
||||
};
|
||||
|
||||
/** ****************************************************************************** */
|
||||
/** ****************************************************************************** */
|
||||
/** ****************************************************************************** */
|
||||
/** ****************************************************************************** */
|
||||
/** ****************************************************************************** */
|
||||
/** ****************************************************************************** */
|
||||
|
||||
/**
|
||||
* Server Side Props or Static Props
|
||||
* ==============================================================================
|
||||
*/
|
||||
export const getStaticPaths: GetStaticPaths = async () => {
|
||||
/**
|
||||
* Data fetching
|
||||
*
|
||||
* @abstract fetch date from the server or externnal source
|
||||
*/
|
||||
const postsResponse = await datasquirel.get({
|
||||
key: process.env.DATASQUIREL_API_KEY,
|
||||
db: "tbenme",
|
||||
query: `select slug from blog_posts`,
|
||||
});
|
||||
|
||||
const posts: { slug: string }[] | null = postsResponse.payload;
|
||||
|
||||
const paths = posts?.map((entry) => {
|
||||
return {
|
||||
params: { single: entry.slug },
|
||||
};
|
||||
});
|
||||
|
||||
return {
|
||||
paths: paths ? paths : [],
|
||||
fallback: "blocking",
|
||||
};
|
||||
};
|
||||
|
||||
+39
-39
@@ -1,39 +1,39 @@
|
||||
import React from "react";
|
||||
import Head from "next/head";
|
||||
import TextShuffler from "../components/actions/TextShuffler";
|
||||
import submitContactForm from "../functions/frontend/submitContactForm";
|
||||
import GeneralLayout from "../layouts/general_layout/GeneralLayout";
|
||||
import threeJsAnimations from "../functions/frontend/threeJsAnimations";
|
||||
import ContactForm from "../app/(components)/ContactForm";
|
||||
|
||||
const contact = () => {
|
||||
let [success, setSuccess] = React.useState(false);
|
||||
|
||||
return (
|
||||
<GeneralLayout>
|
||||
<Head>
|
||||
<title>Contact me</title>
|
||||
<meta
|
||||
name="description"
|
||||
content="Get in touch"
|
||||
/>
|
||||
</Head>
|
||||
|
||||
<div className="flex flex-col items-start max-w-6xl w-full">
|
||||
<h1>
|
||||
<TextShuffler textInput="Get in touch" />
|
||||
</h1>
|
||||
<span className="hero-sub-text">
|
||||
<TextShuffler
|
||||
textInput="Have a question? Want to work together? Send me a message!"
|
||||
delay={500}
|
||||
/>
|
||||
</span>
|
||||
|
||||
<ContactForm />
|
||||
</div>
|
||||
</GeneralLayout>
|
||||
);
|
||||
};
|
||||
|
||||
export default contact;
|
||||
import React from "react";
|
||||
import Head from "next/head";
|
||||
import TextShuffler from "../components/actions/TextShuffler";
|
||||
import submitContactForm from "../functions/frontend/submitContactForm";
|
||||
import GeneralLayout from "../layouts/general_layout/GeneralLayout";
|
||||
import threeJsAnimations from "../functions/frontend/threeJsAnimations";
|
||||
import ContactForm from "../app/(components)/ContactForm";
|
||||
|
||||
const contact = () => {
|
||||
let [success, setSuccess] = React.useState(false);
|
||||
|
||||
return (
|
||||
<GeneralLayout>
|
||||
<Head>
|
||||
<title>Contact me</title>
|
||||
<meta
|
||||
name="description"
|
||||
content="Get in touch"
|
||||
/>
|
||||
</Head>
|
||||
|
||||
<div className="flex flex-col items-start max-w-6xl w-full">
|
||||
<h1>
|
||||
<TextShuffler textInput="Get in touch" />
|
||||
</h1>
|
||||
<span className="hero-sub-text">
|
||||
<TextShuffler
|
||||
textInput="Have a question? Want to work together? Send me a message!"
|
||||
delay={500}
|
||||
/>
|
||||
</span>
|
||||
|
||||
<ContactForm />
|
||||
</div>
|
||||
</GeneralLayout>
|
||||
);
|
||||
};
|
||||
|
||||
export default contact;
|
||||
|
||||
+54
-54
@@ -1,54 +1,54 @@
|
||||
import React from "react";
|
||||
import Head from "next/head";
|
||||
import TextShuffler from "../components/actions/TextShuffler";
|
||||
import GeneralLayout from "../layouts/general_layout/GeneralLayout";
|
||||
import PortfolioEntry from "../components/PortfolioEntry";
|
||||
|
||||
const myWork = () => {
|
||||
const portfolioEntries = require("../components/portfolioEntries.json");
|
||||
|
||||
return (
|
||||
<GeneralLayout>
|
||||
<Head>
|
||||
<title>My Work | Tben</title>
|
||||
<meta
|
||||
name="description"
|
||||
content="Some of my Work"
|
||||
/>
|
||||
</Head>
|
||||
|
||||
<div className="flex flex-col items-start w-full max-w-6xl">
|
||||
<h1>
|
||||
<TextShuffler textInput="My Work" />
|
||||
</h1>
|
||||
<span className="hero-sub-text mb-2">
|
||||
<TextShuffler
|
||||
textInput="Some of the projects I've worked on"
|
||||
delay={500}
|
||||
/>
|
||||
</span>
|
||||
|
||||
<div className="portfolio-entries-block mt-4">
|
||||
{portfolioEntries.map((entry) => (
|
||||
<PortfolioEntry
|
||||
key={entry.title}
|
||||
title={entry.title}
|
||||
description={entry.description}
|
||||
url={entry.url}
|
||||
image={entry.image}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</GeneralLayout>
|
||||
);
|
||||
};
|
||||
|
||||
export default myWork;
|
||||
|
||||
// {
|
||||
// "title": "Stirrmedia Social webapp",
|
||||
// "description": "A new social media experience without censorship",
|
||||
// "url": "https://stirrmedia.com",
|
||||
// "image": "/images/stirrmediascreenshot.png"
|
||||
// },
|
||||
import React from "react";
|
||||
import Head from "next/head";
|
||||
import TextShuffler from "../components/actions/TextShuffler";
|
||||
import GeneralLayout from "../layouts/general_layout/GeneralLayout";
|
||||
import PortfolioEntry from "../components/PortfolioEntry";
|
||||
|
||||
const myWork = () => {
|
||||
const portfolioEntries = require("../components/portfolioEntries.json");
|
||||
|
||||
return (
|
||||
<GeneralLayout>
|
||||
<Head>
|
||||
<title>My Work | Tben</title>
|
||||
<meta
|
||||
name="description"
|
||||
content="Some of my Work"
|
||||
/>
|
||||
</Head>
|
||||
|
||||
<div className="flex flex-col items-start w-full max-w-6xl">
|
||||
<h1>
|
||||
<TextShuffler textInput="My Work" />
|
||||
</h1>
|
||||
<span className="hero-sub-text mb-2">
|
||||
<TextShuffler
|
||||
textInput="Some of the projects I've worked on"
|
||||
delay={500}
|
||||
/>
|
||||
</span>
|
||||
|
||||
<div className="portfolio-entries-block mt-4">
|
||||
{portfolioEntries.map((entry) => (
|
||||
<PortfolioEntry
|
||||
key={entry.title}
|
||||
title={entry.title}
|
||||
description={entry.description}
|
||||
url={entry.url}
|
||||
image={entry.image}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</GeneralLayout>
|
||||
);
|
||||
};
|
||||
|
||||
export default myWork;
|
||||
|
||||
// {
|
||||
// "title": "Stirrmedia Social webapp",
|
||||
// "description": "A new social media experience without censorship",
|
||||
// "url": "https://stirrmedia.com",
|
||||
// "image": "/images/stirrmediascreenshot.png"
|
||||
// },
|
||||
|
||||
Reference in New Issue
Block a user