UX פאַל לערנען פון אַן איבערבליק בלאַט

ווי אַזוי איך דיזיינד די איבערבליק בלאַט פֿאַר אַלע פּאָסטן-קאַטעגאָריעס

UI און UX גאָולז

מייַן הויפּט ציל מיט אַן איבערבליק בלאַט וואָס ווייַזן אַלע קאַטעגאָריעס פֿאַר ארויס אַרטיקלען איז צו פאַרגרעסערן די דיסקאַוועראַביליטי פון די אַקשלי בנימצא קאַטעגאָריעס. איך האָב אויך געזען דעם ענדערונג ווי אַ געלעגנהייט צו פֿאַרבעסערן די וויזשאַוואַל שיינקייט פון דעם בלאַט און צו ייַנרייען די UX מיט די אנדערע בלעטער פון דעם פּראָגרעסיוו וועב אַפּ.

די פאלגענדע סקרעענשאָט ווייַזן ווי די בלאַט איז געווען איידער די רידיזיין.

Image e8edca7d7ea0

וואָס האט צו טוישן

די אַלט ימפּלאַמענטיישאַן האט צוויי הויפּט ישוז. ערשטער, דער אויסלייג איז פאקטיש פאַרקריפּלט, ווייַל קאַטעגאָריעס מיט ווייניקער ווי 5 עלעמענטן האָבן סקיילד די פאַראַנען בילדער נאָך די פאָרויסיקע ווייַזונג צו דעקן די גאנצע ברייט. צווייטנס, עס איז געווען קיין ערשטיק קאַמף באַר קענטיק אין די שפּיץ פון די בלאַט - עס זאָל באשטימט זיין איינער רענדערד, ווייַל עס גיט די באַניצער הויפּט נאַוויגאַציע עלעמענטן.

דערצו, עס איז קענטיק אַז די איבערבליק בלאַט פֿאַר קאַטעגאָריעס האט נישט טאַקע האָבן אַ גרויס אַרבעט צו מאַכן זיי קענטיק. אַנשטאָט, דער באַניצער בפֿרט געזען דעקן בילדער פֿאַר אַרטיקלען וואָס זענען שייך צו יעדער קאַטעגאָריע. בלויז ווען איר קוק ווידער, די רודערן מיט אַ ייקאַן און טיטל פון יעדער קאַטעגאָריע איז דערקענט. אַחוץ אַז עס איז עסטעטיקלי נישט וואוילגעפעלן, די וי איז פשוט באַדלי דיזיינד.

קערעקטינג מיסטייקס

ווייַל דאָס איז מיין פערזענלעכע וועב אַפּ, איך איז געווען דער ערשטער וואָס מעסט טינגז טכילעס אויף די קאַטעגאָריעס איבערבליק בלאַט. אָן קיין יקסקיוסיז, איך דעריבער געזעסן צו ריווערק די גאנצע בלאַט.

די נייַע ווערסיע ווייַזן אַ איין זייַל פון ראָוז, וווּ יעדער נומער ווייַזן אַ גרויס פאָרויסיקע ווייַזונג בילד פֿאַר אַ קאַטעגאָריע. דער מנהג בילד נעמט די גאנצע ערלויבט ברייט. דער קאַטעגאָריע טיטל אין די מיטל איז סענטערד אויף ביידע אַקסעס, וואָס מאכט עס גלייך קענטיק און רעקאַגנייזאַבאַל. צו פֿאַרבעסערן ליביליטי, איך צוגעגעבן אַ סאַטאַל גראַדיענט פון שוואַרץ צו טראַנספּעראַנט אונטער דעם טעקסט.

נאָך כאַווערינג איבער די בילד און טעקסט, אַן נאָך אינפֿאָרמאַציע טעקסט איז קענטיק, וואָס ווייַזן די גאַנץ נומער פון אַרטיקלען פֿאַר די קאַטעגאָריע - אַן אינפֿאָרמאַציע וואָס איז נישט ביז אַהער בנימצא.

צו פאַרריכטן די נאַוויגאַציע אַרויסגעבן, איך אויך ריוזד די יגזיסטינג קאַמף באַר מיט אַלע הויפּט רוץ פאַראַנען צו דער באַניצער.

