Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions app/[locale]/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import {
isSupportedLocale,
metadataForLocale,
supportedLocales,
} from "@/lib/i18n";
import type { Metadata } from "next";
import { notFound } from "next/navigation";

type LocaleLayoutProps = Readonly<{
children: React.ReactNode;
params: { locale: string };
}>;

export function generateStaticParams() {
return supportedLocales
.filter((locale) => locale !== "en")
.map((locale) => ({ locale }));
}

export function generateMetadata({ params }: LocaleLayoutProps): Metadata {
return isSupportedLocale(params.locale)
? metadataForLocale(params.locale)
: {};
}

export default function LocaleLayout({ children, params }: LocaleLayoutProps) {
if (!isSupportedLocale(params.locale) || params.locale === "en") {
notFound();
}

return children;
}
3 changes: 3 additions & 0 deletions app/[locale]/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import Home from "../page";

export default Home;
17 changes: 3 additions & 14 deletions app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,13 @@
import type { Metadata, ResolvingMetadata, Viewport } from "next";
import type { Metadata, Viewport } from "next";
import { Inter } from "next/font/google";
import { cn } from "@/lib/utils";
import { Providers } from "@/components/providers/providers";
import { metadataForLocale } from "@/lib/i18n";
import "./globals.css";

const inter = Inter({ subsets: ["latin"] });

export async function generateMetadata(
{ params, searchParams }: any,
parent: ResolvingMetadata
): Promise<Metadata> {
return {
title: "Gibwork | Find Talent, Find Work",
description:
"Gibwork connects skilled professionals with freelance work opportunities, offering seamless integration with all Solana tokens for secure and efficient transactions.",
openGraph: {
images: [`https://cdn.gib.work/metadata/default.png`],
},
};
}
export const metadata: Metadata = metadataForLocale("en");

