iT邦幫忙

2023 iThome 鐵人賽

DAY 28
0
Modern Web

職缺資訊平台—Jobscanner系列 第 28

[開發] 借站巨人的肩膀 -Chakra UI

  • 分享至 

  • xImage
  •  

靜態切版

Job Card

示意:
https://ithelp.ithome.com.tw/upload/images/20231013/20128122EmWHK2m8XI.png

props 接收單一職缺的資料內容,render 職缺名稱、公司名稱、描述、地點、薪資等資訊

// 略
export function JobCard({ job }) {
  const data = { ...job };
  // 不同刊登平台 Badege 底色
  const badgeColor = (jobSource) => {
    let color;
    switch (jobSource) {
      case "104":
        color = "orange";
        break;
      case "yourator":
        color = "blue";
        break;
      case "cakeresume":
        color = "green";
        break;
      default:
        color = "blue";
    }
    return color;
  };

  return (
    <Card maxW={{ sm: "xl", lg: "md" }}>
      <CardBody>
        <HStack mb={4}>
          <Avatar
            size="sm"
            src={data.companyLogo ? data.companyLogo : one04Logo}
          />
          <Text fontSize="sm" noOfLines={1}>
            {data.companyName}
          </Text>
        </HStack>
        <Flex direction="column" textAlign="left" gap="2">
          <Heading size="md">
            <Link href={data.url} isExternal noOfLines={1}>
              {data.name}
            </Link>
          </Heading>
          <Box>
            <Badge
              variant="solid"
              colorScheme={badgeColor(data.source)}
              fontSize="xs"
            >
              {data.source}
            </Badge>
          </Box>
          <Text fontSize="sm" noOfLines={3} align="start">
            {data.description}
          </Text>
        </Flex>
      </CardBody>
      <CardFooter justify="space-between" flexWrap="wrap">
        <Flex gap={2} wrap="wrap">
          <Tag color="gray.500">
            <Icon as={MdLocationOn} />
            {data.location}
          </Tag>
          <Tag color="gray.500">
            <Icon as={MdAttachMoney} />
            {toThousandSeparator(data.salary[0])} ~{" "}
            {toThousandSeparator(data.salary[1])} ({data.salaryType})
          </Tag>
        </Flex>
      </CardFooter>
    </Card>
  );
}

使用 SimpleGrid 設定不同裝置下的排版 (單欄或三欄排列)

// 略
export default function JobCardList({jobs}) {
  const jobsData = [...jobs]
  const jobItems = jobsData.map((job) => {
    return (<JobCard  key={job.key} job={job}></JobCard>)
  })

  return (
    <SimpleGrid columns={{ md: 1, lg: 3 }} spacing={5}>
      {jobItems}
    </SimpleGrid>
  );
}

Sort

原規劃的 Search Input 改為 Select 方式選擇地點或刊登平台,並以 Tag 方式呈現
(參考自 CakeResume 作法)

示意:
https://ithelp.ithome.com.tw/upload/images/20231013/2012812253ztSb6sGE.png


畫面

原規劃 Wireframe
https://ithelp.ithome.com.tw/upload/images/20231013/20128122Lt83R5IyHs.png

調整後的切版畫面
https://ithelp.ithome.com.tw/upload/images/20231013/201281223MLkn9pIi0.png


其他

最終移除掉搜尋關鍵字的功能?

邊做邊改時,想起曾經和設計師討論過表單的設計,內容大概是:
使用者可以透過介面表單,填寫他們要的樣板基本樣式,例如字級大小、行數。但到底是要開一個文字輸入框,讓使用者自由填寫,還是先限縮幾個常用選項出來?

自由填寫會延伸出來的問題是:

  • 驗證規則是?
  • 怎麼提示錯誤給使用者知道?
  • 什麽時機提醒使用者欄位資料不正確?提交時? input blur 時? 即時?

這本書 微互動 Microinteractions 有這麼一段話:
『假如你可以掌控使用者的視線,就能掌控他們將會移動的方向。』
有時候有限的選項對使用者的操作體驗反而是加分的!

於是思考原本的搜尋職缺關鍵字功能,會希望搜尋什麽或是既有資料能搜什麽?
由使用者輸入關鍵字的做法,就像開了一個大門,但很可能是什麽結果都沒有,最後參考 CakeResume 作法,以過濾既有條件的方式篩選結果。


上一篇
[開發] 透過 Cloud Functions 將職缺資料寫入 Firestore
下一篇
[開發] 串接 Firestore
系列文
職缺資訊平台—Jobscanner31
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言