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

Skillsを作成 #4

Merged
merged 11 commits into from
Jul 1, 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
17 changes: 17 additions & 0 deletions __tests__/components/Portfolio/SkillItem.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { render, waitFor } from '@testing-library/react'
import { expect } from '@jest/globals'
import { Mock } from 'ts-mockery'
import { SkillItemProps, SkillItem } from '@/components/Portfolio/SkillItem'
import { SkillType } from '@/resources/types'

describe('<SkillItem />', () => {
it('正常に描画される', async () => {
const props = Mock.from<SkillItemProps>({
skill: Mock.from<SkillType>({ name: 'Rails', percent: 90 }),
})
const component = render(<SkillItem {...props} />)
await waitFor(() => {
expect(component).toBeTruthy()
})
})
})
File renamed without changes.
26 changes: 26 additions & 0 deletions __tests__/containers/Skills.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Skills } from '@/containers/Skills'
import { expect } from '@jest/globals'
import { render, waitFor } from '@testing-library/react'

jest.mock('@/data/skills', () => ({
skillsData: [
{
name: 'Rails',
percent: 90,
},
{
name: 'React',
percent: 100,
},
],
}))

describe('<Skills />', () => {
it('Skillsが正常に描画される', async () => {
const component = render(<Skills />)

await waitFor(() => {
expect(component).toBeTruthy()
})
})
})
3 changes: 3 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ const customJestConfig = {
moduleDirectories: ['node_modules', '<rootDir>/'],
testEnvironment: 'jest-environment-jsdom',
testPathIgnorePatterns: ['./__tests__/testHelpers'],
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1', // 追加
},
}

// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
Expand Down
1 change: 1 addition & 0 deletions public/images/skills/django.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions public/images/skills/python.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions public/images/skills/rails.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions public/images/skills/react.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions public/images/skills/typescript.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions public/images/skills/vue.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
51 changes: 35 additions & 16 deletions src/components/Common/PieItem.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,7 @@
import { ReactNode } from 'react'
import styled from 'styled-components'

const PieDiv = styled.div`
width: 200px;
height: 200px;
border-radius: 50%;
background-image: conic-gradient(
rgb(0, 85, 255),
#00c3ff 60%,
rgb(79, 79, 79) 40% 100%
);
position: relative;
`
const CircleSpan = styled.span`
const CircleDiv = styled.div`
width: 160px;
height: 160px;
background-color: white;
Expand All @@ -20,20 +10,49 @@ const CircleSpan = styled.span`
top: 20px;
left: 20px;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
font-size: 30px;
`

const PieDiv = styled.div<{
start: number[]
end: number[]
percent: number
}>`
width: 200px;
height: 200px;
border-radius: 50%;
background-image: conic-gradient(
${(
props
) => `rgb(${props.start[0]}, ${props.start[1]}, ${props.start[2]}), rgb(${props.end[0]}, ${props.end[1]}, ${props.end[2]}) ${props.percent}%,
rgb(79, 79, 79) ${props.percent}% 100%`}
);
position: relative;
`

export type PieItemProps = {
percent: number
label: string
children: ReactNode
className?: string
innerClassName?: string
}

export const PieItem: React.FC<PieItemProps> = ({ percent, label }) => {
export const PieItem: React.FC<PieItemProps> = ({
percent,
children,
className,
innerClassName,
}) => {
const start = [0, 85, 255]
const end = [0, 255, 238]
const color = end.map((v, i) => start[i] + ((v - start[i]) * percent) / 100)

return (
<PieDiv className="">
<CircleSpan>{label}</CircleSpan>
<PieDiv start={start} end={color} percent={percent} className={className}>
<CircleDiv className={innerClassName}>{children}</CircleDiv>
</PieDiv>
)
}
34 changes: 34 additions & 0 deletions src/components/Portfolio/SkillItem.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { SkillType } from '@/resources/types'
import { PieItem } from '../Common/PieItem'
import Image from 'next/image'

export type SkillItemProps = {
skill: SkillType
className?: string
}

export const SkillItem: React.FC<SkillItemProps> = ({ skill, className }) => {
return (
<div className={className}>
<PieItem
innerClassName="bg-body"
className="mx-auto"
percent={skill.percent}
>
<div className="d-flex flex-column mb-2">
{skill.logoSrc && (
<div className="icon text-center">
<Image
alt={`${skill.name}-logo`}
src={skill.logoSrc}
width={50}
height={50}
/>
</div>
)}
<span className="text-center">{skill.name}</span>
</div>
</PieItem>
</div>
)
}
9 changes: 2 additions & 7 deletions src/containers/Index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { PieItem } from '@/components/Common/PieItem'
import { profileData } from '@/data/profile'
import Image from 'next/image'
import { Skills } from './Skills'

export const Index: React.FC = () => {
return (
Expand All @@ -18,12 +18,7 @@ export const Index: React.FC = () => {
<p className="mt-3 top-profile">{profileData.frontProfile}</p>
</div>
</div>
<div className="d-flex flex-column align-items-center bg-body-tertiary p-5">
<h2 className="text-center">Skills</h2>
<div className="row row-cols-1 row-cols-md-2">
<PieItem label="Rails" percent={90} />
</div>
</div>
<Skills className="bg-body-tertiary" />
</div>
)
}
19 changes: 19 additions & 0 deletions src/containers/Skills.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { SkillItem } from '@/components/Portfolio/SkillItem'
import { skillsData } from '@/data/skills'

export type SkillsProps = {
className?: string
}

export const Skills: React.FC<SkillsProps> = ({ className = '' }) => {
return (
<div className={'d-flex flex-column align-items-center p-5 ' + className}>
<h1 className="text-center">Skills</h1>
<div className="row row-cols-md-2 w-75 mt-4">
{skillsData.map((skill) => (
<SkillItem key={skill.name} skill={skill} className="col p-3 my-3" />
))}
</div>
</div>
)
}
34 changes: 34 additions & 0 deletions src/data/skills.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { SkillType } from '@/resources/types'

export const skillsData: SkillType[] = [
{
name: 'Rails',
percent: 90,
logoSrc: '/images/skills/rails.svg',
},
{
name: 'React',
percent: 90,
logoSrc: '/images/skills/react.svg',
},
{
name: 'Typescript',
percent: 90,
logoSrc: '/images/skills/typescript.svg',
},
{
name: 'Python',
percent: 70,
logoSrc: '/images/skills/python.svg',
},
{
name: 'Vue',
percent: 40,
logoSrc: '/images/skills/vue.svg',
},
{
name: 'django',
percent: 10,
logoSrc: '/images/skills/django.svg',
},
]
6 changes: 6 additions & 0 deletions src/resources/types.ts
Original file line number Diff line number Diff line change
@@ -1 +1,7 @@
export type Theme = 'dark' | 'light'

export type SkillType = {
name: string
percent: number
logoSrc?: string
}