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

65 feat contributors profile page #67

Merged
merged 22 commits into from
Mar 8, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
4f6219e
build: configured typescript config
sboy99 Feb 5, 2023
d8c7174
style: added component style
sboy99 Feb 5, 2023
e3c9227
feat: removed contents as will come from local filesystem
sboy99 Feb 6, 2023
c4adbe3
feat: added respective types declarations
sboy99 Feb 6, 2023
1bbfa82
feat: added custom rehype plugins
sboy99 Feb 6, 2023
233c24e
feat: mdx content generator now accepts rehype plugins as a parameter
sboy99 Feb 6, 2023
034300c
feat: created mdx content generator libraries
sboy99 Feb 6, 2023
0b616a2
perf: used clsx instead of manual conditions
sboy99 Feb 6, 2023
ac9bcf4
style: started designig contributor profile page
sboy99 Feb 6, 2023
9371033
feat: created contributor profile page layout
sboy99 Feb 6, 2023
0d56291
feat: added necessary components and removed unnecessary mdx components
sboy99 Feb 6, 2023
65a680b
contribution: added my profile
sboy99 Feb 6, 2023
b602e08
fix: resolved merge confict
sboy99 Feb 6, 2023
9f5e7f2
build: added new image resouce domain
sboy99 Feb 20, 2023
289cbef
chore: updated contributor profile page components
sboy99 Feb 20, 2023
24107f4
chore: updated mdx components
sboy99 Feb 20, 2023
8b429cb
chore: updated utility components
sboy99 Feb 20, 2023
caf3b76
refactor: updated contributors profile page
sboy99 Feb 20, 2023
41e0ad0
feat: added more rehype plugins
sboy99 Feb 20, 2023
365eedf
feat: added next image rehype plugin
sboy99 Feb 20, 2023
c21fb14
feat: added image styling plugin
sboy99 Feb 20, 2023
cee95f4
chore: updated dummy data
sboy99 Feb 20, 2023
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
Prev Previous commit
Next Next commit
chore: updated contributor profile page components
  • Loading branch information
