Skip to content

Commit

Permalink
Merge pull request #1 from rocket-connect/new-site
Browse files Browse the repository at this point in the history
New site
  • Loading branch information
danstarns authored Jun 7, 2024
2 parents 7513154 + af0a7cc commit cb237c6
Show file tree
Hide file tree
Showing 175 changed files with 102,026 additions and 8,088 deletions.
5 changes: 5 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
METADATA_BASE_URL=http://localhost:4000
EMAIL_SENDER_ADDRESS=""
EMAIL_SENDER_PASSWORD=""
EMAIL_HOST=""
GA_KEY=""
20 changes: 20 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module.exports = {
extends: [
'next',
'next/core-web-vitals',
'eslint:recommended',
'plugin:react/recommended',
'plugin:@typescript-eslint/recommended',
'prettier',
],
plugins: ['react', '@typescript-eslint'],
parserOptions: {
ecmaVersion: 2021,
sourceType: 'module',
},
rules: {
'react/react-in-jsx-scope': 'off',
'react/prop-types': 'off',
'@typescript-eslint/no-explicit-any': 'off',
},
};
22 changes: 22 additions & 0 deletions .github/actions/setup-project/action.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
name: Setup Project

inputs:
node-version:
required: false
default: 18

runs:
using: composite
steps:
- uses: actions/setup-node@v3
with:
node-version: ${{ inputs.node-version }}
- name: Install dependencies
run: npm install
shell: bash
- name: Lint project
run: npm run lint
shell: bash
- name: Build project
run: npm run build
shell: bash
14 changes: 6 additions & 8 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
name: Node Github CI
name: rconnect.tech

on:
push:
branches:
- main

jobs:
deploy:
deploy-preview:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/setup-project
- name: SSH and deploy node app
uses: appleboy/ssh-action@master
with:
Expand All @@ -19,13 +21,9 @@ jobs:
script: |
export NVM_DIR=~/.nvm
source ~/.nvm/nvm.sh
cd rconnect.tech
cd ./rconnect.tech
git reset --hard
git pull origin main
cd ./frontend
npm install
npm run build
cd ../backend
npm install
npm run build
pm2 restart website
pm2 restart rconnect.tech
14 changes: 14 additions & 0 deletions .github/workflows/pr.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name: PR Checks

on:
pull_request:
branches:
- main

jobs:
deploy-preview:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- uses: ./.github/actions/setup-project
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -104,4 +104,6 @@ dist
.tern-port

.DS_Store
settings.json
settings.json

.env.local
8 changes: 8 additions & 0 deletions .prettierrc.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module.exports = {
semi: true,
trailingComma: 'all',
singleQuote: true,
printWidth: 100,
tabWidth: 2,
plugins: ['prettier-plugin-tailwindcss'],
};
39 changes: 7 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,40 +1,15 @@
# rconnect.tech

Frontend & Backend For www.rconnect.tech
Source www.rconnect.tech

## Frontend
## Installation

React app built with Typescript & Tailwind.

## Backend

Node.js express server serving the frontend and handling the API requests to the `/contact` endpoint.

## Getting Started

The repo is **not** managed by a monorepo at this time.

For dev you mostly only need to run the frontend, the backend is only used in Digital Ocean.

#### Running DEV

Run the Webpack dev server on.

```
cd ./frontend
npm i
npm run dev
```bash
npm install
```

#### Simulating Production

To simulate the production environment, you can setup and run the express server.
## Run Dev

```
cd ./frontend
npm run build # Build the client dist first
cd ../backend
npm run build
npm run start
```bash
npm run dev
```
50 changes: 50 additions & 0 deletions app/about/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { Hero } from '@/components/shared/Hero';
import { SocialProofSection } from '@/components/templates/SocialProofSection';
import { TwoColumn } from '@/components/shared/TwoColumn';
import { Cta } from '@/components/shared/Cta';
import { Footer } from '@/components/shared/Footer';
import { Header } from '@/components/shared/Header';
import { Main } from '@/components/shared/Main';
import { about } from '@/content/about';
import Image from 'next/image';
import { Metadata } from 'next';

export const metadata: Metadata = {
title: 'About Us | Rconnect.tech',
description: about.hero.intro,
openGraph: {
images: '/images/blog-default-preview.png',
},
};

export default function About() {
return (
<Main>
<Header />
<Hero content={about.hero} cta={true} />
{about.sections.map((section, index) => (
<TwoColumn key={'servicecol-' + index} index={index}>
<div className="flex flex-col gap-4">
<Image
src={section.image}
width={609}
height={380}
alt=""
className="h-width aspect-video rounded-xl object-cover object-top"
/>
<p className="text-center italic">{section.imageDescription}</p>
</div>
<div className="flex h-full flex-col justify-center gap-8 lg:w-1/2">
<div className="flex flex-col gap-4">
<h4 className="text-2xl font-bold">{section.title}</h4>
<p>{section.content}</p>
</div>
</div>
</TwoColumn>
))}
<SocialProofSection />
<Cta />
<Footer />
</Main>
);
}
39 changes: 39 additions & 0 deletions app/api/contact/route.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { createTransport } from 'nodemailer';