Image 0616bdd11b98

ימפּרוווינג דורך יטעראַטיאָן

צו צושטעלן אַ מער אָנגענעם באַניצער דערפאַרונג, איך אויך צוגעגעבן אַ סאַטאַל סקיילינג-אַנאַמיישאַן צו די בילד ווען כאַווערינג איבער אַ קאַטעגאָריע רודערן. ווען די בילד וואָג אין זיין אָריגינעל באַונדריז, די מיינונג איז נישט אַננעסאַסעראַלי וואַקסן.

דערצו, אַ נייַע רודערן אונטער די בילד פון די קאַטעגאָריע ווערט קענטיק דורך אַנאַמיישאַן ווען כאַווערד איבער אים. די רודערן ווייַזן אַ סעלעקציע פון די לעצטע אַרטיקלען פֿאַר די קאַטעגאָריע. יעדער פּאָסטן-פאָרויסיקע ווייַזונג איז אַ לינק צו דעם פּאָסטן. יעדער אנדערע ינטעראַקטיוו עלעמענט אין דער קאַטעגאָריע-רודערן עפֿענען די דעטאַל בלאַט פֿאַר די קאַטעגאָריע.

כּדי צו געבן אַן אילוזיע פון מער אינהאַלט ווי עס אַקשלי, איך געוויינט Daisy-UIs "אָנלייגן" קלאַס צו געבן יעדער פּאָסטן-פאָרויסיקע ווייַזונג אַ פאַלש אָנלייגן צו מאַכן אַ רושם פון מער פאָרויסיקע ווייַזונג זאכן אונטער די קראַנט אָנעס.

Image 41c052a8c928

אויף קליין דעוויסעס, קיין פּריוויוז זענען רענדערד. א באַניצער קענען בלויז גיט אויף די גרויס קאַטעגאָריע בילד צו גיין צו די דעטאַל בלאַט, ווו אַלע אַרטיקלען זענען ליסטעד.

אָפּשאַצונג און דערוואַרטונג

ווי איר קענען זען, אפילו אַ פּשוט בלאַט מיט אַן איבערבליק פון עלעמענטן קען זיין אַ מקור פון וויזשאַוואַל און קאַנסעפּטשואַל ערראָרס און לערנען מאַטעריאַל פֿאַר דיזיינינג אַ גוט און ארבעטן וי און UX.

איך האָב ניט צוגעלייגט קיין היגע טעקסט זוכן פֿאַר יוזערז צו פילטער דורך טעקסט אַרייַנשרייַב. דערווייַל, איך בדעה צו העכערן עקספּלעריישאַן אויף דעם בלאַט דורך סקראָללינג און כאַווערינג. אויב דאָס ווערט אַן אַרויסגעבן אין דער צוקונפֿט (למשל ווייַל יוזערז קענען נישט געפֿינען דעם אינהאַלט זיי זוכן פֿאַר), איך וועל לייגן עטלעכע פֿילטרירונג אָפּציעס. דאָס קען אויך זיין נויטיק ווייַל די נומער פון אַרטיקלען און קאַטעגאָריעס ינקריסיז. דאָך, איך באַגריסן איר צו פּרובירן דעם בלאַט פֿאַר זיך.

דער מקור קאָד

די פאלגענדע טעקסט כּולל די גאַנץ, אַנמאָדיפיעד קאָד פֿאַר ביידע די בלאַט קאַנטיינער און די קאַטעגאָריע גרופּעס. אַלץ איז געשריבן אין Typescript מיט React.js און Tailwind.css. אויב איר טראַכטן איר קענען נוצן עטלעכע פּאַרץ ווידער, איך בין צופרידן אַז איך קען העלפֿן איר.

//
// Page container.
//

import React from "react";
import { CMSCategoryResolution } from "../../cms/entities/cms.entity.catgory";
import Reveal from "../Reveal/Reveal";
import { BogPostCategoryPostsGroup } from "./BlogPostCategoryPostsGroup";
import BlogPostCategoriesOverviewHero from "./BlogPostCategoriesOverviewHero";
import PrimaryActionBar from "../PrimaryActionsBar/PrimaryActionsBar";

/*
 *
 * Interfaces.
 *
 */