sboy99 committed Feb 20, 2023
commit 289cbef3d81add6d506066cabb7c88d6d91240d0
2 changes: 1 addition & 1 deletion src/components/contributorProfilePage/Profile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export type ProfileProps = {

const Profile: FC<ProfileProps> = ({ meta, contributor }) => {
return (
<div className="relative z-0 min-h-[35vh]">
<div className="relative z-0 pb-12">
<div className="bg-squares -mt-4"></div>
{/* profile Image */}
<div className="absolute inset-x-0 -top-16 w-fit rounded-full border-2 border-accent bg-skin-base p-0.5 sm:-top-20">
Expand Down
35 changes: 35 additions & 0 deletions src/components/contributorProfilePage/Project.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { ChevronRightIcon, WindowIcon } from '@heroicons/react/20/solid';
import type { FC, ReactNode } from 'react';

type ProjectProps = {
icon?: string | ReactNode;
name: string;
livePreview?: string;
tldr?: string;
isActive: boolean;
forkLink?: string;
};

const Project: FC<ProjectProps> = ({ name, livePreview, tldr }) => {
return (
<div className="flex cursor-pointer items-center justify-between rounded-lg px-4 py-2 text-skin-muted hover:bg-skin-shine dark:hover:bg-skin-shine/60">
{/* icon section */}
<div className="flex items-center space-x-4">
<div className="rounded-full border border-accent/50 p-2">
<WindowIcon className="h-6 w-6" />
</div>
{/* name & tldr */}
<div className="">
<h3 className="text-lg font-semibold text-skin-base">{name}</h3>
<p className="text-xs">
{(livePreview && livePreview.replace('https://', '')) ?? tldr}
</p>
</div>
</div>
{/* chevron */}
<ChevronRightIcon className="h-5 w-5" />
</div>
);
};

export default Project;
48 changes: 48 additions & 0 deletions src/components/contributorProfilePage/ProjectDetails.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { ChevronRightIcon } from '@heroicons/react/20/solid';
import RepoIcon from '@icons/Repo';
import type { FC, ReactElement } from 'react';

type ProjectDetailsProps = {
className: string;
children: ReactElement;
};

const ProjectDetails: FC<ProjectDetailsProps> = ({ children }) => {
const content = children.props.children;
const { name, tldr, livePreview, repository } = children.props;
return (
<div className="text-skin-base">
<div className="space-y-4">
{tldr && <strong className="!text-accent">{tldr}</strong>}
<h1 className="mb-8 text-5xl font-extrabold tracking-tight sm:text-6xl">
{name}
</h1>
{content}
<div className="flex items-center gap-4 pt-4">
{repository && (
<a
href={repository}
target="_blank"
rel="norefferer noreferrer"
className="flex cursor-pointer items-center gap-x-1 rounded-md border-none bg-skin-inverted px-3 py-1 font-medium capitalize text-skin-inverted"
>
<RepoIcon className="h-5 w-5" /> Repository
</a>
)}
{livePreview && (
<a
href={livePreview}
target="_blank"
rel="norefferer noreferrer"
className="flex cursor-pointer items-center gap-x-1 rounded-md border border-skin-base bg-skin-base px-4 py-1 font-medium capitalize text-skin-base "
>
Live Preview <ChevronRightIcon className="-mr-2 h-5 w-5" />
</a>
)}
</div>
</div>
</div>
);
};

export default ProjectDetails;
34 changes: 34 additions & 0 deletions src/components/contributorProfilePage/ProjectList.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { CircleStackIcon } from '@heroicons/react/24/outline';
import type { Dispatch, FC, ReactElement, SetStateAction } from 'react';
import Project from './Project';

type ProjectListProps = {
children: ReactElement[];
inFocus: number;
onSelect: Dispatch<SetStateAction<number>>;
};

const ProjectList: FC<ProjectListProps> = ({ children, onSelect, inFocus }) => {
return (
<ul className="not-prose m-0 max-w-lg space-y-2 rounded-xl border border-skin-base/60 bg-skin-base p-4 text-skin-base">
<div className="flex flex-wrap gap-x-2 px-4 py-2 font-medium capitalize">
<CircleStackIcon className="h-6 w-6" />
Projects that beautifies my portfolio
</div>
<div className="max-h-44 overflow-auto">
{children.map((child: ReactElement, i: number) => (
<li key={i} onClick={() => onSelect(i)}>
<Project
name={child?.props?.name ?? 'Project'}
livePreview={child?.props?.livePreview}
tldr={child?.props?.tldr}
isActive={i === inFocus}
/>
</li>
))}
</div>
</ul>
);
};

export default ProjectList;
66 changes: 62 additions & 4 deletions src/components/contributorProfilePage/Projects.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,67 @@
import type { FC } from 'react';
import type { FC, ReactElement } from 'react';

type ProjectsProps = {};
import Image from 'next/image';
import { Children, useState } from 'react';
import ProjectDetails from './ProjectDetails';
import ProjectList from './ProjectList';

const Projects: FC<ProjectsProps> = () => {
return <div>Projects</div>;
type ProjectsProps = {
children?: ReactElement[];
};

const Projects: FC<ProjectsProps> = ({ children }) => {
const [activePtojectIndex, setActivePtojectIndex] = useState(0);
const arrayChildren = Children.toArray(children) as ReactElement[];
const activeChildren = arrayChildren[activePtojectIndex];
const activePtojectProps = arrayChildren[activePtojectIndex]?.props;

const hasImageProp: boolean = activePtojectProps && activePtojectProps?.image;

const isUseNextImage: boolean =
hasImageProp &&
activePtojectProps.image.startsWith(
'https://user-images.githubusercontent.com'
);

return (
<section className="relative my-12 mx-auto max-w-7xl">
<div className="mx-auto grid grid-cols-1 gap-y-8 xl:max-w-none ">
<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
{/* Project Details */}
<div className="row-start-2">
<ProjectDetails className="">{activeChildren}</ProjectDetails>
</div>
<div className="row-start-1 md:row-start-2 xl:mt-6">
<ProjectList
onSelect={setActivePtojectIndex}
inFocus={activePtojectIndex}
>
{arrayChildren}
</ProjectList>
</div>
{/* canvas */}
</div>
<div className="relative xl:col-span-2">
{hasImageProp ? (
isUseNextImage ? (
<Image
className="aspect-video flex-auto rounded-xl bg-white text-skin-base"
src={activePtojectProps?.image}
alt={activePtojectProps?.name}
/>
) : (
// eslint-disable-next-line @next/next/no-img-element
<img
className="aspect-video flex-auto rounded-xl bg-white text-skin-base"
src={activePtojectProps?.image}
alt={activePtojectProps?.name}
/>
)
) : null}
</div>
</div>
</section>
);
};

export default Projects;
69 changes: 40 additions & 29 deletions src/components/contributorProfilePage/Skill.tsx
Original file line number Diff line number Diff line change
@@ -1,43 +1,54 @@
import Dot from '@utilities/Dot';
import type { FC, ReactNode } from 'react';
import LinkComp from '@utilities/LinkComp';
import { FC, ReactNode } from 'react';

type SkillProps = {
children?: ReactNode;
name: string;
level?: string;
icon?: ReactNode;
logoRef?: string;
icon?: ReactNode | string;
href?: string;
};

const Skill: FC<SkillProps> = ({ children, name, level, icon, logoRef }) => {
const Skill: FC<SkillProps> = ({ children, name, level, icon, href }) => {
let isImageLink = false;

if (typeof icon === 'string') {
if (icon.startsWith('http:https://') || icon.startsWith('https://'))
isImageLink = true;
}

return (
<div className="relative h-fit w-full rounded-lg border border-skin-base p-4">
{children}
<div className="not-prose flex items-end gap-x-2 text-skin-base">
{icon ? (
<div className="h-7 w-7 fill-current text-accent">{icon}</div>
) : logoRef ? (
// eslint-disable-next-line @next/next/no-img-element
<img
src={logoRef}
alt={name}
className="h-7 w-7 rounded-full object-cover object-center"
/>
) : null}
<h3 className="mt-2 flex items-center gap-x-2 text-xl font-semibold">
{name}
{level && (
<>
<Dot />
<span className="text-xs font-medium text-skin-muted">
{level}
</span>
</>
)}
</h3>
<LinkComp isCardComp href={href ?? ``}>
<div className="relative h-fit w-full rounded-lg border border-skin-base p-4">
{children}
<div className="not-prose flex items-end gap-x-2 text-skin-base">
{icon ? (
isImageLink ? (
// eslint-disable-next-line @next/next/no-img-element
<img
src={icon as string}
alt={name}
className="h-7 w-7 rounded-full object-cover object-center"
/>
) : (
<div className="h-7 w-7 fill-current text-accent">{icon}</div>
)
) : null}
<h3 className="mt-2 flex items-center gap-x-2 text-xl font-semibold">
{name}
{level && (
<>
<Dot />
<span className="text-xs font-medium text-skin-muted">
{level}
</span>
</>
)}
</h3>
</div>
</div>
</div>
</LinkComp>
);
};

Expand Down
10 changes: 9 additions & 1 deletion src/components/contributorProfilePage/Skills.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,19 @@ import type { FC, ReactNode } from 'react';

type SkillsProps = {
children: ReactNode;
title?: string;
desc?: string;
};

const Skills: FC<SkillsProps> = ({ children }) => {
const Skills: FC<SkillsProps> = ({ children, title, desc }) => {
return (
<>
{title && (
<div className="prose mb-4 max-w-lg ">
<h3>{title}</h3>
{desc && <p>{desc}</p>}
</div>
)}
<div className="grid grid-cols-1 gap-4 md:grid-cols-2 lg:grid-cols-3">
{children}
</div>
Expand Down
1 change: 1 addition & 0 deletions src/components/contributorProfilePage/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export { default as Introduction } from './Introduction';
export { default as Profile } from './Profile';
export { default as Project } from './Project';
export { default as Projects } from './Projects';
export { default as Skill } from './Skill';
export { default as Skills } from './Skills';
Expand Down