export const viewport: Viewport = {
themeColor: "#ffffff",
Expand Down
9 changes: 6 additions & 3 deletions components/cta.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ import { motion } from "framer-motion";
import { FADE_UP_ANIMATION_VARIANTS } from "@/lib/framer-variants";
import Link from "next/link";
import { siteConfig } from "@/lib/site-config";
import { useSiteCopy } from "./use-site-copy";

export function CTA() {
const { copy } = useSiteCopy();

return (
<motion.section
initial="hidden"
Expand All @@ -28,19 +31,19 @@ export function CTA() {
variants={FADE_UP_ANIMATION_VARIANTS}
className="font-semibold text-3xl sm:text-4xl text-center"
>
Start exploring
{copy.cta.heading}
</motion.h2>
<motion.p
variants={FADE_UP_ANIMATION_VARIANTS}
className="text-center mt-2 text-muted-foreground"
>
Check out gibwork and create or complete your very first work.
{copy.cta.description}
</motion.p>

<motion.div variants={FADE_UP_ANIMATION_VARIANTS}>
<Button asChild className="mt-8 group">
<Link href={siteConfig.appUrl} target="_blank">
Get Started
{copy.cta.button}
<ArrowRight className="size-0 group-hover:size-5 transition-all -ml-2 group-hover:ml-0" />
</Link>
</Button>
Expand Down
44 changes: 10 additions & 34 deletions components/faq.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
"use client";

import { Button } from "@/components/ui/button";
import { ArrowRight } from "lucide-react";
import Ripple from "./ui/ripple";
import {
Accordion,
AccordionContent,
Expand All @@ -11,8 +8,11 @@ import {
} from "@/components/ui/accordion";
import { motion } from "framer-motion";
import { FADE_UP_ANIMATION_VARIANTS } from "@/lib/framer-variants";
import { useSiteCopy } from "./use-site-copy";

export function Faq() {
const { copy } = useSiteCopy();

return (
<motion.section
initial="hidden"
Expand All @@ -33,41 +33,17 @@ export function Faq() {
variants={FADE_UP_ANIMATION_VARIANTS}
className="font-semibold text-3xl sm:text-4xl shrink-0 lg:text-left text-center"
>
FAQs
{copy.faq.heading}
</motion.h2>

<motion.div variants={FADE_UP_ANIMATION_VARIANTS} className="grow lg:max-w-3xl">
<Accordion type="single" collapsible>
<AccordionItem value="item-6">
<AccordionTrigger>How do I create Work on Gibwork?</AccordionTrigger>
<AccordionContent>
Under the earnings display on the apps home page, click the
&quot;Create&quot; buttons for creating Open Source Bounties and Task. These buttons guide you through the process of creating and posting jobs on the
platform.
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-1">
<AccordionTrigger>
What&apos;s the difference between a bounty and a task?
</AccordionTrigger>
<AccordionContent>
A bounty is a Github issue with a monetary reward. A task is a
specific, often smaller job that needs to be completed.
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-2">
<AccordionTrigger>How do I get paid for completed work?</AccordionTrigger>
<AccordionContent>
Once your work is approved by the creator, the funds will be released to your noncustodial wallet.
</AccordionContent>
</AccordionItem>
<AccordionItem value="item-3">
<AccordionTrigger>What payment methods does gibwork support?</AccordionTrigger>
<AccordionContent>
We only support wallet transactions, i.e., depositing the winning amount directly to
your wallet in the form of crypto or stablecoins.
</AccordionContent>
</AccordionItem>
{copy.faq.items.map((item, index) => (
<AccordionItem key={item.question} value={`item-${index}`}>
<AccordionTrigger>{item.question}</AccordionTrigger>
<AccordionContent>{item.answer}</AccordionContent>
</AccordionItem>
))}
{/* <AccordionItem value="item-4">
<AccordionTrigger>Are there any fees for using gibwork?</AccordionTrigger>
<AccordionContent>
Expand Down
31 changes: 18 additions & 13 deletions components/footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,11 @@ import { ArrowRight, ExternalLink } from "lucide-react";
import { YoutubeLogoMark } from "./logo/youtube";
import { DiscordLogoMark } from "./logo/discord";
import { TwitterLogoMark } from "./logo/twitter";
import { useSiteCopy } from "./use-site-copy";

export function Footer() {
const { copy, withLocale } = useSiteCopy();

return (
<footer className="relative w-full sm:pb-12 sm:px-6">
<div className="w-full max-w-7xl mx-auto p-4 sm:p-8 shadow-sm sm:border border-0 border-t sm:rounded-lg rounded-none flex flex-col">
Expand All @@ -19,28 +22,30 @@ export function Footer() {
<Image alt="" src={logo} className="size-10 rounded-md bg-muted" />
<p className="font-bold text-2xl">gibwork</p>
</div>
<h2 className="font-semibold text-2xl sm:text-3xl mt-4">Join our community</h2>
<h2 className="font-semibold text-2xl sm:text-3xl mt-4">
{copy.footer.heading}
</h2>
<p className="text-muted-foreground sm:text-base text-sm">
Meet like-minded people and find work opportunities easily.
{copy.footer.description}
</p>
</div>

<div className="grid grid-cols-2 gap-24">
<div className="text-sm flex flex-col gap-2 items-start">
<p className="font-semibold">Quick links</p>
<p className="font-semibold">{copy.footer.quickLinks}</p>
<Link
href={"/#about"}
href={withLocale("/#about")}
className="text-muted-foreground transition-all hover:text-foreground group"
>
About
{copy.nav.about}
<ArrowRight className="inline-block size-4 group-hover:scale-100 scale-0 transition-all ml-1" />
</Link>

<Link
href={"/#testimonial"}
href={withLocale("/#testimonial")}
className="text-muted-foreground transition-all hover:text-foreground group"
>
Testimonial
{copy.nav.testimonial}
<ArrowRight className="inline-block size-4 group-hover:scale-100 scale-0 transition-all ml-1" />
</Link>
{/* <Link
Expand All @@ -51,30 +56,30 @@ export function Footer() {
<ArrowRight className="inline-block size-4 group-hover:scale-100 scale-0 transition-all ml-1" />
</Link> */}
<Link
href={"/#faq"}
href={withLocale("/#faq")}
className="text-muted-foreground transition-all hover:text-foreground group"
>
FAQ
{copy.nav.faq}
<ArrowRight className="inline-block size-4 group-hover:scale-100 scale-0 transition-all ml-1" />
</Link>
<Link
href={"https://docs.gib.work/"}
target="_blank"
className="text-muted-foreground transition-all hover:text-foreground group"
>
Docs
{copy.nav.docs}
<ArrowRight className="inline-block size-4 group-hover:scale-100 scale-0 transition-all ml-1" />
</Link>
</div>

<div className="text-sm flex flex-col gap-2 items-start">
<p className="font-semibold">Resources</p>
<p className="font-semibold">{copy.footer.resources}</p>
<Link
href={"https://legal.gib.work/privacy-policy.pdf"}
target="_blank"
className="text-muted-foreground transition-all hover:text-foreground group"
>
Privacy Policy
{copy.footer.privacy}
<ExternalLink className="inline-block size-4 group-hover:scale-100 scale-0 transition-all ml-1" />
</Link>

Expand Down Expand Up @@ -110,7 +115,7 @@ export function Footer() {
</Link>
</div>

<p className="text-xs text-muted-foreground">Made with ♥ by gibwork</p>
<p className="text-xs text-muted-foreground">{copy.footer.madeBy}</p>
</div>
</div>
</footer>
Expand Down
15 changes: 8 additions & 7 deletions components/hero.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@ import { siteConfig } from "@/lib/site-config";
import SparklesText from "./ui/sparkles-text";
import { motion } from "framer-motion";
import { FADE_UP_ANIMATION_VARIANTS } from "@/lib/framer-variants";
import { Clipboard } from "flowbite-react"
import { useSiteCopy } from "./use-site-copy";


export function Hero() {
const { copy } = useSiteCopy();

return (
<motion.section
initial="hidden"
Expand All @@ -33,14 +35,14 @@ export function Hero() {
<motion.div variants={FADE_UP_ANIMATION_VARIANTS}>
<Badge variant={"secondary"}>
<div className="size-1 rounded-full bg-muted-foreground mr-2" />
Introducing gibwork
{copy.hero.badge}
<div className="size-1 rounded-full bg-muted-foreground ml-2" />
</Badge>
</motion.div>

<motion.div variants={FADE_UP_ANIMATION_VARIANTS} className="relative z-0">
<SparklesText
text="Find Talent, Find Work"
text={copy.hero.heading}
className="font-semibold text-5xl sm:text-6xl mt-4"
/>
</motion.div>
Expand All @@ -49,14 +51,13 @@ export function Hero() {
variants={FADE_UP_ANIMATION_VARIANTS}
className="max-w-2xl mt-4 w-full sm:text-lg text-muted-foreground"
>
Whether you&apos;re searching for your next gig or seeking skilled individuals, our platform
connects you with the perfect match.
{copy.hero.description}
</motion.p>

<motion.div variants={FADE_UP_ANIMATION_VARIANTS}>
<Button className="group mt-8" asChild>
<Link href={siteConfig.appUrl} target="_blank">
Get Started For Free
{copy.hero.cta}
<ArrowRight className="size-0 group-hover:size-5 transition-all -ml-2 group-hover:ml-0" />
</Link>
</Button>
Expand All @@ -67,7 +68,7 @@ export function Hero() {
className="flex items-center gap-2 text-sm mt-4"
>

<span className="opacity-80">powered by</span>
<span className="opacity-80">{copy.hero.poweredBy}</span>
<Link
href={"https://solana.com/"}
target="_blank"
Expand Down
41 changes: 41 additions & 0 deletions components/locale-switcher.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"use client";

import {
getLocaleFromPathname,
localizePath,
messages,
type Locale,
} from "@/lib/i18n";
import { usePathname, useRouter } from "next/navigation";
import { useEffect } from "react";

export function LocaleSwitcher() {
const pathname = usePathname();
const router = useRouter();
const locale = getLocaleFromPathname(pathname);
const copy = messages[locale].language;

useEffect(() => {
document.documentElement.lang = locale;
}, [locale]);

function changeLocale(nextLocale: Locale) {
const hash = window.location.hash;
router.push(`${localizePath(pathname, nextLocale)}${hash}`);
}

return (
<label className="flex items-center gap-2 text-xs text-muted-foreground">
<span className="font-medium">{copy.label}</span>
<select
aria-label={copy.label}
className="h-8 rounded-md border bg-background px-2 text-xs text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring"
onChange={(event) => changeLocale(event.target.value as Locale)}
value={locale}
>
<option value="en">{copy.english}</option>
<option value="es">{copy.spanish}</option>
</select>
</label>
);
}
Loading