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

chore: updated profile page layout #1913

Merged
merged 3 commits into from
Aug 11, 2023
Merged
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import colors from '../../constants/colors';
import styled from 'styled-components';

export const DropdownContainer = styled.div`
display: flex;
position: relative;
gap: 8px;
height: 35px;
flex-grow: 1;
margin-right: 8px;
`;

export const DropdownOptionsHeading = styled.div`
display: flex;
padding: 8px;
flex-direction: row;
justify-content: space-between;
`;

export const DropdownOptionsHeadingText = styled.span`
font-size: 12px;
font-weight: 700;
`;

export const DropdownBtn = styled.button`
display: flex;
flex-grow: 1;
border-radius: 8px;
align-items: center;
padding: 8px;
justify-content: space-between;
border: 1px solid ${colors.gray300};
background-color: ${colors.gray100};
gap: 4px;
min-width: 70px;
outline: none;
@media (min-width: 768px) {
gap: 8px;
min-width: 80px;
}
`;

export const DropdownOption = styled.li`
display: flex;
gap: 4px;
padding: 8px;
flex-direction: row;
border-top-width: 1px;
background-color: #fff;
border-top-style: solid;
border-top-color: ${colors.gray300};
`;

export const DropdownBtnText = styled.span`
font-size: 14px;
font-weight: 500;
`;

export const DropDownMenu = styled.div`
position: absolute;
right: 0px;
z-index: 10;
margin-top: 0.5rem;
width: 14rem;
transform-origin: top right;
border-radius: 0.375rem;
background-color: #fff;
box-shadow: 0px 0px 10px 1px #ccc;
top: 2rem;
`;

export const MenuItemContainer = styled.div`
padding: 0.25rem 0;
transition-property: all;
transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
transition-duration: 150ms;
transition-delay: 50ms;
cursor: pointer;
border-top: 1px solid ${colors.gray200};
`;

export const MenuItem = styled.span`
color: ${colors.gray700};
padding: 0.5rem 1rem;
font-size: 0.875rem;
line-height: 1.25rem;
display: flex;
align-items: center;
gap: 0.75rem;
`;

export const NotSelected = styled.span`
margin-right: 1rem;
`;

export const MenuItemContent = styled.span`
display: flex;
align-items: center;
gap: 0.5rem;
`;

export const MenuItemContentColor = styled.span`
width: 1rem;
height: 1rem;
border-radius: 0.5rem;
flex-shrink: 0;
border: 1px solid ${colors.gray300};
`;

export const CloseWrapper = styled.div`
display: flex;
justify-content: space-between;
align-items: center;
font-size: 0.875rem;
line-height: 1.25rem;
padding: 0.25rem 0.75rem;
`;

export const CloseBtn = styled.button`
outline: none;
border: none;
background-color: transparent;
height: 1rem;
font-size: 1rem;
cursor: pointer;
`;

export const CloseText = styled.strong`
text-transform: capitalize;
font-size: 0.75rem;
line-height: 1rem;
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import { useLayoutEffect, useMemo, useRef, useState } from 'react';
import { CaretIcon } from '../details-dropdown/DetailsDropdown.style';
import {
CloseBtn,
CloseText,
CloseWrapper,
DropDownMenu,
DropdownBtn,
DropdownBtnText,
DropdownContainer,
MenuItem,
MenuItemContainer,
MenuItemContent,
MenuItemContentColor,
NotSelected,
} from './FilterDropdown.styles';
import { CloseIcon, CorrectIcon } from '../icons';
interface FilterDropdownProps {
name: string;
items?: string[];
selected?: string;
itemsColors?: string[];
selectOption?: (value: string) => void;
}
export default function FilterDropdown({
name,
items,
selected,
itemsColors,
selectOption,
}: FilterDropdownProps) {
const [showOptions, setShowOptions] = useState(false);
let ref = useRef<HTMLDivElement>(null);

const toggleOption = () => setShowOptions((prev) => !prev);

const allItems = useMemo(() => {
if (itemsColors && itemsColors.length === (items || []).length) {
return (items || []).map((item, index) => ({
name: item,
color: itemsColors && (itemsColors[index] || 'ccc'),
}));
} else {
return (items || []).map((item) => ({
name: item,
color: null,
}));
}
}, [items, itemsColors]);

const handleClickOutside = (event: any) => {
if (ref.current && !ref.current.contains(event.target)) {
setShowOptions(false);
}
};

useLayoutEffect(() => {
document.addEventListener('click', handleClickOutside, true);
return () => {
document.removeEventListener('clic', handleClickOutside, true);
};
});
return (
<DropdownContainer ref={ref}>
<DropdownBtn onClick={toggleOption}>
<DropdownBtnText>{name}</DropdownBtnText>
<CaretIcon active={false} />
</DropdownBtn>
{showOptions && (
<DropDownMenu
role="menu"
aria-orientation="vertical"
aria-labelledby="menu-button"
>
<CloseWrapper>
<CloseText>Select {name}</CloseText>
<CloseBtn onClick={() => setShowOptions(false)}>
<CloseIcon />
</CloseBtn>
</CloseWrapper>
{allItems.map(({ name, color }, index) => (
<MenuItemContainer role="none" onClick={() => selectOption?.(name)}>
<MenuItem role="menuitem" tabIndex={-1}>
{name === selected ? <CorrectIcon /> : <NotSelected />}
<MenuItemContent>
{color && (
<MenuItemContentColor style={{ backgroundColor: `#${color}` }} />
)}
{name}
</MenuItemContent>
</MenuItem>
</MenuItemContainer>
))}
</DropDownMenu>
)}
</DropdownContainer>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export const RepoBookIcon = (props: any) => (
<svg height="16" viewBox="0 0 16 16" width="16" fill="none" {...props}>
<path
fill="currentColor"
fillRule="evenodd"
d="M2 2.5A2.5 2.5 0 014.5 0h8.75a.75.75 0 01.75.75v12.5a.75.75 0 01-.75.75h-2.5a.75.75 0 110-1.5h1.75v-2h-8a1 1 0 00-.714 1.7.75.75 0 01-1.072 1.05A2.495 2.495 0 012 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 011-1h8zM5 12.25v3.25a.25.25 0 00.4.2l1.45-1.087a.25.25 0 01.3 0L8.6 15.7a.25.25 0 00.4-.2v-3.25a.25.25 0 00-.25-.25h-3.5a.25.25 0 00-.25.25z"
/>
</svg>
);
16 changes: 16 additions & 0 deletions cra-rxjs-styled-components/src/components/icons/RepoIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export const RepoIcon = (props: any) => {
return (
<svg
height="16"
width="16"
viewBox="0 0 16 16"
stroke="currentColor"
{...props}
>
<path
fillRule="evenodd"
d="M2 2.5A2.5 2.5 0 014.5 0h8.75a.75.75 0 01.75.75v12.5a.75.75 0 01-.75.75h-2.5a.75.75 0 110-1.5h1.75v-2h-8a1 1 0 00-.714 1.7.75.75 0 01-1.072 1.05A2.495 2.495 0 012 11.5v-9zm10.5-1V9h-8c-.356 0-.694.074-1 .208V2.5a1 1 0 011-1h8zM5 12.25v3.25a.25.25 0 00.4.2l1.45-1.087a.25.25 0 01.3 0L8.6 15.7a.25.25 0 00.4-.2v-3.25a.25.25 0 00-.25-.25h-3.5a.25.25 0 00-.25.25z"
></path>
</svg>
);
};
2 changes: 2 additions & 0 deletions cra-rxjs-styled-components/src/components/icons/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,5 @@ export { ReadmeListIcon } from './ReadmeListIcon';
export { DirectoryIcon } from './DirectoryIcon';
export { FileIcon } from './FileIcon';
export { TwitterIcon } from './TwitterIcon';
export { RepoIcon } from './RepoIcon';
export { RepoBookIcon } from './RepoBookIcon';
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,8 @@ export const NetlifyBadgeContainer = styled.div`
text-align: center;
background-color: white;
`;

