Refactor card components for improved styling and icon updates
This commit is contained in:
parent
3d42c1fc21
commit
9c09a9d91e
@ -1,6 +1,6 @@
|
|||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
import LazyImage from '../lazy-image';
|
import LazyImage from '../lazy-image';
|
||||||
import { AiOutlineContainer } from 'react-icons/ai';
|
import { PiNewspaper } from 'react-icons/pi';
|
||||||
import { getDevPost, getMediumPost } from '@arifszn/blog-js';
|
import { getDevPost, getMediumPost } from '@arifszn/blog-js';
|
||||||
import { formatDistance } from 'date-fns';
|
import { formatDistance } from 'date-fns';
|
||||||
import { SanitizedBlog } from '../../interfaces/sanitized-config';
|
import { SanitizedBlog } from '../../interfaces/sanitized-config';
|
||||||
@ -38,7 +38,7 @@ const BlogCard = ({
|
|||||||
const array = [];
|
const array = [];
|
||||||
for (let index = 0; index < blog.limit; index++) {
|
for (let index = 0; index < blog.limit; index++) {
|
||||||
array.push(
|
array.push(
|
||||||
<div className="card shadow-lg card-sm bg-base-100" key={index}>
|
<div className="card shadow-md card-sm bg-base-100" key={index}>
|
||||||
<div className="p-8 h-full w-full">
|
<div className="p-8 h-full w-full">
|
||||||
<div className="flex items-center flex-col md:flex-row">
|
<div className="flex items-center flex-col md:flex-row">
|
||||||
<div className="avatar mb-5 md:mb-0">
|
<div className="avatar mb-5 md:mb-0">
|
||||||
@ -95,7 +95,7 @@ const BlogCard = ({
|
|||||||
return articles && articles.length ? (
|
return articles && articles.length ? (
|
||||||
articles.slice(0, blog.limit).map((article, index) => (
|
articles.slice(0, blog.limit).map((article, index) => (
|
||||||
<a
|
<a
|
||||||
className="card shadow-lg card-sm bg-base-100 cursor-pointer"
|
className="card shadow-md card-sm bg-base-100 cursor-pointer"
|
||||||
key={index}
|
key={index}
|
||||||
href={article.link}
|
href={article.link}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
@ -162,7 +162,7 @@ const BlogCard = ({
|
|||||||
))
|
))
|
||||||
) : (
|
) : (
|
||||||
<div className="text-center mb-6">
|
<div className="text-center mb-6">
|
||||||
<AiOutlineContainer className="mx-auto h-12 w-12 opacity-30" />
|
<PiNewspaper className="mx-auto h-12 w-12 opacity-30" />
|
||||||
<p className="mt-1 text-sm opacity-50 text-base-content">
|
<p className="mt-1 text-sm opacity-50 text-base-content">
|
||||||
No recent post
|
No recent post
|
||||||
</p>
|
</p>
|
||||||
@ -172,34 +172,38 @@ const BlogCard = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="col-span-1 lg:col-span-2">
|
<div className="col-span-1 lg:col-span-2">
|
||||||
<div className="grid grid-cols-2 gap-6">
|
<div className="card bg-base-200 shadow-xl border border-base-300">
|
||||||
<div className="col-span-2">
|
<div className="card-body p-8">
|
||||||
<div
|
<div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 mb-8">
|
||||||
className={`card card-sm bg-base-100 ${
|
<div className="flex items-center space-x-3">
|
||||||
loading || (articles && articles.length)
|
{loading ? (
|
||||||
? 'shadow-sm bg-opacity-40'
|
skeleton({
|
||||||
: 'shadow-lg'
|
widthCls: 'w-12',
|
||||||
}`}
|
heightCls: 'h-12',
|
||||||
>
|
className: 'rounded-xl',
|
||||||
<div className="card-body">
|
})
|
||||||
<div className="mx-3 mb-2">
|
) : (
|
||||||
<h5 className="card-title">
|
<div className="flex items-center justify-center w-12 h-12 bg-primary/10 rounded-xl">
|
||||||
{loading ? (
|
<PiNewspaper className="text-2xl" />
|
||||||
skeleton({ widthCls: 'w-28', heightCls: 'h-8' })
|
|
||||||
) : (
|
|
||||||
<span className="text-base-content opacity-70">
|
|
||||||
My Articles
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</h5>
|
|
||||||
</div>
|
|
||||||
<div className="col-span-2">
|
|
||||||
<div className="grid grid-cols-1 gap-6">
|
|
||||||
{loading || !articles ? renderSkeleton() : renderArticles()}
|
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="min-w-0 flex-1">
|
||||||
|
<h3 className="text-base sm:text-lg font-bold text-base-content truncate">
|
||||||
|
{loading
|
||||||
|
? skeleton({ widthCls: 'w-28', heightCls: 'h-8' })
|
||||||
|
: 'My Articles'}
|
||||||
|
</h3>
|
||||||
|
<p className="text-base-content/60 text-xs sm:text-sm mt-1 truncate">
|
||||||
|
{loading
|
||||||
|
? skeleton({ widthCls: 'w-32', heightCls: 'h-4' })
|
||||||
|
: 'Recent posts'}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="grid grid-cols-1 gap-6">
|
||||||
|
{loading || !articles ? renderSkeleton() : renderArticles()}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
import { Fragment } from 'react';
|
import { Fragment } from 'react';
|
||||||
import LazyImage from '../lazy-image';
|
import LazyImage from '../lazy-image';
|
||||||
|
import { MdOpenInNew } from 'react-icons/md';
|
||||||
import { ga, skeleton } from '../../utils';
|
import { ga, skeleton } from '../../utils';
|
||||||
import { SanitizedExternalProject } from '../../interfaces/sanitized-config';
|
import { SanitizedExternalProject } from '../../interfaces/sanitized-config';
|
||||||
|
|
||||||
@ -18,7 +19,7 @@ const ExternalProjectCard = ({
|
|||||||
const array = [];
|
const array = [];
|
||||||
for (let index = 0; index < externalProjects.length; index++) {
|
for (let index = 0; index < externalProjects.length; index++) {
|
||||||
array.push(
|
array.push(
|
||||||
<div className="card shadow-lg card-sm bg-base-100" key={index}>
|
<div className="card shadow-md card-sm bg-base-100" key={index}>
|
||||||
<div className="p-8 h-full w-full">
|
<div className="p-8 h-full w-full">
|
||||||
<div className="flex items-center flex-col">
|
<div className="flex items-center flex-col">
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
@ -69,7 +70,7 @@ const ExternalProjectCard = ({
|
|||||||
const renderExternalProjects = () => {
|
const renderExternalProjects = () => {
|
||||||
return externalProjects.map((item, index) => (
|
return externalProjects.map((item, index) => (
|
||||||
<a
|
<a
|
||||||
className="card shadow-lg card-sm bg-base-100 cursor-pointer"
|
className="card shadow-md card-sm bg-base-100 cursor-pointer"
|
||||||
key={index}
|
key={index}
|
||||||
href={item.link}
|
href={item.link}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
@ -126,28 +127,38 @@ const ExternalProjectCard = ({
|
|||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<div className="col-span-1 lg:col-span-2">
|
<div className="col-span-1 lg:col-span-2">
|
||||||
<div className="grid grid-cols-2 gap-6">
|
<div className="card bg-base-200 shadow-xl border border-base-300">
|
||||||
<div className="col-span-2">
|
<div className="card-body p-8">
|
||||||
<div className="card card-sm bg-base-100 shadow-sm bg-opacity-40">
|
<div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 mb-8">
|
||||||
<div className="card-body">
|
<div className="flex items-center space-x-3">
|
||||||
<div className="mx-3 flex items-center justify-between mb-2">
|
{loading ? (
|
||||||
<h5 className="card-title">
|
skeleton({
|
||||||
{loading ? (
|
widthCls: 'w-12',
|
||||||
skeleton({ widthCls: 'w-40', heightCls: 'h-8' })
|
heightCls: 'h-12',
|
||||||
) : (
|
className: 'rounded-xl',
|
||||||
<span className="text-base-content opacity-70">
|
})
|
||||||
{header}
|
) : (
|
||||||
</span>
|
<div className="flex items-center justify-center w-12 h-12 bg-primary/10 rounded-xl">
|
||||||
)}
|
<MdOpenInNew className="text-2xl" />
|
||||||
</h5>
|
|
||||||
</div>
|
|
||||||
<div className="col-span-2">
|
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
||||||
{loading ? renderSkeleton() : renderExternalProjects()}
|
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="min-w-0 flex-1">
|
||||||
|
<h3 className="text-base sm:text-lg font-bold text-base-content truncate">
|
||||||
|
{loading
|
||||||
|
? skeleton({ widthCls: 'w-40', heightCls: 'h-8' })
|
||||||
|
: header}
|
||||||
|
</h3>
|
||||||
|
<p className="text-base-content/60 text-xs sm:text-sm mt-1 truncate">
|
||||||
|
{loading
|
||||||
|
? skeleton({ widthCls: 'w-32', heightCls: 'h-4' })
|
||||||
|
: `Showcasing ${externalProjects.length} external projects`}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||||
|
{loading ? renderSkeleton() : renderExternalProjects()}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
import { Fragment } from 'react';
|
import { Fragment } from 'react';
|
||||||
import { AiOutlineFork, AiOutlineStar } from 'react-icons/ai';
|
import { AiOutlineFork, AiOutlineStar, AiOutlineGithub } from 'react-icons/ai';
|
||||||
import { MdInsertLink } from 'react-icons/md';
|
import { MdInsertLink } from 'react-icons/md';
|
||||||
import { ga, getLanguageColor, skeleton } from '../../utils';
|
import { ga, getLanguageColor, skeleton } from '../../utils';
|
||||||
import { GithubProject } from '../../interfaces/github-project';
|
import { GithubProject } from '../../interfaces/github-project';
|
||||||
@ -9,14 +9,12 @@ const GithubProjectCard = ({
|
|||||||
githubProjects,
|
githubProjects,
|
||||||
loading,
|
loading,
|
||||||
limit,
|
limit,
|
||||||
username,
|
|
||||||
googleAnalyticsId,
|
googleAnalyticsId,
|
||||||
}: {
|
}: {
|
||||||
header: string;
|
header: string;
|
||||||
githubProjects: GithubProject[];
|
githubProjects: GithubProject[];
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
limit: number;
|
limit: number;
|
||||||
username: string;
|
|
||||||
googleAnalyticsId?: string;
|
googleAnalyticsId?: string;
|
||||||
}) => {
|
}) => {
|
||||||
if (!loading && githubProjects.length === 0) {
|
if (!loading && githubProjects.length === 0) {
|
||||||
@ -27,7 +25,7 @@ const GithubProjectCard = ({
|
|||||||
const array = [];
|
const array = [];
|
||||||
for (let index = 0; index < limit; index++) {
|
for (let index = 0; index < limit; index++) {
|
||||||
array.push(
|
array.push(
|
||||||
<div className="card shadow-lg card-sm bg-base-100" key={index}>
|
<div className="card shadow-md card-sm bg-base-100" key={index}>
|
||||||
<div className="flex justify-between flex-col p-8 h-full w-full">
|
<div className="flex justify-between flex-col p-8 h-full w-full">
|
||||||
<div>
|
<div>
|
||||||
<div className="flex items-center">
|
<div className="flex items-center">
|
||||||
@ -76,7 +74,7 @@ const GithubProjectCard = ({
|
|||||||
const renderProjects = () => {
|
const renderProjects = () => {
|
||||||
return githubProjects.map((item, index) => (
|
return githubProjects.map((item, index) => (
|
||||||
<a
|
<a
|
||||||
className="card shadow-lg card-sm bg-base-100 cursor-pointer"
|
className="card shadow-md card-sm bg-base-100 cursor-pointer"
|
||||||
href={item.html_url}
|
href={item.html_url}
|
||||||
key={index}
|
key={index}
|
||||||
onClick={(e) => {
|
onClick={(e) => {
|
||||||
@ -84,9 +82,7 @@ const GithubProjectCard = ({
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
if (googleAnalyticsId) {
|
if (googleAnalyticsId) {
|
||||||
ga.event('Click project', {
|
ga.event('Click project', { project: item.name });
|
||||||
project: item.name,
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
@ -136,40 +132,41 @@ const GithubProjectCard = ({
|
|||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<div className="col-span-1 lg:col-span-2">
|
<div className="col-span-1 lg:col-span-2">
|
||||||
<div className="grid grid-cols-2 gap-6">
|
<div className="card bg-base-200 shadow-xl border border-base-300">
|
||||||
<div className="col-span-2">
|
<div className="card-body p-8">
|
||||||
<div className="card card-sm bg-base-100 shadow-sm bg-opacity-40">
|
{/* Enhanced Header Section */}
|
||||||
<div className="card-body">
|
<div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 mb-8">
|
||||||
<div className="mx-3 flex items-center justify-between mb-2">
|
<div className="flex items-center space-x-3">
|
||||||
<h5 className="card-title">
|
{loading ? (
|
||||||
{loading ? (
|
skeleton({
|
||||||
skeleton({ widthCls: 'w-40', heightCls: 'h-8' })
|
widthCls: 'w-12',
|
||||||
) : (
|
heightCls: 'h-12',
|
||||||
<span className="text-base-content opacity-70">
|
className: 'rounded-xl',
|
||||||
{header}
|
})
|
||||||
</span>
|
) : (
|
||||||
)}
|
<div className="flex items-center justify-center w-12 h-12 bg-primary/10 rounded-xl">
|
||||||
</h5>
|
<AiOutlineGithub className="text-2xl" />
|
||||||
{loading ? (
|
|
||||||
skeleton({ widthCls: 'w-10', heightCls: 'h-5' })
|
|
||||||
) : (
|
|
||||||
<a
|
|
||||||
href={`https://github.com/${username}?tab=repositories`}
|
|
||||||
target="_blank"
|
|
||||||
rel="noreferrer"
|
|
||||||
className="text-base-content opacity-50 hover:underline"
|
|
||||||
>
|
|
||||||
See All
|
|
||||||
</a>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<div className="col-span-2">
|
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
||||||
{loading ? renderSkeleton() : renderProjects()}
|
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="min-w-0 flex-1">
|
||||||
|
<h3 className="text-base sm:text-lg font-bold text-base-content truncate">
|
||||||
|
{loading
|
||||||
|
? skeleton({ widthCls: 'w-48', heightCls: 'h-8' })
|
||||||
|
: header}
|
||||||
|
</h3>
|
||||||
|
<p className="text-base-content/60 text-xs sm:text-sm mt-1 truncate">
|
||||||
|
{loading
|
||||||
|
? skeleton({ widthCls: 'w-32', heightCls: 'h-4' })
|
||||||
|
: `Showcasing ${githubProjects.length} featured repositories`}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Projects Grid */}
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||||
|
{loading ? renderSkeleton() : renderProjects()}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -1,4 +1,5 @@
|
|||||||
import { Fragment } from 'react';
|
import { Fragment } from 'react';
|
||||||
|
import { AiOutlineBook } from 'react-icons/ai';
|
||||||
import { SanitizedPublication } from '../../interfaces/sanitized-config';
|
import { SanitizedPublication } from '../../interfaces/sanitized-config';
|
||||||
import { skeleton } from '../../utils';
|
import { skeleton } from '../../utils';
|
||||||
|
|
||||||
@ -13,7 +14,7 @@ const PublicationCard = ({
|
|||||||
const array = [];
|
const array = [];
|
||||||
for (let index = 0; index < publications.length; index++) {
|
for (let index = 0; index < publications.length; index++) {
|
||||||
array.push(
|
array.push(
|
||||||
<div className="card shadow-lg card-sm bg-base-100" key={index}>
|
<div className="card shadow-md card-sm bg-base-100" key={index}>
|
||||||
<div className="p-8 h-full w-full">
|
<div className="p-8 h-full w-full">
|
||||||
<div className="flex items-center flex-col">
|
<div className="flex items-center flex-col">
|
||||||
<div className="w-full">
|
<div className="w-full">
|
||||||
@ -76,7 +77,7 @@ const PublicationCard = ({
|
|||||||
const renderPublications = () => {
|
const renderPublications = () => {
|
||||||
return publications.map((item, index) => (
|
return publications.map((item, index) => (
|
||||||
<a
|
<a
|
||||||
className="card shadow-lg card-sm bg-base-100 cursor-pointer"
|
className="card shadow-md card-sm bg-base-100 cursor-pointer"
|
||||||
key={index}
|
key={index}
|
||||||
href={item.link}
|
href={item.link}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
@ -120,28 +121,38 @@ const PublicationCard = ({
|
|||||||
return (
|
return (
|
||||||
<Fragment>
|
<Fragment>
|
||||||
<div className="col-span-1 lg:col-span-2">
|
<div className="col-span-1 lg:col-span-2">
|
||||||
<div className="grid grid-cols-2 gap-6">
|
<div className="card bg-base-200 shadow-xl border border-base-300">
|
||||||
<div className="col-span-2">
|
<div className="card-body p-8">
|
||||||
<div className="card card-sm bg-base-100 shadow-sm bg-opacity-40">
|
<div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 mb-8">
|
||||||
<div className="card-body">
|
<div className="flex items-center space-x-3">
|
||||||
<div className="mx-3 flex items-center justify-between mb-2">
|
{loading ? (
|
||||||
<h5 className="card-title">
|
skeleton({
|
||||||
{loading ? (
|
widthCls: 'w-12',
|
||||||
skeleton({ widthCls: 'w-40', heightCls: 'h-8' })
|
heightCls: 'h-12',
|
||||||
) : (
|
className: 'rounded-xl',
|
||||||
<span className="text-base-content opacity-70">
|
})
|
||||||
Publications
|
) : (
|
||||||
</span>
|
<div className="flex items-center justify-center w-12 h-12 bg-primary/10 rounded-xl">
|
||||||
)}
|
<AiOutlineBook className="text-2xl" />
|
||||||
</h5>
|
|
||||||
</div>
|
|
||||||
<div className="col-span-2">
|
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
||||||
{loading ? renderSkeleton() : renderPublications()}
|
|
||||||
</div>
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="min-w-0 flex-1">
|
||||||
|
<h3 className="text-base sm:text-lg font-bold text-base-content truncate">
|
||||||
|
{loading
|
||||||
|
? skeleton({ widthCls: 'w-40', heightCls: 'h-8' })
|
||||||
|
: 'Publications'}
|
||||||
|
</h3>
|
||||||
|
<p className="text-base-content/60 text-xs sm:text-sm mt-1 truncate">
|
||||||
|
{loading
|
||||||
|
? skeleton({ widthCls: 'w-32', heightCls: 'h-4' })
|
||||||
|
: `Showcasing ${publications.length} publications`}
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||||
|
{loading ? renderSkeleton() : renderPublications()}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -33,14 +33,11 @@ const SkillCard = ({
|
|||||||
</h5>
|
</h5>
|
||||||
</div>
|
</div>
|
||||||
<div className="p-3 flow-root">
|
<div className="p-3 flow-root">
|
||||||
<div className="-m-1 flex flex-wrap justify-center">
|
<div className="-m-1 flex flex-wrap justify-center gap-2">
|
||||||
{loading
|
{loading
|
||||||
? renderSkeleton()
|
? renderSkeleton()
|
||||||
: skills.map((skill, index) => (
|
: skills.map((skill, index) => (
|
||||||
<div
|
<div key={index} className="badge badge-primary badge-sm">
|
||||||
key={index}
|
|
||||||
className="m-1 text-xs inline-flex items-center font-bold leading-sm px-3 py-1 badge-primary bg-opacity-90 rounded-full"
|
|
||||||
>
|
|
||||||
{skill}
|
{skill}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@ -65,7 +65,7 @@ const ThemeChanger = ({
|
|||||||
<div className="flex-0">
|
<div className="flex-0">
|
||||||
{loading ? (
|
{loading ? (
|
||||||
skeleton({
|
skeleton({
|
||||||
widthCls: 'w-14 md:w-28',
|
widthCls: 'w-12',
|
||||||
heightCls: 'h-10',
|
heightCls: 'h-10',
|
||||||
className: 'mr-6',
|
className: 'mr-6',
|
||||||
})
|
})
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user