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

feat: skill refactor #152

Open
wants to merge 3 commits into
base: test
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 10 additions & 21 deletions src/app/bounties/Filter.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,32 +20,32 @@ import clsx from 'clsx';
import { motion } from 'framer-motion';
import Image from 'next/image';
import { useRouter, useSearchParams, usePathname } from 'next/navigation';
import { useMemo, useState } from 'react';
import { useState } from 'react';

import { ChevronUpIcon } from '@/components/icon/solid';
import { ReactSelect } from '@/components/Select/ReactSelect';
import { createQueryString } from '@/utils';

import { bountyFilterList } from '#/lib/bountyFilterList';
import { useAllSkills } from '#/state/application/hooks';
import SelectSkills from '#/shared/components/SelectSkills';


export function SkillsFilter() {
const searchParams = useSearchParams();
const { replace } = useRouter();
const pathname = usePathname();

const skillOpts = useAllSkills();
const [open, setOpen] = useState(true);

const defaultValue = useMemo(() => {
const current = searchParams.get('skills')?.split(',');
return current?.length > 0 ? current.map(ci => skillOpts?.filter(f => f.value === Number(ci))).flat(1) : null;
}, [skillOpts, searchParams]);
const selectedSkills =
searchParams
.get('skills')
?.split(',')
.map(id => Number(id)) || [];

const handleSearch = term => {
const params = new URLSearchParams(searchParams);
params.set('page', '1');
if (term) {
if (term && term.length > 0) {
params.set('skills', term);
} else {
params.delete('skills');
Expand Down Expand Up @@ -82,18 +82,7 @@ export function SkillsFilter() {
closed: { opacity: 0, height: '0' },
}}
>
<ReactSelect
isMulti
name="skills"
value={defaultValue}
options={skillOpts}
onChange={e => {
const _skills = e.map(i => i.value);
handleSearch(_skills);
}}
placeholder={'Select skills'}
className="no-bg hauto"
/>
<SelectSkills selectedSkills={selectedSkills} onChange={handleSearch}/>
<div className="h-8" />
</motion.div>
</>
Expand Down
19 changes: 4 additions & 15 deletions src/app/creator/build/[type]/[id]/page.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,9 @@ import { BASE_INPUT_STYLE } from '@/constants/config';
import { get } from '@/utils/request';

import { publishBounty, editBounty } from '#/services/creator';
import { useAllSkills, useConfig, useMediaUrl } from '#/state/application/hooks';
import SelectSkills from '#/shared/components/SelectSkills';
import { useConfig, useMediaUrl } from '#/state/application/hooks';


const options = [
{
Expand Down Expand Up @@ -61,7 +63,6 @@ export default function Page({params: { id }}) {
const router = useRouter();
const config = useConfig();
const mediaUrl = useMediaUrl();
const allSkills = useAllSkills();

const [ecosystem, setEcosystem] = useState('');
const [skills, setSkills] = useState([]);
Expand Down Expand Up @@ -228,19 +229,7 @@ export default function Page({params: { id }}) {
</div>
<div className="col-span-2">
<h5>Required Skills <span className={clsx('text-xs font-normal', {' opacity-60': !skillsErr, 'text-red': skillsErr}) }>Select up to 3 items </span></h5>
<ReactSelect
value={skills.map(i => allSkills?.find(f => f.value === i))}
isMulti
name="skills"
options={allSkills}
className="no-bg"
onChange={e => {
const _skills = e.map(i => i.value);
setSkills(_skills);
}}
/>

{/* <SelectSkills skills={skills} setSkills={setSkills} /> */}
<SelectSkills selectedSkills={skills} onChange={setSkills} />
</div>
</div>
<div className="grid grid-cols-2 gap-4 mt-4">
Expand Down
48 changes: 4 additions & 44 deletions src/app/profile/MySkill.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ import { Button } from '@/components/Button';
import { UploadIcon } from '@/components/Icons';
import Loader from '@/components/Loader';
import { Select } from '@/components/Select';
import { ReactSelect } from '@/components/Select/ReactSelect';
// import { Transition } from '@/components/control';
// import { CheckIcon, XMarkIcon } from '@/components/icon/solid'
import { BASE_INPUT_STYLE } from '@/constants/config';
Expand All @@ -31,20 +30,11 @@ import { classNames } from '@/utils';
import { ProfileTitle, ProfileLabel } from '#/domain/profile/widgets/blocks';
import { EXPERIENCE_OPTIONS } from '#/lib/user';
import { upload } from '#/services/common';
import { useAllSkills, useConfig } from '#/state/application/hooks';
import SelectSkills from '#/shared/components/SelectSkills';
import { useConfig } from '#/state/application/hooks';

export function MySkill({ forms, set, formsError }) {
const allSkills = useAllSkills();

// const [openSkills, setOpenSkills] = useState(false)
// const [skillsInputValue, setSkillsInputValue] = useState('')
// // const [delFlag, setDelFlag] = useState(0)
// const [searchSkillOpts, setSearchSkillOpts] = useState<
// {
// key: number
// name: string
// }[]
// >([])
export function MySkill({ forms, set, formsError }) {
const [uploading, setUploading] = useState(false);
const [uploadFileSizeError, setUploadFileSizeError] = useState(false);
const uploadRef = useRef(null);
Expand All @@ -59,20 +49,6 @@ export function MySkill({ forms, set, formsError }) {
}));
}, [allOpts]);

// const skillOpts = useMemo(() => {
// return allOpts?.skills?.map(i => ({
// key: i.id,
// name: i.name,
// }))
// }, [allOpts])

// useEffect(() => {
// if (skillOpts) {
// const _search = skillOpts.filter(f => f.name.toLocaleLowerCase().includes(skillsInputValue.toLocaleLowerCase()))
// setSearchSkillOpts(_search)
// }
// }, [skillsInputValue, skillOpts])

const handleFileChange = event => {
const files = event.target.files;
if (files && files[0]) {
Expand Down Expand Up @@ -121,23 +97,7 @@ export function MySkill({ forms, set, formsError }) {
<ProfileLabel className="mt-9 text-gray-50">
Skills <span className="text-red">*</span>
</ProfileLabel>
<ReactSelect
value={forms.skills.map(i => allSkills?.find(f => f.value === i))}
isMulti
name="skills"
options={allSkills}
className="no-bg"
styles={{
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个 styles 应当传进新组件

control: () => ({
height: 'auto !important',
minHeight: '40px',
}),
}}
onChange={e => {
const _skills = e.map(i => i.value);
set('skills', _skills);
}}
/>
<SelectSkills selectedSkills={forms.skills} onChange={_skills => set('skills',_skills)} />
{/* <div className="relative">
<div
className={classNames(
Expand Down
18 changes: 4 additions & 14 deletions src/app/shilling/Filters.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@
*/

'use client';
import { useSelector } from 'react-redux';

import { ReactSelect } from '@/components/Select/ReactSelect';

import { useAllSkills } from '#/state/application/hooks';
// import { useRouter, useSearchParams } from 'next/navigation'
import SelectSkills from '#/shared/components/SelectSkills';
import { useAppDispatch } from '#/state/hooks';
import { setRequiredSkills, setExperience, setSortBy } from '#/state/shilling/reducer';

Expand Down Expand Up @@ -70,24 +71,13 @@ const SORT_BYS = [

export function ShillingFilters() {
const dispatch = useAppDispatch();

const skillOpts = useAllSkills();
const selectedSkills = useSelector(state => state.shilling.requiredSkills);

return (
<div className="flex">
<div className="mr-6 w-[568px]">
<h5 className="mb-2 text-sm">Required Skills:</h5>
<ReactSelect
isMulti
name="skills"
options={skillOpts}
onChange={e => {
const _skills = e.map(i => i.value);
dispatch(setRequiredSkills(_skills));
}}
className="react-select-noborder !h-12 border-0 "
limit={3}
/>
<SelectSkills selectedSkills={selectedSkills} limit={3} onChange={_skills => dispatch(setRequiredSkills(_skills))} className="react-select-noborder !h-12 border-0 "/>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不需要传 selectedSkills

</div>
<div className="mr-6 w-[240px]">
<h5 className="mb-2 text-sm">Experience:</h5>
Expand Down
15 changes: 3 additions & 12 deletions src/app/shilling/[id]/Author.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,18 @@ import Avatar from '@/components/Avatar';
import { Button } from '@/components/Button';
import { RepositioningIcon, TriangleIcon, InformationIcon } from '@/components/Icons';
import { Modal } from '@/components/Modal';
import { ReactSelect } from '@/components/Select/ReactSelect';

import { baseInputStyles } from '#/domain/profile/widgets/blocks';
import { countries } from '#/lib/countries';
import { applyGetContact } from '#/services/shilling';
import { useDetailsPermission } from '#/services/shilling/hooks';
import { useAllSkills } from '#/state/application/hooks';
import SelectSkills from '#/shared/components/SelectSkills';

import { ContactModal } from '../ContactModal';
import { HireConfirmModal } from '../HireConfirmModal';
import { HireOnChainModal } from '../HireOnChainModal';


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这行多余

export function Author({ data }) {
const { status } = useSession();
const router = useRouter();
Expand All @@ -52,7 +52,6 @@ export function Author({ data }) {
const [applyLoading, setApplyLoading] = useState(false);
const [openToken, setOpenToken] = useState(false);
const [token, setToken] = useState('');
const skills = useAllSkills();
const [selectSkills, setSelectSkills] = useState();
const getContact = token => {
setOpenToken(false);
Expand Down Expand Up @@ -139,15 +138,7 @@ export function Author({ data }) {
<div>
<div>
<p className="mb-1 text-sm opacity-60">Choose the Skill you interested</p>
<ReactSelect
isMulti
options={skills}
onChange={e => {
const _skills = e.map(i => i.value);
setSelectSkills(_skills);
}}
className="react-select-container !min-h-12 border-0"
/>
<SelectSkills selectedSkills={selectSkills} onChange={setSelectSkills} className="react-select-container !min-h-12 border-0"/>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

逻辑保持原样,不需要传 selectedSkills

</div>
<div className="mt-4">
<p className="mb-1 text-sm opacity-60">The developer need you provide your introduction & demand</p>
Expand Down
91 changes: 4 additions & 87 deletions src/app/shilling/[id]/page.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,23 +15,21 @@
*/

'use client';
import clsx from 'clsx';
import { useEffect, useState } from 'react';

import { OViewer } from '@/components/MarkDown';
import { Skeleton } from '@/components/Skeleton/details';
import { fromNow } from '@/utils/date';

import SkillInsight from '#/domain/skill/widgets/skill-insight';
import SkillOverviewView from '#/domain/skill/views/skill-overview';
import SkillLabel from '#/domain/skill/widgets/skill-label';
import { ownedNFTs } from '#/services/common';
import { useDetails } from '#/services/shilling/hooks';
import { useAllSkills } from '#/state/application/hooks';

import { Author } from './Author';
import { Header } from './Header';

export default function Page({ params }) {
const skills = useAllSkills();
const { data, loading } = useDetails(params.id);
const [nfts, setNfts] = useState([]);

Expand All @@ -45,8 +43,6 @@
}
}, [data]);

console.log(nfts);

return loading ? (
<Skeleton />
) : (
Expand Down Expand Up @@ -85,89 +81,10 @@
{data?.rec && <OViewer value={data?.rec} />}
</div>
{/* <BountiesDetail data={data?.detail} /> */}
<div className="mb-14">
{data?.skill_datas.map(i => (
<span
key={`skill-tag-${i.id}`}
className="mr-[6px] inline-block mb-2 h-7 rounded-md border border-gray-600 px-2 text-sm leading-7 text-gray-100"
>
{skills?.find(f => f.value === Number(i.skill))?.label}
</span>
))}
</div>
<SkillLabel userId={params.id}/>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

单独弄个这个没多大意义,还增加了请求数量,先恢复原样并删除新增的与 SkillLabel 相关的文件

<hr className="my-14 border-gray-400" />
<div>
<h6 className="mb-6 text-lg">Skills</h6>
<div className="grid grid-cols-3 gap-4">
{data?.skill_datas.map(i => (
<div key={`skill-${i.id}`} className="rounded-lg border border-gray-400 p-4">
<div className="flex items-start justify-between">
<div>
<h6 className="mb-2 text-base">{skills?.find(f => f.value === i.skill)?.label}</h6>
<div className="text-xs">
{i.level && (
<span
className={clsx('mr-2 rounded-sm px-1 py-[2px] capitalize', {
'bg-[rgba(58,171,118,0.1)] text-[#3AAB76]': i.level === 'generally',
'bg-[rgba(24,160,251,0.1)] text-[#18A0FB]': i.level === 'well',
'bg-[rgba(216,97,65,0.1)] text-[#D86141]': i.level === 'proficient',
'bg-[rgba(118,82,237,0.1)] text-[#7652ED]': i.level === 'skilled',
})}
>
{i.level}
</span>
)}

<span className="opacity-80">Usage time {i.time}Y</span>
</div>
</div>
<svg width="20" height="20" viewBox="0 0 440 440">
<circle
cx="220"
cy="220"
r="170"
strokeWidth="40"
stroke="rgba(16,16,16,0.1)"
fill="none"
/>
<circle
cx="220"
cy="220"
r="170"
strokeWidth="40"
stroke="rgba(16,16,16,0.4)"
fill="none"
transform="matrix(0,-1,1,0,0,440)"
style={{
strokeDasharray:
i.level === 'generally'
? '267 1069'
: i.level === 'well'
? '534 1069'
: i.level === 'proficient'
? '801 1069'
: '1069 1069',
}}
/>
</svg>
</div>
<div className="mt-3 flex items-center justify-between border-t border-gray-400 pt-3 text-xs">
<p className="opacity-80">Estimated cost</p>
<p>
<strong>
${Number(i.cost_min).toFixed(2)}-${Number(i.cost_max).toFixed(2)}
</strong>{' '}
/ Hourly
</p>
</div>
</div>
))}
</div>
</div>
<SkillOverviewView userId={params.id} />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不能直接用 SkillOverviewView,把它里面的下图部分代码拆成单独的 widget:

image

然后在 SkillOverviewView 和这里复用那个新 widget。

<div className="h-6" />
{data?.aspecta_show && (
<SkillInsight data={data?.skill_user.user_extra_skills} />
)}
{data?.onchain_show && nfts.length > 0 && (
<div>
<div className="mb-4 mt-14 flex items-center justify-between">
Expand All @@ -175,7 +92,7 @@
</div>
<div className="flex flex-wrap">
{nfts.map((i, k) => (
<img

Check warning on line 95 in src/app/shilling/[id]/page.js

View workflow job for this annotation

GitHub Actions / lint

Using `<img>` could result in slower LCP and higher bandwidth. Consider using `<Image />` from `next/image` to automatically optimize images. This may incur additional usage or cost from your provider. See: https://nextjs.org/docs/messages/no-img-element
width={64}
height={64}
className="mr-4 mb-4 rounded-full"
Expand Down
Loading
Loading