Extracted display of Job image into a component

This commit is contained in:
Justin Edmund 2023-01-23 22:08:38 -08:00
parent fadf422d9a
commit 6f32c975ce
4 changed files with 147 additions and 65 deletions

View file

@ -0,0 +1,80 @@
.JobImage {
$height: 252px;
$width: 447px;
aspect-ratio: 7/9;
background: url('/images/background_a.jpg');
background-size: 500px 281px;
border-radius: $unit;
box-sizing: border-box;
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.2);
display: block;
isolation: isolate;
flex-grow: 2;
flex-shrink: 0;
height: $height;
margin-right: $unit * 3;
max-height: $height;
max-width: $width;
overflow: hidden;
position: relative;
width: $width;
transition: box-shadow 0.15s ease-in-out;
// prettier-ignore
@media only screen
and (max-width: 800px)
and (max-height: 920px)
and (-webkit-min-device-pixel-ratio: 2) {
margin-right: 0;
width: 100%;
}
@include breakpoint(phone) {
aspect-ratio: 16/9;
margin: 0;
width: 100%;
height: inherit;
}
img {
-webkit-filter: drop-shadow(4px 4px 8px rgba(0, 0, 0, 0.48));
filter: drop-shadow(4px 4px 8px rgba(0, 0, 0, 0.48));
position: relative;
top: $unit * -4;
left: 50%;
transform: translateX(-50%);
width: 100%;
z-index: 2;
}
.JobAccessory.Button {
align-items: center;
border-radius: 99px;
justify-content: center;
position: relative;
padding: $unit * 1.5;
top: $unit;
left: $unit;
height: auto;
z-index: 10;
&:hover .Accessory svg {
stroke: var(--button-text-hover);
}
.Accessory svg {
fill: none;
stroke: var(--button-text);
stroke-width: 3px;
width: $unit-3x;
height: auto;
}
}
.Overlay {
background: none;
position: absolute;
z-index: 1;
}
}

View file

@ -0,0 +1,61 @@
import React, { useEffect, useState } from 'react'
import { useRouter } from 'next/router'
import { useTranslation } from 'next-i18next'
import Button from '~components/Button'
import ShieldIcon from '~public/icons/Shield.svg'
import './index.scss'
interface Props {
job?: Job
user?: User
onAccessoryButtonClicked: () => void
}
const ACCESSORY_JOB_IDS = ['683ffee8-4ea2-432d-bc30-4865020ac9f4']
const JobImage = ({ job, user, onAccessoryButtonClicked }: Props) => {
// Localization
const { t } = useTranslation('common')
const router = useRouter()
const locale =
router.locale && ['en', 'ja'].includes(router.locale) ? router.locale : 'en'
// Static variables
const imageUrl = () => {
let source = ''
if (job) {
const slug = job.name.en.replaceAll(' ', '-').toLowerCase()
const gender = user && user.gender == 1 ? 'b' : 'a'
source = `${process.env.NEXT_PUBLIC_SIERO_IMG_URL}/jobs/${slug}_${gender}.png`
}
return source
}
const hasAccessory = job && ACCESSORY_JOB_IDS.includes(job.id)
const image = <img alt={job?.name[locale]} src={imageUrl()} />
// Elements
const accessoryButton = () => {
return (
<Button
accessoryIcon={<ShieldIcon />}
className="JobAccessory"
onClick={onAccessoryButtonClicked}
/>
)
}
return (
<div className="JobImage">
{hasAccessory ? accessoryButton() : ''}
{job && job.id !== '-1' ? image : ''}
<div className="Job Overlay" />
</div>
)
}
export default JobImage

View file

@ -53,63 +53,6 @@
} }
} }
.JobImage {
$height: 252px;
$width: 447px;
aspect-ratio: 7/9;
background: url('/images/background_a.jpg');
background-size: 500px 281px;
border-radius: $unit;
box-sizing: border-box;
box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.2);
display: block;
isolation: isolate;
flex-grow: 2;
flex-shrink: 0;
height: $height;
margin-right: $unit * 3;
max-height: $height;
max-width: $width;
overflow: hidden;
position: relative;
width: $width;
transition: box-shadow 0.15s ease-in-out;
// prettier-ignore
@media only screen
and (max-width: 800px)
and (max-height: 920px)
and (-webkit-min-device-pixel-ratio: 2) {
margin-right: 0;
width: 100%;
}
@include breakpoint(phone) {
aspect-ratio: 16/9;
margin: 0;
width: 100%;
height: inherit;
}
img {
-webkit-filter: drop-shadow(4px 4px 8px rgba(0, 0, 0, 0.48));
filter: drop-shadow(4px 4px 8px rgba(0, 0, 0, 0.48));
position: relative;
top: $unit * -4;
left: 50%;
transform: translateX(-50%);
width: 100%;
z-index: 2;
}
.Overlay {
background: none;
position: absolute;
z-index: 1;
}
}
.JobSkills { .JobSkills {
display: flex; display: flex;
flex-direction: column; flex-direction: column;

View file

@ -4,6 +4,7 @@ import { useSnapshot } from 'valtio'
import { useTranslation } from 'next-i18next' import { useTranslation } from 'next-i18next'
import JobDropdown from '~components/JobDropdown' import JobDropdown from '~components/JobDropdown'
import JobImage from '~components/JobImage'
import JobSkillItem from '~components/JobSkillItem' import JobSkillItem from '~components/JobSkillItem'
import SearchModal from '~components/SearchModal' import SearchModal from '~components/SearchModal'
@ -130,14 +131,11 @@ const JobSection = (props: Props) => {
// Render: JSX components // Render: JSX components
return ( return (
<section id="Job"> <section id="Job">
<div className="JobImage"> <JobImage
{party.job && party.job.id !== '-1' ? ( job={party.job}
<img alt={party.job.name[locale]} src={imageUrl} /> user={party.user}
) : ( onAccessoryButtonClicked={() => {}}
'' />
)}
<div className="Job Overlay" />
</div>
<div className="JobDetails"> <div className="JobDetails">
{props.editable ? ( {props.editable ? (
<JobDropdown <JobDropdown