Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a982db2

Browse files
committed
feat: finish gpg key setup
1 parent b857533 commit a982db2

File tree

6 files changed

+105
-16
lines changed

6 files changed

+105
-16
lines changed

src/app/(pages)/contact/page.tsx

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,38 @@ import { Button } from '@/app/components/ui/button';
55
import { Heading1 as H1 } from '@/app/components/reusables/headers';
66
import { TextContent as C } from '@/app/components/reusables/content';
77
import { motion } from 'framer-motion';
8+
import { Toaster, toast } from 'sonner';
9+
import { useCopyToClipboard } from 'react-use';
10+
11+
import { EMAIL, GPG_PUBLIC_KEY_INTERNAL_URL } from '@/lib/constants';
812

9-
import { EMAIL } from '@/lib/constants';
1013
export default function Main() {
14+
const [, copyToClipboard] = useCopyToClipboard();
15+
16+
const successToast = () => {
17+
toast.message('GPG KEY ID: 79821E0224D34EC4969FF6A8E5168EE090AE80D0', {
18+
description: 'Public key has been copied to your clipboard',
19+
});
20+
};
21+
22+
const failToast = (message?: string) => {
23+
toast.message('Oops! Looks like something went wrong!', {
24+
description: message,
25+
});
26+
};
27+
28+
async function copyGPG() {
29+
const res = await fetch(GPG_PUBLIC_KEY_INTERNAL_URL, {
30+
method: 'GET',
31+
});
32+
if (!res.ok) {
33+
const failureMessage = await res.text();
34+
failToast(failureMessage);
35+
}
36+
const key = await res.text();
37+
copyToClipboard(key);
38+
successToast();
39+
}
1140
return (
1241
<div className="flex flex-col">
1342
<main className="flex-1">
@@ -20,15 +49,25 @@ export default function Main() {
2049
</H1>
2150
<div className="mx-auto max-w-[600px]">
2251
<C>
23-
I&apos;m available for business inquiries, and new
24-
opportunities. Feel free to reach out through email. I will
25-
get back to you as soon as possible.
52+
Feel free to reach out through email. I will get back to you
53+
as soon as possible. If you prefer to communicate securely
54+
use my <span> </span>
55+
<button
56+
onClick={async () => {
57+
await copyGPG();
58+
}}
59+
>
60+
<strong className="text-white glows underline">
61+
GPG
62+
</strong>
63+
</button>
64+
<span> </span> key to encrypt messages before you
2665
</C>
2766
</div>
2867
</div>
2968
<div className="mx-auto max-w-sm space-y-2">
3069
<motion.div
31-
className="space-y-4 glowsup"
70+
className="space-y-4 "
3271
initial={{
3372
opacity: 0,
3473
scale: 0.8,
@@ -43,7 +82,9 @@ export default function Main() {
4382
}}
4483
>
4584
<Link href={`mailto:${EMAIL}`}>
46-
<Button variant="navbar">email me</Button>
85+
<Button className="glowsup" variant="navbar">
86+
email me
87+
</Button>
4788
</Link>
4889
</motion.div>
4990
</div>
@@ -52,6 +93,7 @@ export default function Main() {
5293
</section>
5394
</main>
5495
<Footer />
96+
<Toaster />
5597
</div>
5698
);
5799
}

src/app/(pages)/services/page.tsx

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,14 @@ export default function Component() {
4747
transition={transition}
4848
className="dimmed-1 md:text-xl/relaxed lg:text-base/relaxed xl:text-xl/relaxed"
4949
>
50-
Our team of experts is here to help you succeed. From
51-
architecting scalable APIs to designing beautiful user
52-
interfaces, we have the skills and experience to bring your
53-
ideas to life.
50+
If you use my
51+
<span> </span>
52+
<strong className="text-white glows underline">stack</strong>
53+
<span> </span>
54+
I&apos;m here to help. From architecting scalable APIs and
55+
designing beautiful user interfaces to writing quality code,
56+
I&apos;ve got the skills and experience to bring your ideas to
57+
life.
5458
</motion.p>
5559
</div>
5660
</div>
@@ -80,8 +84,9 @@ export default function Component() {
8084
Consulting
8185
</h3>
8286
<p className="text-center md:text-base/relaxed dimmed-1">
83-
Migrate to the cloud with confidence. Our team can help you
84-
design and deploy a scalable, secure architecture.
87+
Invite me to become an extension of your team. Working
88+
directly with you on a daily basis from code audits to
89+
assistence in development
8590
</p>
8691
</div>
8792
</Link>
@@ -111,8 +116,8 @@ export default function Component() {
111116
Software Solutions
112117
</h3>
113118
<p className="text-center md:text-base/relaxed dimmed-1">
114-
Commercial end-to-end software solutions tailored to meet your
115-
specific needs, from ideation to deployment.
119+
Commercial end-to-end software solutions covering the whole
120+
softwre lifecyle, from ideation to deployment.
116121
</p>
117122
</div>
118123
</Link>

src/app/api/v1/gpg/route.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { NextRequest, NextResponse } from 'next/server';
2+
import { NewType } from 'ts-roids';
3+
import { GPG_PUBLIC_KEY_EXTERNAL_URL } from '@/lib/constants';
4+
5+
type Key = NewType<'Key', string>;
6+
type Err = string;
7+
8+
export async function GET(
9+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
10+
_req: NextRequest
11+
): Promise<NextResponse<Key> | NextResponse<Err>> {
12+
try {
13+
const res = await fetch(GPG_PUBLIC_KEY_EXTERNAL_URL, {
14+
method: 'GET',
15+
mode: 'no-cors',
16+
});
17+
if (!res.ok) {
18+
return new NextResponse('Failed to fetch the public key', {
19+
status: 424,
20+
});
21+
}
22+
23+
const key = (await res.text()) as Key;
24+
return new NextResponse(key);
25+
} catch (e) {
26+
console.log(e);
27+
return new NextResponse('Something unexpected happened', {
28+
status: 500,
29+
});
30+
}
31+
}

src/app/components/protos/hero-section.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,9 @@ function TypingAnimation() {
1111
useEffect(() => {
1212
const typed = new Typed(el.current, {
1313
strings: [
14-
'I <span class="glows">do</span> software',
14+
'I <span class="glows">make</span> software',
1515
'I <span class="glows">solve</span> software',
16+
'I <span class="glows">architect</span> software',
1617
],
1718
typeSpeed: 50,
1819
loop: true,
@@ -87,7 +88,7 @@ export default function HeroSection() {
8788
>
8889
<TextContent>
8990
Welcome to my corner of the internet where I share my thoughts
90-
and conduct my business. You can read my blogs or checkout my
91+
and conduct my business. You can read my blogs, checkout my
9192
services, or learn more about me, and if you like what you see
9293
</TextContent>
9394
</motion.div>

src/lib/constants.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,7 @@ export const Status = {
1212
BAD_REQUEST: 400,
1313
NOT_FOUND: 404,
1414
};
15+
16+
export const DEFAULT_API_URI = '/api/v1';
17+
export const GPG_PUBLIC_KEY_EXTERNAL_URL = 'https://github.com/ashgw.gpg';
18+
export const GPG_PUBLIC_KEY_INTERNAL_URL = SITE_URL + DEFAULT_API_URI + '/gpg';

src/lib/types/global.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,10 @@ export type Ok<T> = {
1010
data: T;
1111
};
1212

13+
export type ErrText = string;
14+
export type OkText<T> = T;
15+
1316
export type AsyncResponse<T> = Promise<NextResponse<Ok<T>> | NextResponse<Err>>;
17+
export type NextPlainTextResponse<T> = Promise<
18+
NextResponse<Ok<T>> | NextResponse<ErrText>
19+
>;

0 commit comments

Comments
 (0)