refactor(logo): Update main logo SVG to use currentColor

The main logo SVG has been replaced with an updated version.

The previous logo had hardcoded fill colors, making it difficult to adapt to different color schemes, such as light and dark modes.

The new SVG uses `fill="currentColor"`, which allows its color to be controlled via the parent element's CSS `color` property. This makes the logo easily themeable and more flexible for use throughout the application.
This commit is contained in:
AmirReza Jamali
2025-09-16 18:31:33 +03:30
parent 2fa774b6bd
commit 4fb1a931c5
17 changed files with 138 additions and 202 deletions
@@ -63,7 +63,7 @@ const InputGroup = <T extends FieldValues>({
className="text-body-sm font-medium text-dark dark:text-white"
>
{label}
{required && <span className="text-red ml-1 select-none">*</span>}
{required && <span className="ml-1 select-none text-error">*</span>}
</label>
<div
+1 -1
View File
@@ -55,7 +55,7 @@ export function Select<T extends FieldValues>({
className="block text-body-sm font-medium text-dark dark:text-white"
>
{label}
{required && <span className="text-red ml-1 select-none">*</span>}
{required && <span className="ml-1 select-none text-error">*</span>}
</label>
<div className="relative">
+1 -1
View File
@@ -40,7 +40,7 @@ const CompaniesTable = ({}: IProps) => {
{columns.map((columns) => (
<TableHead
colSpan={100}
className="text-start font-extrabold"
className="text-start font-extrabold uppercase"
key={columns}
>
{columns}
@@ -32,7 +32,7 @@ export const useCompanyListPresenter = () => {
"country",
"state",
"city",
"postal_code",
"postal code",
"language",
"currency",
"employee count",
+4 -1
View File
@@ -17,6 +17,7 @@ import AssignToCompanyModalContent from "./AssignToCompanyModalContent";
import Modal from "@/components/ui/modal";
import { TAssignCustomerToCompanyCredentials } from "@/lib/api";
import { toast } from "react-toastify";
import Status from "@/components/ui/Status";
const CustomersTable = () => {
const {
isPending,
@@ -63,7 +64,9 @@ const CustomersTable = () => {
<TableCell colSpan={100}>{customer.email}</TableCell>
<TableCell colSpan={100}>{customer.created_at}</TableCell>
<TableCell colSpan={100}>{customer.type}</TableCell>
<TableCell colSpan={100}>{customer.status}</TableCell>
<TableCell colSpan={100}>
<Status status={customer.status}>{customer.status}</Status>
</TableCell>
<TableCell colSpan={100}>
{customer.companies?.length ? (
customer.companies.map((c) => (
+15 -28
View File
@@ -10,33 +10,20 @@ import {
export function TendersSkeleton() {
return (
<div className="rounded-[10px] bg-white px-7.5 pb-4 pt-7.5 shadow-1 dark:bg-gray-dark dark:shadow-card">
<h2 className="mb-5.5 text-body-2xlg font-bold text-dark dark:text-white">
Tenders
</h2>
<Table>
<TableHeader>
<TableRow className="border-none uppercase [&>th]:text-center">
<TableHead>Full name</TableHead>
<TableHead>Email</TableHead>
<TableHead>Type</TableHead>
<TableHead>Status</TableHead>
<TableHead>Company</TableHead>
<TableHead>Actions</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{Array.from({ length: 5 }).map((_, i) => (
<TableRow key={i}>
<TableCell colSpan={100}>
<Skeleton className="h-8" />
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
<TableBody>
{Array.from({ length: 5 }).map((_, i) => (
<TableRow key={i}>
<TableCell colSpan={100}>
<Skeleton className="h-8" />
</TableCell>
<TableCell colSpan={100}>
<Skeleton className="h-8" />
</TableCell>
<TableCell colSpan={100}>
<Skeleton className="h-8" />
</TableCell>
</TableRow>
))}
</TableBody>
);
}
+10 -10
View File
@@ -1,7 +1,7 @@
"use client";
import useTenderListPresenter from "./useTenderListPresenter";
import Status from "@/components/ui/Status";
import {
Table,
TableBody,
@@ -30,6 +30,9 @@ const TendersTable = () => {
<Table>
<TableHeader>
<TableRow className="border-none uppercase [&>th]:text-start">
<TableHead colSpan={100} className="text-start font-extrabold">
Row
</TableHead>
<TableHead colSpan={100} className="text-start font-extrabold">
Title
</TableHead>
@@ -42,6 +45,7 @@ const TendersTable = () => {
</TableRow>
</TableHeader>
{isPending && <TendersSkeleton />}
<TableBody>
{allTenders.map((item, index) =>
!item ? (
@@ -52,6 +56,9 @@ const TendersTable = () => {
key={item.id}
className="odd:bg-gray-2 dark:odd:bg-gray-7"
>
<TableCell className="text-start" colSpan={100}>
{index + 1}
</TableCell>
<TableCell className="text-start" colSpan={100}>
{item.title}
</TableCell>
@@ -59,21 +66,14 @@ const TendersTable = () => {
{item.country_code}
</TableCell>
<TableCell className={cn(`text capitalize`)} colSpan={100}>
<span
className={cn(
"rounded-2xl p-2",
getStatusColor(item.status),
)}
>
{item.status}
</span>
<Status status={item.status}>{item.status}</Status>
</TableCell>
</TableRow>
),
)}
</TableBody>
{isFetchingNextPage && <TendersSkeleton />}
</Table>
{isFetchingNextPage && <TendersSkeleton />}
{(data?.pages.length ?? 0) >= 5 && hasNextPage && (
<button
onClick={() => fetchNextPage()}
+5 -1
View File
@@ -45,6 +45,7 @@ const CreateAdminForm: FC<IProps> = ({ defaultValues, editMode, id }) => {
})}
label="Full name"
placeholder="Full name"
required
type="text"
name="full_name"
/>
@@ -60,6 +61,7 @@ const CreateAdminForm: FC<IProps> = ({ defaultValues, editMode, id }) => {
label="Username"
placeholder="Username"
autoComplete="off"
required
type="text"
{...register("username", {
required: {
@@ -94,6 +96,7 @@ const CreateAdminForm: FC<IProps> = ({ defaultValues, editMode, id }) => {
autoComplete="off"
placeholder="Email"
type="email"
required
{...register("email", {
required: {
value: true,
@@ -117,7 +120,8 @@ const CreateAdminForm: FC<IProps> = ({ defaultValues, editMode, id }) => {
<InputGroup
label="Password"
placeholder="Password"
autoComplete="off"
autoComplete="new-password"
required
type="password"
{...register("password", {
required: {
+20 -135
View File
@@ -9,6 +9,7 @@ import { Select } from "@/components/FormElements/select";
import { CurrencyIcon, GlobeIcon, MoneyIcon } from "@/assets/icons";
import MultiSelect from "@/components/FormElements/MultiSelect";
import { TextAreaGroup } from "@/components/FormElements/InputGroup/text-area";
import { PHONE_REGEX } from "@/constants/regex";
interface IProps {
editMode?: boolean;
@@ -34,7 +35,7 @@ const CreateCompany = ({ defaultValues, editMode, id }: IProps) => {
});
return (
<form
className="grid grid-cols-1 items-start gap-9 rounded-xl bg-gray-1 p-10 sm:grid-cols-2"
className="grid grid-cols-1 items-start gap-9 rounded-xl bg-gray-1 p-10 dark:bg-gray-7 sm:grid-cols-2"
onSubmit={handleSubmit(onSubmit)}
>
<div className="flex flex-col gap-9">
@@ -56,6 +57,7 @@ const CreateCompany = ({ defaultValues, editMode, id }: IProps) => {
})}
label="Name"
name="name"
required
type="text"
placeholder="Enter Company Name"
/>
@@ -72,6 +74,7 @@ const CreateCompany = ({ defaultValues, editMode, id }: IProps) => {
})}
label="Email"
name="email"
required
type="email"
placeholder="Enter Company Email"
/>
@@ -89,9 +92,14 @@ const CreateCompany = ({ defaultValues, editMode, id }: IProps) => {
value: 20,
message: FormErrorMessages.maxLength(20),
},
pattern: {
value: PHONE_REGEX,
message: FormErrorMessages.invalidPattern,
},
})}
label="Phone"
name="phone"
required
type="tel"
placeholder="Enter Company Phone"
/>
@@ -104,6 +112,7 @@ const CreateCompany = ({ defaultValues, editMode, id }: IProps) => {
})}
name="type"
label="Company type"
required
items={[
{ value: "private", label: "Private" },
{ value: "public", label: "Public" },
@@ -129,6 +138,7 @@ const CreateCompany = ({ defaultValues, editMode, id }: IProps) => {
label="Registration Number"
name="registration_number"
type="text"
required
placeholder="Enter Registration Number"
/>
{errors.registration_number && (
@@ -148,6 +158,7 @@ const CreateCompany = ({ defaultValues, editMode, id }: IProps) => {
label="Tax id"
name="tax_id"
type="text"
required
placeholder="Enter Tax id"
/>
{errors.tax_id && (
@@ -165,6 +176,7 @@ const CreateCompany = ({ defaultValues, editMode, id }: IProps) => {
label="Industry"
name="industry"
type="text"
required
placeholder="Enter Industry"
/>
{errors.industry && (
@@ -202,6 +214,7 @@ const CreateCompany = ({ defaultValues, editMode, id }: IProps) => {
},
})}
label="Website"
required
name="website"
type="url"
placeholder="Enter Company Website"
@@ -212,116 +225,7 @@ const CreateCompany = ({ defaultValues, editMode, id }: IProps) => {
</p>
)}
</ShowcaseSection>
<ShowcaseSection
title="Contact Person"
className="grid grid-cols-1 gap-5"
>
<InputGroup
{...register("contact_person.full_name", {
required: { value: true, message: FormErrorMessages.required },
minLength: {
value: 2,
message: FormErrorMessages.minLength(2),
},
maxLength: {
value: 100,
message: FormErrorMessages.maxLength(100),
},
})}
label="Full name"
name="contact_person.full_name"
placeholder="Enter Full name"
type="text"
/>
{errors.contact_person?.full_name && (
<p className="mt-1 text-sm text-red-500">
{errors.contact_person.full_name.message}
</p>
)}
<InputGroup
{...register("contact_person.position", {
required: { value: true, message: FormErrorMessages.required },
minLength: {
value: 2,
message: FormErrorMessages.minLength(2),
},
maxLength: {
value: 100,
message: FormErrorMessages.maxLength(100),
},
})}
label="Position"
name="contact_person.position"
placeholder="Enter Content Person Position"
type="text"
/>
{errors.contact_person?.position && (
<p className="mt-1 text-sm text-red-500">
{errors.contact_person.position.message}
</p>
)}
<InputGroup
{...register("contact_person.email", {
required: { value: true, message: FormErrorMessages.required },
pattern: {
value: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
message: FormErrorMessages.invalidEmail,
},
})}
label="Email"
name="contact_person.email"
placeholder="Enter Contact Person Email"
type="email"
/>
{errors.contact_person?.email && (
<p className="mt-1 text-sm text-red-500">
{errors.contact_person.email.message}
</p>
)}
<InputGroup
{...register("contact_person.phone", {
required: { value: true, message: FormErrorMessages.required },
minLength: {
value: 10,
message: FormErrorMessages.minLength(10),
},
maxLength: {
value: 20,
message: FormErrorMessages.maxLength(20),
},
})}
label="Phone"
name="contact_person.phone"
placeholder="Enter Contact Person Phone"
type="tel"
/>
{errors.contact_person?.phone && (
<p className="mt-1 text-sm text-red-500">
{errors.contact_person.phone.message}
</p>
)}
<InputGroup
{...register("contact_person.mobile", {
minLength: {
value: 10,
message: FormErrorMessages.minLength(10),
},
maxLength: {
value: 20,
message: FormErrorMessages.maxLength(20),
},
})}
label="Mobile"
name="contact_person.mobile"
placeholder="Enter Contact Person Mobile"
type="tel"
/>
{errors.contact_person?.mobile && (
<p className="mt-1 text-sm text-red-500">
{errors.contact_person.mobile.message}
</p>
)}
</ShowcaseSection>
<ShowcaseSection title="Settings" className="grid grid-cols-1 gap-5">
<Select
{...register("language")}
@@ -461,6 +365,7 @@ const CreateCompany = ({ defaultValues, editMode, id }: IProps) => {
})}
label="Street"
name="address.street"
required
type="text"
placeholder="Enter Street"
/>
@@ -482,6 +387,7 @@ const CreateCompany = ({ defaultValues, editMode, id }: IProps) => {
},
})}
label="City"
required
name="address.city"
type="text"
placeholder="Enter City"
@@ -506,6 +412,7 @@ const CreateCompany = ({ defaultValues, editMode, id }: IProps) => {
label="State"
name="address.state"
type="text"
required
placeholder="Enter State"
/>
{errors.address?.state && (
@@ -528,6 +435,7 @@ const CreateCompany = ({ defaultValues, editMode, id }: IProps) => {
label="Postal code"
name="address.postal_code"
type="text"
required
placeholder="Enter Postal code"
/>
{errors.address?.postal_code && (
@@ -550,6 +458,7 @@ const CreateCompany = ({ defaultValues, editMode, id }: IProps) => {
label="Country"
name="address.country"
type="text"
required
placeholder="Enter Country"
/>
{errors.address?.country && (
@@ -595,30 +504,6 @@ const CreateCompany = ({ defaultValues, editMode, id }: IProps) => {
{errors.tags.specializations.message}
</p>
)}
<InputGroup
{...register("tags.certifications")}
label="Certifications"
name="tags.certifications"
type="text"
placeholder="Enter Tag Certifications"
/>
{errors.tags?.certifications && (
<p className="mt-1 text-sm text-red-500">
{errors.tags.certifications.message}
</p>
)}
<InputGroup
{...register("tags.cpv_codes")}
label="CPV Code"
name="tags.cpv_codes"
type="text"
placeholder="Enter Tag CPV Code"
/>
{errors.tags?.cpv_codes && (
<p className="mt-1 text-sm text-red-500">
{errors.tags.cpv_codes.message}
</p>
)}
</ShowcaseSection>
</div>
+1 -2
View File
@@ -6,10 +6,9 @@ export function Logo() {
src="/images/main-logo.svg"
width={174}
height={32}
alt="NextAdmin logo"
alt="Opp lens logo"
role="presentation"
quality={100}
className="dark:invert"
/>
);
}
+51
View File
@@ -0,0 +1,51 @@
import { cn } from "@/lib/utils";
import { ReactNode } from "react";
interface IProps {
status: string;
children: ReactNode;
}
const Status = ({ status, children }: IProps) => {
const reds = [
"cancelled",
"inactive",
"rejected",
"failed",
"denied",
"blocked",
];
const greens = [
"active",
"approved",
"completed",
"success",
"verified",
"published",
];
const blues = ["awarded", "processing", "in-review", "scheduled"];
const yellows = ["pending", "warning", "on-hold", "delayed"];
const oranges = ["expired", "expiring", "limited"];
const grays = ["draft", "disabled", "archived", "paused"];
return (
<span
className={cn("rounded-2xl px-3 py-1.5 text-sm font-medium capitalize", {
"bg-green text-white": greens.includes(status),
"bg-orange-light text-white": oranges.includes(status),
"bg-error text-white": reds.includes(status),
"bg-blue text-white": blues.includes(status),
"bg-gray-3 text-gray-7": grays.includes(status),
"bg-yellow-light text-yellow-dark-2": yellows.includes(status),
"bg-green-light-6 text-green-dark": status === "new",
"bg-blue-light-5 text-blue-dark": status === "info",
"bg-error-light-6 text-error-dark": status === "urgent",
"bg-primary text-white": status === "featured",
})}
>
{children}
</span>
);
};
export default Status;