Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for automatic code formatting and liniting #46

Open
wants to merge 4 commits into
base: develop
Choose a base branch
from
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
26 changes: 26 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"env": {
"browser": true,
"es2021": true
},
"extends": [
"eslint:recommended",
"plugin:react/jsx-runtime",
"plugin:@typescript-eslint/recommended",
"prettier"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": "latest",
"sourceType": "module"
},
"plugins": [
"react",
"@typescript-eslint"
],
"rules": {
}
}
1 change: 1 addition & 0 deletions .husky/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
_
4 changes: 4 additions & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npx lint-staged
43 changes: 43 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# next.js
/.next/
/out/

# production
/build

# misc
.DS_Store
*.pem

# debug
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.pnpm-debug.log*

# local env files
.env*
.env.local
.env.development.local
.env.test.local
.env.production.local

# vercel
.vercel

# typescript
*.tsbuildinfo

# Build files
yarn.lock
package-lock.json
6 changes: 6 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"printWidth": 120,
"semi": true,
"bracketSameLine": true,
"singleAttributePerLine": false
}
104 changes: 43 additions & 61 deletions components/ActiveLink.tsx
Original file line number Diff line number Diff line change
@@ -1,63 +1,45 @@
import { useRouter } from 'next/router'
import Link, { LinkProps } from 'next/link'
import React, { useState, useEffect, ReactElement, Children } from 'react'
import { useRouter } from "next/router";
import Link, { LinkProps } from "next/link";
import React, { useState, useEffect, ReactElement, Children } from "react";

type ActiveLinkProps = LinkProps & {
children: ReactElement
activeClassName: string
}

const ActiveLink = ({
children,
activeClassName,
...props
}: ActiveLinkProps) => {
const { asPath, isReady } = useRouter()

const child = Children.only(children)
const childClassName = child.props.className || ''
const [className, setClassName] = useState(childClassName)

useEffect(() => {
// Check if the router fields are updated client-side
if (isReady) {
// Dynamic route will be matched via props.as
// Static route will be matched via props.href
const linkPathname = new URL(
(props.as || props.href) as string,
location.href
).pathname

// Using URL().pathname to get rid of query and hash
const activePathname = new URL(asPath, location.href).pathname

const newClassName =
linkPathname === activePathname
? `${childClassName} ${activeClassName}`.trim()
: childClassName

if (newClassName !== className) {
setClassName(newClassName)
}
}
}, [
asPath,
isReady,
props.as,
props.href,
childClassName,
activeClassName,
setClassName,
className,
])

return (
<Link {...props}>
{React.cloneElement(child, {
className: className || null,
})}
</Link>
)
}

export default ActiveLink
children: ReactElement;
activeClassName: string;
};

const ActiveLink = ({ children, activeClassName, ...props }: ActiveLinkProps) => {
const { asPath, isReady } = useRouter();

const child = Children.only(children);
const childClassName = child.props.className || "";
const [className, setClassName] = useState(childClassName);

useEffect(() => {
// Check if the router fields are updated client-side
if (isReady) {
// Dynamic route will be matched via props.as
// Static route will be matched via props.href
const linkPathname = new URL((props.as || props.href) as string, location.href).pathname;

// Using URL().pathname to get rid of query and hash
const activePathname = new URL(asPath, location.href).pathname;

const newClassName =
linkPathname === activePathname ? `${childClassName} ${activeClassName}`.trim() : childClassName;

if (newClassName !== className) {
setClassName(newClassName);
}
}
}, [asPath, isReady, props.as, props.href, childClassName, activeClassName, setClassName, className]);

return (
<Link {...props}>
{React.cloneElement(child, {
className: className || null,
})}
</Link>
);
};

export default ActiveLink;
50 changes: 12 additions & 38 deletions components/Banner.tsx
Original file line number Diff line number Diff line change
@@ -1,62 +1,36 @@
import CtaButton from "./CtaButton";
import LandingValueProposition from "./LandingValueProposition";

type PropsWithClassName<T = {}> = { className?: string } & T;
type PropsWithClassName<T = Record<string, unknown>> = { className?: string } & T;

