feat: add 'all makers' tab, add email contact to ConnectToMakerModal, make tabs buttons a carousel in makers page

This commit is contained in:
MTG2000
2022-09-06 13:59:56 +03:00
parent 53b6088397
commit fbb8d1cf6d
8 changed files with 49 additions and 29 deletions

View File

@@ -6,7 +6,7 @@ import { Controller, SubmitHandler, useForm } from 'react-hook-form';
import SaveChangesCard from '../SaveChangesCard/SaveChangesCard';
import { toast } from 'react-toastify';
import { NotificationsService } from 'src/services';
import { gql, NetworkStatus, useApolloClient } from '@apollo/client';
import { NetworkStatus, useApolloClient } from '@apollo/client';
import { usePrompt } from 'src/utils/hooks';
import { UpdateUserRolesSkillsMutationVariables, useMyProfileRolesSkillsQuery, useUpdateUserRolesSkillsMutation, UserRolesSkillsFragmentDoc } from 'src/graphql'
import UpdateRolesCard from "./UpdateRolesCard/UpdateRolesCard";

View File

@@ -1,8 +1,6 @@
import React from 'react'
import { Control, useFieldArray } from 'react-hook-form'
import Card from 'src/Components/Card/Card'
import { GenericMakerRole, MakerRole, RoleLevelEnum } from 'src/graphql'
import { IRolesSkillsForm } from '../RolesSkillsTab'
type Value = Pick<MakerRole, 'id' | 'level'>

View File

@@ -1,6 +1,5 @@
import Card from 'src/Components/Card/Card'
import Button from 'src/Components/Button/Button'
import { RoleLevelEnum, User } from 'src/graphql';
import { User } from 'src/graphql';

View File

