diff --git a/src/components/Activity/EmptyActivity.tsx b/src/components/Activity/EmptyActivity.tsx index 8dcf5b4a6..f984100e1 100644 --- a/src/components/Activity/EmptyActivity.tsx +++ b/src/components/Activity/EmptyActivity.tsx @@ -1,14 +1,11 @@ -import RoadmapIcon from '../../icons/roadmap.svg'; +import { RoadmapIcon } from "../ReactIcons/RoadmapIcon"; export function EmptyActivity() { return (
- no roadmaps + +

No Progress

Progress will appear here as you start tracking your{' '} diff --git a/src/components/CreateTeam/NotDropdown.tsx b/src/components/CreateTeam/NotDropdown.tsx index d0e2e7761..66259d567 100644 --- a/src/components/CreateTeam/NotDropdown.tsx +++ b/src/components/CreateTeam/NotDropdown.tsx @@ -1,4 +1,4 @@ -import ChevronDownIcon from '../../icons/chevron-down.svg'; +import { ChevronDownIcon } from '../ReactIcons/ChevronDownIcon'; type NotDropdownProps = { onClick: () => void; @@ -37,11 +37,7 @@ export function NotDropdown(props: NotDropdownProps) {

)} - {singularName} +
); } diff --git a/src/components/CustomRoadmap/PersonalRoadmapList.tsx b/src/components/CustomRoadmap/PersonalRoadmapList.tsx index a9a25f88b..7e863abbb 100644 --- a/src/components/CustomRoadmap/PersonalRoadmapList.tsx +++ b/src/components/CustomRoadmap/PersonalRoadmapList.tsx @@ -14,11 +14,11 @@ import { type AllowedRoadmapVisibility, type RoadmapDocument, } from './CreateRoadmap/CreateRoadmapModal'; -import RoadmapIcon from '../../icons/roadmap.svg'; import { PersonalRoadmapActionDropdown } from './PersonalRoadmapActionDropdown'; import type { GetRoadmapListResponse } from './RoadmapListPage'; import { useState, type Dispatch, type SetStateAction } from 'react'; import { ShareOptionsModal } from '../ShareOptions/ShareOptionsModal'; +import {RoadmapIcon} from "../ReactIcons/RoadmapIcon.tsx"; type PersonalRoadmapListType = { roadmaps: GetRoadmapListResponse['personalRoadmaps']; @@ -91,11 +91,8 @@ export function PersonalRoadmapList(props: PersonalRoadmapListType) { if (roadmapList.length === 0) { return (
- roadmap + +

No roadmaps

Create a roadmap to get started diff --git a/src/components/Friends/EmptyFriends.tsx b/src/components/Friends/EmptyFriends.tsx index ac5741dec..740ba1904 100644 --- a/src/components/Friends/EmptyFriends.tsx +++ b/src/components/Friends/EmptyFriends.tsx @@ -1,6 +1,5 @@ -import UserPlusIcon from '../../icons/user-plus.svg'; -import CopyIcon from '../../icons/copy.svg'; import { useCopyText } from '../../hooks/use-copy-text'; +import { CopyIcon, UserPlus2 } from 'lucide-react'; type EmptyFriendsProps = { befriendUrl: string; @@ -13,14 +12,12 @@ export function EmptyFriends(props: EmptyFriendsProps) { return (

- no friends + +

Invite your Friends

- Share the unique link below with your friends to track their skills and progress. + Share the unique link below with your friends to track their skills + and progress.

@@ -44,7 +41,8 @@ export function EmptyFriends(props: EmptyFriendsProps) { copyText(befriendUrl); }} > - Invite Friends + + {isCopied ? 'Copied' : 'Copy'}
diff --git a/src/components/Friends/FriendsPage.tsx b/src/components/Friends/FriendsPage.tsx index 3c3c353e3..0c8a50b95 100644 --- a/src/components/Friends/FriendsPage.tsx +++ b/src/components/Friends/FriendsPage.tsx @@ -7,10 +7,10 @@ import type { FriendshipStatus } from '../Befriend'; import { useToast } from '../../hooks/use-toast'; import { EmptyFriends } from './EmptyFriends'; import { FriendProgressItem } from './FriendProgressItem'; -import UserIcon from '../../icons/user.svg'; import { UserProgressModal } from '../UserProgress/UserProgressModal'; import { InviteFriendPopup } from './InviteFriendPopup'; import { UserCustomProgressModal } from '../UserProgress/UserCustomProgressModal'; +import { UserIcon } from '../ReactIcons/UserIcon.tsx'; type FriendResourceProgress = { updatedAt: string; @@ -64,7 +64,7 @@ export function FriendsPage() { async function loadFriends() { const { response, error } = await httpGet( - `${import.meta.env.PUBLIC_API_URL}/v1-list-friends` + `${import.meta.env.PUBLIC_API_URL}/v1-list-friends`, ); if (error || !response) { @@ -89,15 +89,15 @@ export function FriendsPage() { const befriendUrl = `${baseUrl}/befriend?u=${user?.id}`; const selectedGroupingType = groupingTypes.find( - (grouping) => grouping.value === selectedGrouping + (grouping) => grouping.value === selectedGrouping, ); - const filteredFriends = friends.filter((friend) => - selectedGroupingType?.statuses.includes(friend.status) + const filteredFriends = friends.filter( + (friend) => selectedGroupingType?.statuses.includes(friend.status), ); const receivedRequests = friends.filter( - (friend) => friend.status === 'received' + (friend) => friend.status === 'received', ); if (isLoading) { @@ -203,11 +203,8 @@ export function FriendsPage() { {filteredFriends.length === 0 && (
- Empty Friends + +

{selectedGrouping === 'active' && 'No friends yet'} {selectedGrouping === 'sent' && 'No requests sent'} diff --git a/src/components/Friends/InviteFriendPopup.tsx b/src/components/Friends/InviteFriendPopup.tsx index 3a0a2d9f4..2121a3ff8 100644 --- a/src/components/Friends/InviteFriendPopup.tsx +++ b/src/components/Friends/InviteFriendPopup.tsx @@ -1,8 +1,8 @@ import type { MouseEvent } from 'react'; import { useRef } from 'react'; import { useOutsideClick } from '../../hooks/use-outside-click'; -import CopyIcon from '../../icons/copy.svg'; import { useCopyText } from '../../hooks/use-copy-text'; +import { CopyIcon } from 'lucide-react'; type InviteFriendPopupProps = { befriendUrl: string; @@ -54,11 +54,7 @@ export function InviteFriendPopup(props: InviteFriendPopupProps) { copyText(befriendUrl); }} > - Invite Friends + {isCopied ? 'Copied' : 'Copy URL'}

diff --git a/src/components/Notification/NotificationPage.tsx b/src/components/Notification/NotificationPage.tsx index 754f04662..3c964d4c6 100644 --- a/src/components/Notification/NotificationPage.tsx +++ b/src/components/Notification/NotificationPage.tsx @@ -1,10 +1,10 @@ import { useEffect, useState } from 'react'; -import { httpGet, httpPatch, httpPost } from '../../lib/http'; +import { httpGet, httpPatch } from '../../lib/http'; import { pageProgressMessage } from '../../stores/page'; import type { TeamMemberDocument } from '../TeamMembers/TeamMembersPage'; -import XIcon from '../../icons/close-dark.svg'; -import AcceptIcon from '../../icons/accept.svg'; import { useToast } from '../../hooks/use-toast'; +import { AcceptIcon } from '../ReactIcons/AcceptIcon.tsx'; +import { XIcon } from 'lucide-react'; interface NotificationList extends TeamMemberDocument { name: string; @@ -18,7 +18,7 @@ export function NotificationPage() { const lostNotifications = async () => { const { error, response } = await httpGet( - `${import.meta.env.PUBLIC_API_URL}/v1-get-invitation-list` + `${import.meta.env.PUBLIC_API_URL}/v1-get-invitation-list`, ); if (error || !response) { toast.error(error?.message || 'Something went wrong'); @@ -28,28 +28,37 @@ export function NotificationPage() { setNotifications(response); }; - async function respondInvitation(status: 'accept' | 'reject', inviteId: string) { + async function respondInvitation( + status: 'accept' | 'reject', + inviteId: string, + ) { setIsLoading(true); setError(''); const { response, error } = await httpPatch<{ teamId: string }>( - `${import.meta.env.PUBLIC_API_URL}/v1-respond-invite/${inviteId}`, { - status - }); + `${import.meta.env.PUBLIC_API_URL}/v1-respond-invite/${inviteId}`, + { + status, + }, + ); if (error || !response) { - setError(error?.message || 'Something went wrong') - setIsLoading(false) + setError(error?.message || 'Something went wrong'); + setIsLoading(false); return; } if (status === 'accept') { window.location.href = `/team/progress?t=${response.teamId}`; } else { - window.dispatchEvent(new CustomEvent('refresh-notification', { - detail: { - count: notifications.length - 1 - } - })); - setNotifications(notifications.filter((notification) => notification._id !== inviteId)); + window.dispatchEvent( + new CustomEvent('refresh-notification', { + detail: { + count: notifications.length - 1, + }, + }), + ); + setNotifications( + notifications.filter((notification) => notification._id !== inviteId), + ); setIsLoading(false); } } @@ -66,15 +75,20 @@ export function NotificationPage() {

Notification

Manage your notifications

- { - notifications.length === 0 && ( -
-

- No notifications, you can create a team and invite your friends to join. -

-
- ) - } + {notifications.length === 0 && ( +
+

+ No notifications, you can{' '} + + create a team + {' '} + and invite your friends to join. +

+
+ )}
{notifications.map((notification) => (
@@ -86,19 +100,21 @@ export function NotificationPage() {
- -
diff --git a/src/components/ReactIcons/AcceptIcon.tsx b/src/components/ReactIcons/AcceptIcon.tsx new file mode 100644 index 000000000..f26c231e9 --- /dev/null +++ b/src/components/ReactIcons/AcceptIcon.tsx @@ -0,0 +1,24 @@ +type AcceptIconProps = { + className?: string; +}; + +export function AcceptIcon(props: AcceptIconProps) { + const { className } = props; + + return ( + + + + ); +} diff --git a/src/components/RespondInviteForm.tsx b/src/components/RespondInviteForm.tsx index 1443a1701..909182682 100644 --- a/src/components/RespondInviteForm.tsx +++ b/src/components/RespondInviteForm.tsx @@ -1,7 +1,5 @@ import { useEffect, useState } from 'react'; import { httpGet, httpPatch } from '../lib/http'; -import BuildingIcon from '../icons/building.svg'; -import ErrorIcon from '../icons/error.svg'; import { pageProgressMessage } from '../stores/page'; import type { TeamDocument } from './CreateTeam/CreateTeamForm'; import type { AllowedRoles } from './CreateTeam/RoleDropdown'; @@ -9,6 +7,8 @@ import type { AllowedMemberStatus } from './TeamDropdown/TeamDropdown'; import { isLoggedIn } from '../lib/jwt'; import { showLoginPopup } from '../lib/popup'; import { getUrlParams } from '../lib/browser'; +import { ErrorIcon2 } from './ReactIcons/ErrorIcon2'; +import { BuildingIcon } from './ReactIcons/BuildingIcon'; type InvitationResponse = { team: TeamDocument; @@ -85,11 +85,7 @@ export function RespondInviteForm() { if (!invite) { return (
- {'error'} +

Error

@@ -110,11 +106,7 @@ export function RespondInviteForm() { return (

- {'join +

Join Team

diff --git a/src/components/TeamProgress/GroupRoadmapItem.tsx b/src/components/TeamProgress/GroupRoadmapItem.tsx index ba7842a6d..7a21d074c 100644 --- a/src/components/TeamProgress/GroupRoadmapItem.tsx +++ b/src/components/TeamProgress/GroupRoadmapItem.tsx @@ -1,8 +1,8 @@ import { useState } from 'react'; import type { GroupByRoadmap, TeamMember } from './TeamProgressPage'; import { getUrlParams } from '../../lib/browser'; -import ExternalLinkIcon from '../../icons/external-link.svg'; import { useAuth } from '../../hooks/use-auth'; +import { LucideExternalLink } from 'lucide-react'; type GroupRoadmapItemProps = { roadmap: GroupByRoadmap; @@ -33,11 +33,7 @@ export function GroupRoadmapItem(props: GroupRoadmapItemProps) { className="group mb-0.5 flex shrink-0 items-center justify-between text-base font-medium leading-none text-black" target={'_blank'} > - {'link'} +

@@ -58,7 +54,7 @@ export function GroupRoadmapItem(props: GroupRoadmapItemProps) { onClick={() => { onShowResourceProgress( member.member, - member.progress?.resourceId! + member.progress?.resourceId!, ); }} > diff --git a/src/components/TeamProgress/MemberCustomProgressModal.tsx b/src/components/TeamProgress/MemberCustomProgressModal.tsx index e6bcf93ff..32eae1d80 100644 --- a/src/components/TeamProgress/MemberCustomProgressModal.tsx +++ b/src/components/TeamProgress/MemberCustomProgressModal.tsx @@ -25,6 +25,7 @@ import type { Node } from 'reactflow'; import { useKeydown } from '../../hooks/use-keydown'; import { useOutsideClick } from '../../hooks/use-outside-click'; import { MemberProgressModalHeader } from './MemberProgressModalHeader'; +import { X } from 'lucide-react'; export type ProgressMapProps = { member: TeamMember; @@ -284,7 +285,7 @@ export function MemberCustomProgressModal(props: ProgressMapProps) { }`} onClick={onClose} > - {'close'} + Close modal
diff --git a/src/components/TeamProgress/MemberProgressModal.tsx b/src/components/TeamProgress/MemberProgressModal.tsx index 70d12efa2..81c2942d7 100644 --- a/src/components/TeamProgress/MemberProgressModal.tsx +++ b/src/components/TeamProgress/MemberProgressModal.tsx @@ -12,12 +12,12 @@ import { type ResourceType, updateResourceProgress, } from '../../lib/resource-progress'; -import CloseIcon from '../../icons/close.svg'; import { useToast } from '../../hooks/use-toast'; import { useAuth } from '../../hooks/use-auth'; import { pageProgressMessage } from '../../stores/page'; import { MemberProgressModalHeader } from './MemberProgressModalHeader'; -import {replaceChildren} from "../../lib/dom.ts"; +import { replaceChildren } from '../../lib/dom.ts'; +import { XIcon } from 'lucide-react'; export type ProgressMapProps = { member: TeamMember; @@ -68,12 +68,12 @@ export function MemberProgressModal(props: ProgressMapProps) { teamId: string, memberId: string, resourceType: string, - resourceId: string + resourceId: string, ) { const { error, response } = await httpGet( `${ import.meta.env.PUBLIC_API_URL - }/v1-get-member-resource-progress/${teamId}/${memberId}?resourceType=${resourceType}&resourceId=${resourceId}` + }/v1-get-member-resource-progress/${teamId}/${memberId}?resourceType=${resourceType}&resourceId=${resourceId}`, ); if (error || !response) { toast.error(error?.message || 'Failed to get member progress'); @@ -160,14 +160,14 @@ export function MemberProgressModal(props: ProgressMapProps) { resourceType: resourceType as ResourceType, topicId, }, - newStatus + newStatus, ) .then(() => { renderTopicProgress(topicId, newStatus); getMemberProgress(teamId, member._id, resourceType, resourceId).then( (data) => { setMemberProgress(data); - } + }, ); }) .catch((err) => { @@ -227,7 +227,7 @@ export function MemberProgressModal(props: ProgressMapProps) { e.preventDefault(); updateTopicStatus( topicId, - !isCurrentStatusLearning ? 'learning' : 'pending' + !isCurrentStatusLearning ? 'learning' : 'pending', ); return; } @@ -236,7 +236,7 @@ export function MemberProgressModal(props: ProgressMapProps) { e.preventDefault(); updateTopicStatus( topicId, - !isCurrentStatusSkipped ? 'skipped' : 'pending' + !isCurrentStatusSkipped ? 'skipped' : 'pending', ); return; @@ -298,7 +298,8 @@ export function MemberProgressModal(props: ProgressMapProps) { }`} onClick={onClose} > - {'close'} + + Close modal diff --git a/src/components/TeamRoadmapsList/TeamRoadmaps.tsx b/src/components/TeamRoadmapsList/TeamRoadmaps.tsx index c96fd55b3..dd29e8870 100644 --- a/src/components/TeamRoadmapsList/TeamRoadmaps.tsx +++ b/src/components/TeamRoadmapsList/TeamRoadmaps.tsx @@ -4,7 +4,6 @@ import type { TeamDocument } from '../CreateTeam/CreateTeamForm'; import type { TeamResourceConfig } from '../CreateTeam/RoadmapSelector'; import { httpGet, httpPut } from '../../lib/http'; import { pageProgressMessage } from '../../stores/page'; -import RoadmapIcon from '../../icons/roadmap.svg'; import type { PageType } from '../CommandMenu/CommandMenu'; import { useStore } from '@nanostores/react'; import { $canManageCurrentTeam } from '../../stores/team'; @@ -28,6 +27,7 @@ import { RoadmapActionDropdown } from './RoadmapActionDropdown'; import { UpdateTeamResourceModal } from '../CreateTeam/UpdateTeamResourceModal'; import { ShareOptionsModal } from '../ShareOptions/ShareOptionsModal'; import { cn } from '../../lib/classname'; +import { RoadmapIcon } from '../ReactIcons/RoadmapIcon.tsx'; export function TeamRoadmaps() { const { t: teamId } = getUrlParams(); @@ -73,7 +73,7 @@ export function TeamRoadmaps() { async function loadTeam(teamIdToFetch: string) { const { response, error } = await httpGet( - `${import.meta.env.PUBLIC_API_URL}/v1-get-team/${teamIdToFetch}` + `${import.meta.env.PUBLIC_API_URL}/v1-get-team/${teamIdToFetch}`, ); if (error || !response) { @@ -87,7 +87,7 @@ export function TeamRoadmaps() { async function loadTeamResourceConfig(teamId: string) { const { error, response } = await httpGet( - `${import.meta.env.PUBLIC_API_URL}/v1-get-team-resource-config/${teamId}` + `${import.meta.env.PUBLIC_API_URL}/v1-get-team-resource-config/${teamId}`, ); if (error || !Array.isArray(response)) { console.error(error); @@ -127,7 +127,7 @@ export function TeamRoadmaps() { { resourceId: roadmapId, resourceType: 'roadmap', - } + }, ); if (error || !response) { @@ -156,7 +156,7 @@ export function TeamRoadmaps() { resourceId: roadmapId, resourceType: 'roadmap', removed: [], - } + }, ); if (error || !response) { @@ -190,13 +190,13 @@ export function TeamRoadmaps() { } window.addEventListener( 'custom-roadmap-created', - handleCustomRoadmapCreated + handleCustomRoadmapCreated, ); return () => { window.removeEventListener( 'custom-roadmap-created', - handleCustomRoadmapCreated + handleCustomRoadmapCreated, ); }; }, []); @@ -252,13 +252,13 @@ export function TeamRoadmaps() { ); const placeholderRoadmaps = teamResources.filter( - (c: TeamResourceConfig[0]) => c.isCustomResource && !c.topics + (c: TeamResourceConfig[0]) => c.isCustomResource && !c.topics, ); const customRoadmaps = teamResources.filter( - (c: TeamResourceConfig[0]) => c.isCustomResource && c.topics + (c: TeamResourceConfig[0]) => c.isCustomResource && c.topics, ); const defaultRoadmaps = teamResources.filter( - (c: TeamResourceConfig[0]) => !c.isCustomResource + (c: TeamResourceConfig[0]) => !c.isCustomResource, ); const hasRoadmaps = @@ -272,11 +272,8 @@ export function TeamRoadmaps() { {addRoadmapModal} {createRoadmapModal} - roadmap + +

No roadmaps

{canManageCurrentTeam @@ -380,11 +377,11 @@ export function TeamRoadmaps() { onDelete={() => { if ( confirm( - 'Are you sure you want to remove this roadmap?' + 'Are you sure you want to remove this roadmap?', ) ) { onRemove(resourceConfig.resourceId).finally( - () => {} + () => {}, ); } }} @@ -405,7 +402,7 @@ export function TeamRoadmaps() { )} ); - } + }, )} @@ -433,7 +430,7 @@ export function TeamRoadmaps() { 'grid grid-cols-1 p-2.5', canManageCurrentTeam ? 'sm:grid-cols-[auto_172px]' - : 'sm:grid-cols-[auto_110px]' + : 'sm:grid-cols-[auto_110px]', )} key={resourceConfig.resourceId} > @@ -464,11 +461,11 @@ export function TeamRoadmaps() { onDelete={() => { if ( confirm( - 'Are you sure you want to remove this roadmap?' + 'Are you sure you want to remove this roadmap?', ) ) { onRemove(resourceConfig.resourceId).finally( - () => {} + () => {}, ); } }} @@ -557,11 +554,11 @@ export function TeamRoadmaps() { onDelete={() => { if ( confirm( - 'Are you sure you want to remove this roadmap?' + 'Are you sure you want to remove this roadmap?', ) ) { onRemove(resourceConfig.resourceId).finally( - () => {} + () => {}, ); } }} diff --git a/src/components/UserProgress/UserCustomProgressModal.tsx b/src/components/UserProgress/UserCustomProgressModal.tsx index f79fd6068..b907c0396 100644 --- a/src/components/UserProgress/UserCustomProgressModal.tsx +++ b/src/components/UserProgress/UserCustomProgressModal.tsx @@ -4,13 +4,13 @@ import { useKeydown } from '../../hooks/use-keydown'; import { httpGet } from '../../lib/http'; import type { ResourceType } from '../../lib/resource-progress'; import { topicSelectorAll } from '../../lib/resource-progress'; -import CloseIcon from '../../icons/close.svg'; import { deleteUrlParam, getUrlParams } from '../../lib/browser'; import { useAuth } from '../../hooks/use-auth'; import type { GetRoadmapResponse } from '../CustomRoadmap/CustomRoadmap'; import { ReadonlyEditor } from '../../../editor/readonly-editor'; import { ProgressLoadingError } from './ProgressLoadingError'; import { UserProgressModalHeader } from './UserProgressModalHeader'; +import { X } from 'lucide-react'; export type ProgressMapProps = { userId?: string; @@ -208,7 +208,7 @@ export function UserCustomProgressModal(props: ProgressMapProps) { className={`absolute right-2.5 top-3 ml-auto inline-flex items-center rounded-lg bg-gray-100 bg-transparent p-1.5 text-sm text-gray-400 hover:text-gray-900 lg:hidden`} onClick={onClose} > - {'close'} + Close modal diff --git a/src/components/UserProgress/UserProgressModal.tsx b/src/components/UserProgress/UserProgressModal.tsx index 69774038e..5a03e2fc3 100644 --- a/src/components/UserProgress/UserProgressModal.tsx +++ b/src/components/UserProgress/UserProgressModal.tsx @@ -6,11 +6,11 @@ import { useKeydown } from '../../hooks/use-keydown'; import { httpGet } from '../../lib/http'; import type { ResourceType } from '../../lib/resource-progress'; import { topicSelectorAll } from '../../lib/resource-progress'; -import CloseIcon from '../../icons/close.svg'; import { deleteUrlParam, getUrlParams } from '../../lib/browser'; import { useAuth } from '../../hooks/use-auth'; import { ProgressLoadingError } from './ProgressLoadingError'; import { UserProgressModalHeader } from './UserProgressModalHeader'; +import { X } from 'lucide-react'; export type ProgressMapProps = { userId?: string; @@ -70,12 +70,12 @@ export function UserProgressModal(props: ProgressMapProps) { async function getUserProgress( userId: string, resourceType: string, - resourceId: string + resourceId: string, ): Promise { const { error, response } = await httpGet( `${ import.meta.env.PUBLIC_API_URL - }/v1-get-user-progress/${userId}?resourceType=${resourceType}&resourceId=${resourceId}` + }/v1-get-user-progress/${userId}?resourceType=${resourceType}&resourceId=${resourceId}`, ); if (error || !response) { @@ -86,7 +86,7 @@ export function UserProgressModal(props: ProgressMapProps) { } async function getRoadmapSVG( - jsonUrl: string + jsonUrl: string, ): Promise { const { error, response: roadmapJson } = await httpGet(jsonUrl); if (error || !roadmapJson) { @@ -216,7 +216,7 @@ export function UserProgressModal(props: ProgressMapProps) { className={`absolute right-2.5 top-3 ml-auto inline-flex items-center rounded-lg bg-gray-100 bg-transparent p-1.5 text-sm text-gray-400 hover:text-gray-900 lg:hidden`} onClick={onClose} > - {'close'} + Close modal