function BannerImage({
className,
...props
}: PropsWithClassName<{ src: string; alt: string }>) {
return (
<img
className={`rounded-[50px] border-[10px] border-zinc-50 ${className}`}
{...props}
/>
);
function BannerImage({ className, ...props }: PropsWithClassName<{ src: string; alt: string }>) {
return <img className={`rounded-[50px] border-[10px] border-zinc-50 ${className}`} {...props} />;
}

function Banner({ className }: PropsWithClassName) {
return (
<div className={`flex py-10 ${className}`}>
<div className="basis-0 grow">
<div className="grow basis-0">
<div className="mb-2.5 md:-mr-48">
{/* <span className="font-header text-primary text-3xl md:text-6xl md:leading-[5rem] lg:text-7xl lg:leading-[6rem] xl:text-8xl xl:leading-[8rem]">
Learn. Grow. Connect
</span> */}
<LandingValueProposition
elems={["Learn ", "Grow ", "Connect "]}
typeSpeed={100}
backSpeed={100}
delay={10}
/>
<LandingValueProposition elems={["Learn ", "Grow ", "Connect "]} typeSpeed={100} backSpeed={100} delay={10} />
</div>
<div className="lg:text-2xl lg:leading-10 max-w-prose font-light md:w-11/12 mb-6 md:mb-8">
She Codes Africa Nairobi: A community that empowers and celebrates
women in tech across the Nairobi region
<div className="mb-6 max-w-prose font-light md:mb-8 md:w-11/12 lg:text-2xl lg:leading-10">
She Codes Africa Nairobi: A community that empowers and celebrates women in tech across the Nairobi region
</div>

<CtaButton>Be a Member</CtaButton>
</div>

<div className="hidden md:grid w-3/5 grid-cols-[repeat(15,1fr)] grid-rows-[repeat(5,60px)] lg:grid-rows-5">
<BannerImage
className="col-start-5 col-span-6 row-start-1 row-span-3 z-10"
src="/images/image1.png"
alt=""
/>
<BannerImage
className="col-start-1 col-span-6 row-start-3 row-span-3"
src="/images/image2.png"
alt=""
/>
<BannerImage
className="col-start-10 col-span-6 row-start-3 row-span-3 z-20"
src="/images/image3.png"
alt=""
/>
<div className="hidden w-3/5 grid-cols-[repeat(15,1fr)] grid-rows-[repeat(5,60px)] md:grid lg:grid-rows-5">
<BannerImage className="z-10 col-span-6 col-start-5 row-span-3 row-start-1" src="/images/image1.png" alt="" />
<BannerImage className="col-span-6 col-start-1 row-span-3 row-start-3" src="/images/image2.png" alt="" />
<BannerImage className="z-20 col-span-6 col-start-10 row-span-3 row-start-3" src="/images/image3.png" alt="" />
</div>
</div>
);
}

export { Banner as default }
export { Banner as default };
50 changes: 28 additions & 22 deletions components/Blog.tsx
Original file line number Diff line number Diff line change
@@ -1,49 +1,55 @@
import Link from "next/link";
import React from "react";
import { BsArrowUpRightSquareFill } from "react-icons/bs";
const Blog = ({ posts }: any) => {
import { Post } from "../typings";

type BlogProps = {
posts: Post[]
};

const Blog = ({ posts }: BlogProps) => {
return (
<div className="space-y-5 md:p-10 md:flex items-center justify-center">
<div className="items-center justify-center space-y-5 md:flex md:p-10">
<div className="space-y-5">
<h1 className="text-primary text-2xl text-center md:text-4xl leading-relaxed">
Recent Blog Posts
</h1>
<div className="md:grid grid-cols-[1fr_2fr] gap-x-20 md:pt-20">
<h1 className="text-center text-2xl leading-relaxed text-primary md:text-4xl">Recent Blog Posts</h1>
<div className="grid-cols-[1fr_2fr] gap-x-20 md:grid md:pt-20">
<div className="space-y-5">
<div className="">
<div className="hidden relative z-0 h-[354px] bg-primary w-[584px]"></div>
<div className="bg-[#FFF7FC] bg-opacity-[98%] p-5 rounded-lg space-y-3 md:w-96">
<button className=" bg-primary text-sm font-light rounded-full text-white px-3 py-2 text-center">
<div className="relative z-0 hidden h-[354px] w-[584px] bg-primary"></div>
<div className="space-y-3 rounded-lg bg-[#FFF7FC] bg-opacity-[98%] p-5 md:w-96">
<button className=" rounded-full bg-primary px-3 py-2 text-center text-sm font-light text-white">
#Read
</button>
<h1 className="font-semibold text-lg">{posts[0].title}</h1>
<p className="leading-relaxed font-light text-base">

</p>
<h1 className="text-lg font-semibold">{posts[0].title}</h1>
<p className="text-base font-light leading-relaxed"></p>
<div className="flex items-center justify-between">
<h2 className="italic">By Essy</h2>
<a href={posts[0].url} target="_blank"> <BsArrowUpRightSquareFill className=" text-primary h-8 w-8 rounded-full" /></a>
<a href={posts[0].url} target="_blank" rel="noreferrer">
{" "}
<BsArrowUpRightSquareFill className=" h-8 w-8 rounded-full text-primary" />
</a>
</div>
</div>
</div>

<h1 className="text-lg text-primary font-normal md:hidden">
<h1 className="text-lg font-normal text-primary md:hidden">
<Link href="/">See more articles...</Link>
</h1>
</div>
<div className="hidden md:block">
<ul className="space-y-6">
{posts.map((post: any) => (
{posts.map((post: Post) => (
<li
key={post.id}
className="text-2xl duration-300 ease-out cursor-pointer border-b-2 border-opacity-[98%] border-[#FFF7fc] p-3 flex
hover:scale-105 justify-between leading-relaxed items-center tracking-wide"
>
className="flex cursor-pointer items-center justify-between border-b-2 border-[#FFF7fc] border-opacity-[98%] p-3 text-2xl
leading-relaxed tracking-wide duration-300 ease-out hover:scale-105">
<div>
<a href={post.url} target="_blank"> {post.title}</a>
<a href={post.url} target="_blank" rel="noreferrer">
{" "}
{post.title}
</a>
</div>{" "}
<div>
<BsArrowUpRightSquareFill className="rounded-full h-8 w-8 text-[#FFF7FC] " />{" "}
<BsArrowUpRightSquareFill className="h-8 w-8 rounded-full text-[#FFF7FC] " />{" "}
</div>
</li>
))}
Expand Down