export const ProfileNav = styled.div`
background-color: #fff;
padding-top: 40px;
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import colors from '../../constants/colors';
import styled from 'styled-components';

export const Container = styled.div`
background-color: white;
`;

export const RepoFilterWrapper = styled.div`
display: flex;
gap: 10px;
width: 100%;
border-bottom-width: 1px;
border-bottom-style: solid;
border-bottom-color: ${colors.gray300};
flex-direction: column;
padding: 16px 0px;
@media (min-width: 1024px) {
flex-direction: row;
padding: 10px 0px;
}
`;

export const FiltersWrapper = styled.div`
display: flex;
width: 100%;
flex: 0.45;
@media (min-width: 1024px) && (max-width: 1440px) {
flex: 0.6;
}
`;

export const SearchTextInput = styled.input`
font-size: 16px;
padding: 8px 12px;
border-radius: 8px;
background-color: #fff;
color: ${colors.gray500};
border: 1px solid ${colors.gray300};
flex: 1;
`;

export const RepoBtn = styled.button`
display: flex;
gap: 8px;
height: 35px;
padding: 6px 12px;
border-radius: 8px;
flex-direction: row;
align-items: center;
justify-content: center;
background-color: ${colors.primaryGreen};
outline: none;
border: none;
`;

export const RepoBtnText = styled.span`
color: #fff;
font-size: 14px;
font-weight: 700;
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import FilterDropdown from '../filter-dropdown/FilterDropdown';
import { RepoBookIcon } from '../icons';
import {
Container,
FiltersWrapper,
RepoBtn,
RepoBtnText,
RepoFilterWrapper,
} from './RepoFilter.styles';
import SearchInput from './SearchInput';
import { FILTER_TYPE_OPTIONS, SORT_OPTIONS } from './data';

interface RepoFilterProps {
languages?: string[];
filteredRepoCount?: number;
repoBtnText?: string;
}

export default function RepoFilter({
languages,
filteredRepoCount,
repoBtnText,
}: RepoFilterProps) {
const typeOptions = Object.values(FILTER_TYPE_OPTIONS);
const sortOptions = Object.values(SORT_OPTIONS);
const languageOptions = ['All', 'HTML', 'CSS', 'PHP'];

return (
<Container>
<RepoFilterWrapper>
<SearchInput />
<FiltersWrapper>
<FilterDropdown name="Type" items={typeOptions} />
<FilterDropdown name="Sort" items={sortOptions} />
<FilterDropdown
name="Language"
items={languages && languages.length > 0 ? languages : languageOptions}
/>
</FiltersWrapper>
<RepoBtn>
<RepoBookIcon color="#fff" />
<RepoBtnText>{repoBtnText || 'New'}</RepoBtnText>
</RepoBtn>
</RepoFilterWrapper>
</Container>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { SearchTextInput } from './RepoFilter.styles';

export default function SearchInput() {
return <SearchTextInput placeholder="Find a repository..." />;
}
Loading
Loading