const transporter = createTransport({
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore - this is a bug in the types?
host: process.env.EMAIL_HOST,
secureConnection: false,
port: 587,
tls: {
ciphers: 'SSLv3',
},
auth: {
user: process.env.EMAIL_SENDER_ADDRESS,
pass: process.env.EMAIL_SENDER_PASSWORD,
},
});

async function handler({ name, email, message }: { name: string; email: string; message: string }) {
try {
await transporter.sendMail({
to: email,
from: process.env.EMAIL_SENDER_ADDRESS,
subject: 'Rocket Connect Contact',
text: `Thank you for contacting us ${name}, we will get back to you as soon as possible. Your message '${message}'`,
cc: [process.env.EMAIL_SENDER_ADDRESS as string, '[email protected]'],
});
} catch (error) {
console.error('Error sending email', error);
throw new Error('Error sending email');
}
}

export async function POST(req: Request) {
const { email, name, message } = await req.json();

await handler({ email, name, message });

return Response.json({});
}
96 changes: 96 additions & 0 deletions app/blog/[slug]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import fs from 'fs';
import path from 'path';
import matter from 'gray-matter';
import { MDXRemote } from 'next-mdx-remote/rsc';
import YouTube from '@/components/shared/Youtube';
import Code from '@/components/shared/Code';
import { Cta } from '@/components/shared/Cta';
import { Footer } from '@/components/shared/Footer';
import { Header } from '@/components/shared/Header';
import { Main } from '@/components/shared/Main';
import { Container } from '@/components/shared/Container';
import { ChevronLeft } from 'lucide-react';
import Link from 'next/link';
import { categoryColor, cn, formatdate, metadataBase } from '@/lib/utils';
import { Metadata, ResolvingMetadata } from 'next';

type Props = {
params: { slug: string };
};

export async function generateMetadata(
{ params }: Props,
parent: ResolvingMetadata,
): Promise<Metadata> {
const props = await getPost(params);
const previousImages = (await parent).openGraph?.images || [];

return {
title: `Blog | ${props.frontMatter.title}`,
description: props.frontMatter.description,
metadataBase,
openGraph: {
images: [props.frontMatter.hero, ...previousImages],
},
};
}

async function getPost({ slug }: { slug: string }) {
const markdownFile = fs.readFileSync(path.join('content/posts', slug + '.mdx'), 'utf-8');
const { data: frontMatter, content } = matter(markdownFile);
return {
frontMatter,
slug,
content,
};
}

export async function generateStaticParams() {
const files = fs.readdirSync(path.join('content/posts'));
const params = files.map((filename) => ({
slug: filename.replace('.mdx', ''),
}));
return params;
}

export default async function Page({ params }: { params: { slug: string } }) {
const props = await getPost(params);
const components = {
pre: Code,
YouTube,
};

const formattedDate = formatdate(props.frontMatter.date);
const color = categoryColor(props.frontMatter.category);

return (
<Main>
<Header />
<Container className="lg:py-0">
<div className="relative mx-auto max-w-2xl">
<Link href={'/blog'}>
<div className="sticky left-0 top-24 z-10 -ml-24 hidden h-10 w-10 items-center justify-center rounded-full border border-slate-300 bg-background-main transition-all ease-in hover:scale-[1.03] hover:shadow-sm dark:border-slate-600 dark:bg-background-invert lg:flex">
<ChevronLeft className="h-6 w-6 stroke-slate-500 dark:stroke-slate-400" />
</div>
</Link>
<article>
<div className="flex w-full items-center gap-1">
<div className={cn('text-md font-bold uppercase')} style={{ color }}>
{props.frontMatter.category}
</div>
<div className="text-slate-600 dark:text-slate-400">· {formattedDate}</div>
</div>
<h1 className="mb-4 text-4xl font-bold text-foreground-main dark:text-foreground-invert">
{props.frontMatter.title}
</h1>
<div className="prose-a:text-bold prose prose-sm mx-auto text-foreground-main md:prose-base lg:prose-lg prose-headings:text-foreground-main prose-a:text-foreground-main prose-a:visited:text-foreground-main prose-ol:list-decimal prose-ul:list-disc dark:text-foreground-invert dark:prose-headings:text-foreground-invert dark:prose-a:text-foreground-invert prose-a:dark:visited:text-foreground-invert">
<MDXRemote source={props.content} components={components} />
</div>
</article>
</div>
</Container>
<Cta />
<Footer />
</Main>
);
}
Loading

0 comments on commit cb237c6

Please sign in to comment.