interface Props {
  categories: CMSCategoryResolution[];
}

/*
 *
 * Components.
 *
 */

export default function BlogPostCategoriesOverview(props: Props) {
  const { categories } = props;

  return (
    <div className="max-w-6xl mx-auto">
      <BlogPostCategoriesOverviewHero />
      <div className="mt-10 mb-20">
        <PrimaryActionBar isCentered color="white" />
      </div>
      <div className="px-6 mx-auto space-y-6 lg:px-0 md:space-y-16 lg:space-y-20">
        {categories.map((c, i) => (
          <Reveal key={i}>
            <BogPostCategoryPostsGroup category={c} maxPostsEachThreshold={20} />
          </Reveal>
        ))}
      </div>
    </div>
  );
}

//
// BogPostCategoryPostsGroup.
//

import React from "react";
import { CMSCategoryResolution } from "../../cms/entities/cms.entity.catgory";
import { FLPath } from "../../models/route/model.route";
import { CMSCategoryIconFactory } from "../CMS/CMSCategoryIcon";
import Link from "next/link";
import RiMore from "remixicon-react/MoreLineIcon";

/*
 *
 * Interfaces.
 *
 */

interface Props {
  category: CMSCategoryResolution;
  maxPostsEachThreshold: number;
}

/*
 *
 * Components.
 *
 */

export const BogPostCategoryPostsGroup = (props: Props) => {
  const { category, maxPostsEachThreshold } = props;
  const { posts } = category;

  if (posts.length === 0) {
    return null;
  }

  const url = `${FLPath.Categories}/${category.slug.current}`;
  const Icon = CMSCategoryIconFactory({ variant: category.slug.current });

  return (
    <div className="flex flex-col items-center group">
      <div className="relative max-w-4xl overflow-visible rounded-md">
        <div className="absolute items-end justify-start hidden w-full h-full px-6 space-x-4 overflow-x-scroll duration-500 ease-in-out translate-y-12 opacity-0 md:flex pb-14 group-hover:opacity-100 group-hover:translate-y-20">
          {posts.slice(0, 4).map((p, i) => (
            <span className="stack">
              <Link
                href={`${FLPath.Posts}/${p.slug.current}`}
                aria-label={p.title}
                prefetch={false}>
                <a className="duration-200 ease-out hover:scale-105">
                  <img
                    src={p.imageUrl.jpg}
                    alt={p.title}
                    loading="lazy"
                    className="object-contain h-20 rounded "
                  />
                </a>
              </Link>

              {Array.from({ length: 2 }, (_, i) => (
                <span key={i} style={{ width: 152, height: 80 }} className="bg-gray-800 rounded" />
              ))}
            </span>
          ))}
          {posts.length >= 5 && (
            <Link passHref href={url} aria-label={`Link to ${category.title}`} prefetch={false}>
              <a className="flex flex-col items-center justify-center h-20 w-14">
                <RiMore />
              </a>
            </Link>
          )}
        </div>

        <div className="relative flex flex-col items-center overflow-hidden duration-500 ease-in-out rounded-md shadow-xl md:group-hover:-translate-y-20">
          <img
            className="object-cover w-full duration-500 ease-in-out group-hover:scale-105"
            width={960}
            height={200}
            src={category.imageUrl.webp}
            alt={category.title}
            loading="lazy"
          />
          <Link passHref href={url} aria-label={`Link to ${category.title}`} prefetch={false}>
            <a className="absolute flex flex-col items-center justify-center w-full h-full bg-gradient-to-t from-primary">
              <span className="flex items-center space-x-2 duration-300 ease-in-out translate-y-2 group-hover:-translate-y-3">
                <Icon size="2em" />
                <h2 className="text-sm md:text-xl">{category.title}</h2>
              </span>
              <span className="text-sm font-light text-gray-200 transition duration-500 ease-in-out translate-y-2 opacity-0 group-hover:opacity-100 group-hover:-translate-y-2">
                {category.posts.length}
                {category.posts.length === maxPostsEachThreshold ? "+" : ""}{" "}
                {category.posts.length === 1 ? "post" : "posts"}
              </span>
            </a>
          </Link>
        </div>
      </div>
    </div>
  );
};