@@ -1,6 +1,6 @@
import { motion } from 'framer-motion'
import { ModalCard, modalCardVariants } from 'src/Components/Modals/ModalsContainer/ModalsContainer'
import { FiGithub, FiLinkedin, FiTwitter } from "react-icons/fi";
import { FiGithub, FiLinkedin, FiMail, FiTwitter } from "react-icons/fi";
import { IoClose } from 'react-icons/io5';
import { GetMakersInTournamentQuery } from 'src/graphql';
import Avatar from 'src/features/Profiles/Components/Avatar/Avatar';
@@ -15,25 +15,28 @@ export default function LinkingAccountModal({ onClose, direction, maker, ...prop
const links = [
{
hasValue: maker.email,
text: maker.email,
icon: FiMail,
url: maker.email && `mailto:${maker.email}`
},
{
hasValue: maker.twitter,
text: maker.twitter,
icon: FiTwitter,
colors: "bg-blue-100 text-blue-500",
url: `https://twitter.com/@${maker.twitter}`
},
{
hasValue: maker.github,
text: maker.github,
icon: FiGithub,
colors: "bg-pink-100 text-pink-600",
url: `https://github.com/${maker.github}`
},
{
hasValue: maker.linkedin,
text: "LinkedIn",
icon: FiLinkedin,
colors: "bg-sky-100 text-cyan-600",
url: maker.linkedin && withHttp(maker.linkedin),
}
];
@@ -66,7 +69,7 @@ export default function LinkingAccountModal({ onClose, direction, maker, ...prop
<a
key={idx}
href={link.url!}
className={`w-40 aspect-square rounded-full flex justify-center items-center ${link.colors}`}
className={`w-40 aspect-square rounded-full flex justify-center items-center bg-primary-100 text-primary-900`}
target='_blank'
rel="noreferrer">
<link.icon className="scale-125" />

View File

@@ -18,10 +18,12 @@ export default function MakerCard({ maker, isMe }: Props) {
const dispatch = useAppDispatch();
const contactLinksAvailable = maker.github || maker.email || maker.linkedin || maker.twitter;
let actionBtn = <Button fullWidth color='white' disabled size='sm' className='ml-auto'>Hacking solo</Button>
if (isMe) actionBtn = <Button fullWidth color='white' href={createRoute({ type: 'edit-profile' })} size='sm' className='ml-auto'>Edit Profile</Button>;
else actionBtn = <Button fullWidth color='white' size='sm' className='ml-auto' onClick={() => dispatch(openModal({ Modal: "ConnectToMakerModal", props: { maker } }))}>🤝 Team Up</Button>
else if (contactLinksAvailable) actionBtn = <Button fullWidth color='white' size='sm' className='ml-auto' onClick={() => dispatch(openModal({ Modal: "ConnectToMakerModal", props: { maker } }))}>🤝 Team Up</Button>
return (

View File

@@ -9,9 +9,10 @@ interface Props {
tournamentId: number
searchFilter: string,
roleFilter: number | null
onlyLookingToTeam?: boolean
}
const ITEMS_PER_PAGE = 3;
const ITEMS_PER_PAGE = 15;
export default function MakersList(props: Props) {

View File

@@ -1,6 +1,7 @@
import { useDebouncedState } from '@react-hookz/web';
import { useState } from 'react'
import { GenericMakerRole } from 'src/graphql'
import { useCarousel } from 'src/utils/hooks';
import MakersFilters from '../MakersFilters/MakersFilters';
import MakersList from './MakersList';
import ProjectsList from './ProjectsList';
@@ -13,9 +14,13 @@ export default function ParticipantsSection({ tournamentId }: Props) {
const [searchFilter, setSearchFilter] = useState("");
const [debouncedsearchFilter, setDebouncedSearchFilter] = useDebouncedState("", 500);
const [roleFilter, setRoleFilter] = useState<GenericMakerRole | null>(null);
const [curTab, setCurTab] = useState<'makers' | 'projects'>('makers')
const [curTab, setCurTab] = useState<'all-makers' | 'makers-to-team' | 'projects'>('all-makers')
const { viewportRef, } = useCarousel({
align: 'start', slidesToScroll: 1,
containScroll: "trimSnaps",
})
const changeSearchFilter = (new_value: string) => {
setSearchFilter(new_value);
@@ -37,30 +42,42 @@ export default function ParticipantsSection({ tournamentId }: Props) {
/>
</div>
</div>
<div className="flex gap-8">
<button
className={`
<div className="overflow-hidden" ref={viewportRef}>
<div className="select-none w-full flex gap-8">
<button
className={`
min-w-max rounded-48 px-16 py-8 cursor-pointer font-medium text-body5
active:scale-95 transition-transform
${curTab === 'makers' ? 'bg-primary-100 text-primary-600' : 'bg-gray-100 hover:bg-gray-200 text-gray-600'}
${curTab === 'all-makers' ? 'bg-primary-100 text-primary-600' : 'bg-gray-100 hover:bg-gray-200 text-gray-600'}
`}
onClick={() => setCurTab('makers')}
>
Makers looking for projects
</button>
<button
className={`
onClick={() => setCurTab('all-makers')}
>
All makers
</button>
<button
className={`
min-w-max rounded-48 px-16 py-8 cursor-pointer font-medium text-body5
active:scale-95 transition-transform
${curTab === 'makers-to-team' ? 'bg-primary-100 text-primary-600' : 'bg-gray-100 hover:bg-gray-200 text-gray-600'}
`}
onClick={() => setCurTab('makers-to-team')}
>
Makers looking for a team
</button>
<button
className={`
min-w-max rounded-48 px-16 py-8 cursor-pointer font-medium text-body5
active:scale-95 transition-transform
${curTab === 'projects' ? 'bg-primary-100 text-primary-600' : 'bg-gray-100 hover:bg-gray-200 text-gray-600'}
`}
onClick={() => setCurTab('projects')}
>
Projects looking for makers
</button>
onClick={() => setCurTab('projects')}
>
Projects looking for makers
</button>
</div>
</div>
{curTab === 'projects' && <ProjectsList searchFilter={debouncedsearchFilter} roleFilter={roleFilter?.id ?? null} tournamentId={tournamentId} />}
{curTab === 'makers' && <MakersList searchFilter={debouncedsearchFilter} roleFilter={roleFilter?.id ?? null} tournamentId={tournamentId} />}
{curTab !== 'projects' && <MakersList onlyLookingToTeam={curTab === 'makers-to-team'} searchFilter={debouncedsearchFilter} roleFilter={roleFilter?.id ?? null} tournamentId={tournamentId} />}
</>
)
}

View File

@@ -11,7 +11,7 @@ interface Props {
roleFilter: number | null
}
const ITEMS_PER_PAGE = 3;
const ITEMS_PER_PAGE = 15;
export default function ProjectsList(props: Props) {