chore: replace nextjs Image element (#1227)

This commit is contained in:
Aaryan Khandelwal 2023-06-07 01:56:21 +05:30 committed by GitHub
parent 1f3fdd5d0a
commit 684df96969
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 121 additions and 186 deletions

View File

@ -1,4 +1,7 @@
module.exports = {
root: true,
extends: ["custom"],
rules: {
"@next/next/no-img-element": "off",
},
};

View File

@ -1,5 +1,3 @@
import Image from "next/image";
type Props = {
users: {
avatar: string | null;
@ -23,12 +21,10 @@ export const AnalyticsLeaderboard: React.FC<Props> = ({ users, title }) => (
>
<div className="flex items-center gap-2">
{user && user.avatar && user.avatar !== "" ? (
<div className="rounded-full h-4 w-4 flex-shrink-0">
<Image
<div className="relative rounded-full h-4 w-4 flex-shrink-0">
<img
src={user.avatar}
height="100%"
width="100%"
className="rounded-full"
className="absolute top-0 left-0 h-full w-full object-cover rounded-full"
alt={user.email ?? "None"}
/>
</div>

View File

@ -1,5 +1,6 @@
import React from "react";
import Image from "next/image";
import Link from "next/link";
// icons
import {
@ -22,7 +23,6 @@ import { renderShortNumericDateFormat, timeAgo } from "helpers/date-time.helper"
import { addSpaceIfCamelCase } from "helpers/string.helper";
// types
import RemirrorRichTextEditor from "components/rich-text-editor";
import Link from "next/link";
const activityDetails: {
[key: string]: {
@ -206,7 +206,7 @@ export const Feeds: React.FC<any> = ({ activities }) => (
<div className="relative flex items-start space-x-3">
<div className="relative px-1">
{activity.actor_detail.avatar && activity.actor_detail.avatar !== "" ? (
<Image
<img
src={activity.actor_detail.avatar}
alt={activity.actor_detail.first_name}
height={30}
@ -276,7 +276,7 @@ export const Feeds: React.FC<any> = ({ activities }) => (
activityDetails[activity.field as keyof typeof activityDetails]?.icon
) : activity.actor_detail.avatar &&
activity.actor_detail.avatar !== "" ? (
<Image
<img
src={activity.actor_detail.avatar}
alt={activity.actor_detail.first_name}
height={24}

View File

@ -1,8 +1,5 @@
import React, { useEffect, useState, useRef } from "react";
// next
import Image from "next/image";
// swr
import useSWR from "swr";
@ -107,12 +104,7 @@ export const ImagePickerPopover: React.FC<Props> = ({ label, value, onChange })
onChange={(e) => setFormData({ ...formData, search: e.target.value })}
placeholder="Search for images"
/>
<PrimaryButton
type="button"
onClick={() => setSearchParams(formData.search)}
className="bg-indigo-600"
size="sm"
>
<PrimaryButton onClick={() => setSearchParams(formData.search)} size="sm">
Search
</PrimaryButton>
</div>
@ -123,12 +115,10 @@ export const ImagePickerPopover: React.FC<Props> = ({ label, value, onChange })
key={image.id}
className="relative col-span-2 aspect-video md:col-span-1"
>
<Image
<img
src={image.urls.small}
alt={image.alt_description}
layout="fill"
objectFit="cover"
className="cursor-pointer rounded"
className="cursor-pointer rounded absolute top-0 left-0 h-full w-full object-cover"
onClick={() => {
setIsOpen(false);
onChange(image.urls.regular);

View File

@ -1,7 +1,6 @@
import React from "react";
import Link from "next/link";
import Image from "next/image";
import { useRouter } from "next/router";
import useSWR, { mutate } from "swr";
@ -301,7 +300,7 @@ export const ActiveCycleDetails: React.FC<TSingleStatProps> = ({ cycle, isComple
<div className="flex items-center gap-4">
<div className="flex items-center gap-2.5 text-brand-secondary">
{cycle.owned_by.avatar && cycle.owned_by.avatar !== "" ? (
<Image
<img
src={cycle.owned_by.avatar}
height={16}
width={16}

View File

@ -1,6 +1,5 @@
import React from "react";
import Image from "next/image";
import { useRouter } from "next/router";
import useSWR from "swr";
@ -16,8 +15,6 @@ import useLocalStorage from "hooks/use-local-storage";
import { SingleProgressStats } from "components/core";
// ui
import { Avatar } from "components/ui";
// icons
import User from "public/user.png";
// types
import { IIssue, IIssueLabels } from "types";
// fetch-keys
@ -125,9 +122,9 @@ export const ActiveCycleProgressStats: React.FC<Props> = ({ issues }) => {
<SingleProgressStats
title={
<div className="flex items-center gap-2">
<div className="h-5 w-5 rounded-full border-2 border-white bg-brand-surface-2">
<Image
src={User}
<div className="h-5 w-5 rounded-full border-2 border-brand-base bg-brand-surface-2">
<img
src="/user.png"
height="100%"
width="100%"
className="rounded-full"

View File

@ -1,7 +1,6 @@
import React, { useEffect, useState } from "react";
import { useRouter } from "next/router";
import Image from "next/image";
import useSWR, { mutate } from "swr";
@ -454,7 +453,7 @@ export const CycleDetailsSidebar: React.FC<Props> = ({
<div className="flex items-center gap-2.5">
{cycle.owned_by.avatar && cycle.owned_by.avatar !== "" ? (
<Image
<img
src={cycle.owned_by.avatar}
height={12}
width={12}

View File

@ -1,7 +1,6 @@
import React from "react";
import Link from "next/link";
import Image from "next/image";
import { useRouter } from "next/router";
// headless ui
@ -246,7 +245,7 @@ export const SingleCycleCard: React.FC<TSingleStatProps> = ({
<div className="w-16">Creator:</div>
<div className="flex items-center gap-2.5 text-brand-secondary">
{cycle.owned_by.avatar && cycle.owned_by.avatar !== "" ? (
<Image
<img
src={cycle.owned_by.avatar}
height={16}
width={16}

View File

@ -244,7 +244,7 @@ export const SingleCycleList: React.FC<TSingleStatProps> = ({
<div className="flex items-center gap-2.5 text-brand-secondary">
{cycle.owned_by.avatar && cycle.owned_by.avatar !== "" ? (
<Image
<img
src={cycle.owned_by.avatar}
height={16}
width={16}

View File

@ -1,4 +1,3 @@
import Image from "next/image";
import { useRouter } from "next/router";
import useSWR from "swr";
@ -66,11 +65,9 @@ export const SingleUserSelect: React.FC<Props> = ({ collaborator, index, users,
<div className="grid grid-cols-3 items-center gap-2 rounded-md bg-brand-surface-2 px-2 py-3">
<div className="flex items-center gap-2">
<div className="relative h-8 w-8 flex-shrink-0 rounded">
<Image
<img
src={collaborator.avatar_url}
layout="fill"
objectFit="cover"
className="rounded"
className="absolute top-0 left-0 h-full w-full object-cover rounded"
alt={`${collaborator.login} GitHub user`}
/>
</div>

View File

@ -1,6 +1,7 @@
import React from "react";
import { useRouter } from "next/router";
import Image from "next/image";
import useSWR from "swr";
// icons
@ -346,7 +347,7 @@ export const IssueActivitySection: React.FC<Props> = ({ user }) => {
?.icon
) : activityItem.actor_detail.avatar &&
activityItem.actor_detail.avatar !== "" ? (
<Image
<img
src={activityItem.actor_detail.avatar}
alt={activityItem.actor_detail.first_name}
height={24}

View File

@ -1,6 +1,5 @@
import React, { useEffect, useState } from "react";
import Image from "next/image";
import dynamic from "next/dynamic";
// react-hook-form
@ -68,12 +67,12 @@ export const CommentCard: React.FC<Props> = ({ comment, onSubmit, handleCommentD
<div className="relative flex items-start space-x-3">
<div className="relative px-1">
{comment.actor_detail.avatar && comment.actor_detail.avatar !== "" ? (
<Image
<img
src={comment.actor_detail.avatar}
alt={comment.actor_detail.first_name}
height={30}
width={30}
className="grid h-7 w-7 place-items-center rounded-full border-2 border-white bg-gray-500 text-white"
className="grid h-7 w-7 place-items-center rounded-full border-2 border-brand-base"
/>
) : (
<div

View File

@ -1,7 +1,5 @@
import { useState } from "react";
import Image from "next/image";
import useSWR from "swr";
// headless ui
@ -143,7 +141,7 @@ export const Workspace: React.FC<Props> = ({ setStep, setWorkspace, user }) => {
<div className="flex-shrink-0">
<span className="inline-flex h-10 w-10 items-center justify-center rounded-lg">
{invitation.workspace.logo && invitation.workspace.logo !== "" ? (
<Image
<img
src={invitation.workspace.logo}
height="100%"
width="100%"

View File

@ -1,6 +1,5 @@
import React, { useState, useEffect } from "react";
import Image from "next/image";
import { useRouter } from "next/router";
import useSWR, { mutate } from "swr";
@ -186,14 +185,12 @@ export const CreateProjectModal: React.FC<Props> = (props) => {
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
>
<Dialog.Panel className="transform rounded-lg bg-brand-surface-2 text-left shadow-xl transition-all sm:w-full sm:max-w-2xl">
<div className="relative h-36 w-full rounded-t-lg bg-gray-300">
<div className="relative h-36 w-full rounded-t-lg bg-brand-surface-2">
{watch("cover_image") !== null && (
<Image
<img
src={watch("cover_image")!}
layout="fill"
alt="cover image"
objectFit="cover"
className="rounded-t-lg"
className="absolute top-0 left-0 h-full w-full object-cover rounded-t-lg"
alt="Cover Image"
/>
)}

View File

@ -2,7 +2,6 @@ import React from "react";
import { useRouter } from "next/router";
import Link from "next/link";
import Image from "next/image";
import { mutate } from "swr";
@ -142,15 +141,13 @@ export const SingleProjectCard: React.FC<ProjectCardProps> = ({
<Link href={`/${workspaceSlug as string}/projects/${project.id}/issues`}>
<a>
<div className="relative h-32 w-full rounded-t-[10px]">
<Image
<img
src={
project.cover_image ??
"https://images.unsplash.com/photo-1672243775941-10d763d9adef?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=1170&q=80"
}
alt={project.name}
layout="fill"
objectFit="cover"
className="rounded-t-[10px]"
className="absolute top-0 left-0 h-full w-full object-cover rounded-t-[10px]"
/>
<div className="absolute left-7 bottom-4 flex items-center gap-3 text-white">
{!hasJoined ? (

View File

@ -1,6 +1,5 @@
import React, { useState } from "react";
import Image from "next/image";
import { useRouter } from "next/router";
import useSWR from "swr";
@ -62,12 +61,10 @@ const SearchListbox: React.FC<Props> = ({
if (user.member.avatar && user.member.avatar !== "") {
return (
<div className="relative h-4 w-4">
<Image
<img
src={user.member.avatar}
className="absolute top-0 left-0 h-full w-full object-cover rounded-full"
alt="avatar"
className="rounded-full"
layout="fill"
objectFit="cover"
/>
</div>
);
@ -151,7 +148,9 @@ const SearchListbox: React.FC<Props> = ({
</Combobox.Option>
))
) : (
<p className="text-xs text-brand-secondary px-2">No {title.toLowerCase()} found</p>
<p className="text-xs text-brand-secondary px-2">
No {title.toLowerCase()} found
</p>
)
) : (
<p className="text-xs text-brand-secondary px-2">Loading...</p>

View File

@ -44,11 +44,9 @@ export const Avatar: React.FC<AvatarProps> = ({
width: width,
}}
>
<Image
<img
src={user.avatar}
height="100%"
width="100%"
className="rounded-full"
className="absolute top-0 left-0 h-full w-full object-cover rounded-full"
alt={user.first_name}
/>
</div>

View File

@ -1,9 +1,10 @@
import { Fragment } from "react";
import { Menu, Transition } from "@headlessui/react";
import { useRouter } from "next/router";
import Image from "next/image";
import Link from "next/link";
import { CheckIcon, PlusIcon } from "@heroicons/react/24/outline";
// headless ui
import { Menu, Transition } from "@headlessui/react";
// hooks
import useUser from "hooks/use-user";
import useTheme from "hooks/use-theme";
@ -14,7 +15,9 @@ import userService from "services/user.service";
import authenticationService from "services/authentication.service";
// components
import { Avatar, Loader } from "components/ui";
// helper
// icons
import { CheckIcon, PlusIcon } from "@heroicons/react/24/outline";
// helpers
import { truncateText } from "helpers/string.helper";
// types
import { IWorkspace } from "types";
@ -94,12 +97,10 @@ export const WorkspaceSidebarDropdown = () => {
>
<div className="relative grid h-6 w-6 place-items-center rounded bg-gray-700 uppercase text-white dark:bg-brand-surface-2 dark:text-gray-800">
{activeWorkspace?.logo && activeWorkspace.logo !== "" ? (
<Image
<img
src={activeWorkspace.logo}
className="absolute top-0 left-0 h-full w-full object-cover rounded"
alt="Workspace Logo"
layout="fill"
objectFit="cover"
className="rounded"
/>
) : (
activeWorkspace?.name?.charAt(0) ?? "..."
@ -155,12 +156,10 @@ export const WorkspaceSidebarDropdown = () => {
<div className="flex items-center justify-start gap-2.5">
<span className="relative flex h-6 w-6 items-center justify-center rounded bg-gray-700 p-2 text-xs uppercase text-white">
{workspace?.logo && workspace.logo !== "" ? (
<Image
<img
src={workspace.logo}
className="absolute top-0 left-0 h-full w-full object-cover rounded"
alt="Workspace Logo"
layout="fill"
objectFit="cover"
className="rounded"
/>
) : (
workspace?.name?.charAt(0) ?? "..."

View File

@ -1,8 +1,5 @@
// next
// helpers
import { getFirstCharacters, truncateText } from "helpers/string.helper";
import Image from "next/image";
// react
import { useState } from "react";
// types
import { IWorkspaceMemberInvitation } from "types";
@ -16,65 +13,57 @@ const SingleInvitation: React.FC<Props> = ({
invitation,
invitationsRespond,
handleInvitation,
}) => {
const [isChecked, setIsChecked] = useState(invitationsRespond.includes(invitation.id));
return (
<>
<li>
<label
className={`group relative flex cursor-pointer items-start space-x-3 border-2 border-transparent py-4`}
htmlFor={invitation.id}
>
<div className="flex-shrink-0">
<span className="inline-flex h-10 w-10 items-center justify-center rounded-lg">
{invitation.workspace.logo && invitation.workspace.logo !== "" ? (
<Image
src={invitation.workspace.logo}
height="100%"
width="100%"
className="rounded"
alt={invitation.workspace.name}
/>
) : (
<span className="flex h-full w-full items-center justify-center rounded-xl bg-gray-700 p-4 uppercase text-white">
{getFirstCharacters(invitation.workspace.name)}
</span>
)}
}) => (
<li>
<label
className={`group relative flex cursor-pointer items-start space-x-3 border-2 border-transparent py-4`}
htmlFor={invitation.id}
>
<div className="flex-shrink-0">
<span className="inline-flex h-10 w-10 items-center justify-center rounded-lg">
{invitation.workspace.logo && invitation.workspace.logo !== "" ? (
<img
src={invitation.workspace.logo}
height="100%"
width="100%"
className="rounded"
alt={invitation.workspace.name}
/>
) : (
<span className="flex h-full w-full items-center justify-center rounded-xl bg-gray-700 p-4 uppercase text-white">
{getFirstCharacters(invitation.workspace.name)}
</span>
</div>
<div className="min-w-0 flex-1">
<div className="text-sm font-medium">{truncateText(invitation.workspace.name, 30)}</div>
<p className="text-sm text-brand-secondary">
Invited by{" "}
{invitation.created_by_detail
? invitation.created_by_detail.first_name
: invitation.workspace.owner.first_name}
</p>
</div>
<div className="flex-shrink-0 self-center">
<button
className={`${
invitationsRespond.includes(invitation.id)
? "bg-brand-surface-2 text-brand-secondary"
: "bg-brand-accent text-white"
} text-sm px-4 py-2 border border-brand-base rounded-3xl`}
onClick={(e) => {
handleInvitation(
invitation,
invitationsRespond.includes(invitation.id) ? "withdraw" : "accepted"
);
}}
>
{invitationsRespond.includes(invitation.id)
? "Invitation Accepted"
: "Accept Invitation"}
</button>
</div>
</label>
</li>
</>
);
};
)}
</span>
</div>
<div className="min-w-0 flex-1">
<div className="text-sm font-medium">{truncateText(invitation.workspace.name, 30)}</div>
<p className="text-sm text-brand-secondary">
Invited by{" "}
{invitation.created_by_detail
? invitation.created_by_detail.first_name
: invitation.workspace.owner.first_name}
</p>
</div>
<div className="flex-shrink-0 self-center">
<button
className={`${
invitationsRespond.includes(invitation.id)
? "bg-brand-surface-2 text-brand-secondary"
: "bg-brand-accent text-white"
} text-sm px-4 py-2 border border-brand-base rounded-3xl`}
onClick={(e) => {
handleInvitation(
invitation,
invitationsRespond.includes(invitation.id) ? "withdraw" : "accepted"
);
}}
>
{invitationsRespond.includes(invitation.id) ? "Invitation Accepted" : "Accept Invitation"}
</button>
</div>
</label>
</li>
);
export default SingleInvitation;

View File

@ -1,7 +1,5 @@
import React, { useEffect, useState } from "react";
import Image from "next/image";
// react-hook-form
import { Controller, useForm } from "react-hook-form";
// services
@ -168,14 +166,11 @@ const Profile: NextPage = () => {
</div>
) : (
<div className="relative h-12 w-12 overflow-hidden">
<Image
<img
src={watch("avatar")}
alt={myProfile.first_name}
layout="fill"
objectFit="cover"
className="rounded-md"
className="absolute top-0 left-0 h-full w-full object-cover rounded-md"
onClick={() => setIsImageUploadModalOpen(true)}
priority
alt={myProfile.first_name}
/>
</div>
)}

View File

@ -1,7 +1,6 @@
import React, { useEffect } from "react";
import { useRouter } from "next/router";
import Image from "next/image";
import useSWR, { mutate } from "swr";
@ -138,12 +137,10 @@ const ControlSettings: NextPage = () => {
<div className="flex items-center gap-2">
{person.member.avatar && person.member.avatar !== "" ? (
<div className="relative h-4 w-4">
<Image
<img
src={person.member.avatar}
alt="avatar"
className="rounded-full"
layout="fill"
objectFit="cover"
className="absolute top-0 left-0 h-full w-full object-cover rounded-full"
alt="User Avatar"
/>
</div>
) : (
@ -201,12 +198,10 @@ const ControlSettings: NextPage = () => {
<div className="flex items-center gap-2">
{person.member.avatar && person.member.avatar !== "" ? (
<div className="relative h-4 w-4">
<Image
<img
src={person.member.avatar}
alt="avatar"
className="rounded-full"
layout="fill"
objectFit="cover"
className="absolute top-0 left-0 h-full w-full object-cover rounded-full"
alt="User Avatar"
/>
</div>
) : (

View File

@ -1,6 +1,5 @@
import { useEffect, useState } from "react";
import Image from "next/image";
import { useRouter } from "next/router";
import useSWR, { mutate } from "swr";
@ -256,12 +255,10 @@ const GeneralSettings: NextPage = () => {
{watch("cover_image") ? (
<div className="h-32 w-full rounded border border-brand-base p-1">
<div className="relative h-full w-full rounded">
<Image
<img
src={watch("cover_image")!}
className="absolute top-0 left-0 h-full w-full object-cover rounded"
alt={projectDetails?.name ?? "Cover image"}
objectFit="cover"
layout="fill"
className="rounded"
/>
<div className="absolute bottom-0 flex w-full justify-end">
<ImagePickerPopover

View File

@ -1,6 +1,5 @@
import { useState } from "react";
import Image from "next/image";
import { useRouter } from "next/router";
import useSWR from "swr";
@ -177,12 +176,10 @@ const MembersSettings: NextPage = () => {
<div className="flex items-center gap-x-6 gap-y-2">
<div className="relative flex h-10 w-10 items-center justify-center rounded-lg bg-gray-700 p-4 capitalize text-white">
{member.avatar && member.avatar !== "" ? (
<Image
<img
src={member.avatar}
alt={member.first_name}
layout="fill"
objectFit="cover"
className="rounded-lg"
className="absolute top-0 left-0 h-full w-full object-cover rounded-lg"
/>
) : member.first_name !== "" ? (
member.first_name.charAt(0)

View File

@ -1,6 +1,5 @@
import React, { useEffect, useState } from "react";
import Image from "next/image";
import { useRouter } from "next/router";
import useSWR, { mutate } from "swr";
@ -190,13 +189,10 @@ const WorkspaceSettings: NextPage = () => {
<button type="button" onClick={() => setIsImageUploadModalOpen(true)}>
{watch("logo") && watch("logo") !== null && watch("logo") !== "" ? (
<div className="relative mx-auto flex h-12 w-12">
<Image
<img
src={watch("logo")!}
alt="Workspace Logo"
objectFit="cover"
layout="fill"
className="rounded-md"
priority
className="absolute top-0 left-0 h-full w-full object-cover rounded-md"
/>
</div>
) : (

View File

@ -177,12 +177,10 @@ const MembersSettings: NextPage = () => {
<div className="flex items-center gap-x-8 gap-y-2">
<div className="relative flex h-10 w-10 items-center justify-center rounded-lg bg-gray-700 p-4 capitalize text-white">
{member.avatar && member.avatar !== "" ? (
<Image
<img
src={member.avatar}
className="absolute top-0 left-0 h-full w-full object-cover rounded-lg"
alt={member.first_name}
layout="fill"
objectFit="cover"
className="rounded-lg"
/>
) : member.first_name !== "" ? (
member.first_name.charAt(0)