Migrate to Tailwind 4 + Editor Upgrade (#8465)
* wip * fix: roadmap editor * fix: padding * wip * fix: remove editor package * wip * fix: update pnpm lock * Add contribution docs * UI changes for TW4 * Update deployment workflow --------- Co-authored-by: Arik Chakma <arikchangma@gmail.com>
This commit is contained in:
1 parent
09d8c709d4
commit
64a65fa2e9
239 files changed
+1167
-1171
No files matched your search
@@ -163,7 +163,7 @@ const sidebarLinks = [
|
||||
: 'border-r-transparent text-gray-500 hover:border-r-gray-300'
|
||||
}`}
|
||||
>
|
||||
<span class='flex flex-grow items-center'>
|
||||
<span class='flex grow items-center'>
|
||||
{sidebarLink.icon.component ? (
|
||||
<sidebarLink.icon.component
|
||||
className={`${sidebarLink.icon.classes} mr-2`}
|
||||
|
||||
@@ -83,10 +83,10 @@ export function AccountStreak(props: AccountStreakProps) {
|
||||
const totalCircles = leftCircleCount + currentCircleCount + remainingCount;
|
||||
|
||||
return (
|
||||
<div className="relative z-[90] animate-fade-in">
|
||||
<div className="relative z-90 animate-fade-in">
|
||||
<button
|
||||
className={cn(
|
||||
'flex items-center justify-center rounded-lg p-1.5 px-2 text-purple-400 hover:bg-purple-100/10 focus:outline-none',
|
||||
'flex items-center justify-center rounded-lg p-1.5 px-2 text-purple-400 hover:bg-purple-100/10 focus:outline-hidden',
|
||||
{
|
||||
'bg-purple-100/10': showDropdown,
|
||||
},
|
||||
|
||||
@@ -128,20 +128,20 @@ export function AccountStreakHeatmap(props: AccountStreakHeatmapProps) {
|
||||
]}
|
||||
classForValue={(value) => {
|
||||
if (!value) {
|
||||
return 'fill-slate-700 rounded-md [rx:2px] focus:outline-none';
|
||||
return 'fill-slate-700 rounded-md [rx:2px] focus:outline-hidden';
|
||||
}
|
||||
|
||||
const { count } = value;
|
||||
if (count >= 20) {
|
||||
return 'fill-slate-200 rounded-md [rx:2px] focus:outline-none';
|
||||
return 'fill-slate-200 rounded-md [rx:2px] focus:outline-hidden';
|
||||
} else if (count >= 10) {
|
||||
return 'fill-slate-300 rounded-md [rx:2px] focus:outline-none';
|
||||
return 'fill-slate-300 rounded-md [rx:2px] focus:outline-hidden';
|
||||
} else if (count >= 5) {
|
||||
return 'fill-slate-400 rounded-md [rx:2px] focus:outline-none';
|
||||
return 'fill-slate-400 rounded-md [rx:2px] focus:outline-hidden';
|
||||
} else if (count >= 3) {
|
||||
return 'fill-slate-500 rounded-md [rx:2px] focus:outline-none';
|
||||
return 'fill-slate-500 rounded-md [rx:2px] focus:outline-hidden';
|
||||
} else {
|
||||
return 'fill-slate-600 rounded-md [rx:2px] focus:outline-none';
|
||||
return 'fill-slate-600 rounded-md [rx:2px] focus:outline-hidden';
|
||||
}
|
||||
}}
|
||||
tooltipDataAttrs={(value: any) => {
|
||||
@@ -159,7 +159,7 @@ export function AccountStreakHeatmap(props: AccountStreakHeatmapProps) {
|
||||
|
||||
<ReactTooltip
|
||||
id="user-activity-tip"
|
||||
className="!rounded-lg !bg-slate-900 !p-1 !px-2 !text-xs"
|
||||
className="rounded-lg! bg-slate-900! p-1! px-2! text-xs!"
|
||||
/>
|
||||
|
||||
<div className="mt-2 flex items-center justify-end">
|
||||
@@ -173,14 +173,14 @@ export function AccountStreakHeatmap(props: AccountStreakHeatmapProps) {
|
||||
data-tooltip-content={`${legend.count} Updates`}
|
||||
>
|
||||
<div
|
||||
className={`h-2.5 w-2.5 ${legend.color} mr-1 rounded-sm`}
|
||||
className={`h-2.5 w-2.5 ${legend.color} mr-1 rounded-xs`}
|
||||
></div>
|
||||
</div>
|
||||
))}
|
||||
<span className="ml-2 text-xs text-slate-500">More</span>
|
||||
<ReactTooltip
|
||||
id="user-activity-tip"
|
||||
className="!rounded-lg !bg-slate-900 !p-1 !px-2 !text-sm"
|
||||
className="rounded-lg! bg-slate-900! p-1! px-2! text-sm!"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -43,7 +43,7 @@ export function ActivityTopicsModal(props: ActivityTopicDetailsProps) {
|
||||
onClose();
|
||||
}}
|
||||
>
|
||||
<div className={`popup-body relative rounded-lg bg-white p-4 shadow`}>
|
||||
<div className={`popup-body relative rounded-lg bg-white p-4 shadow-sm`}>
|
||||
<span className="mb-2 flex items-center justify-between text-lg font-semibold capitalize">
|
||||
<span className="flex items-center gap-2">
|
||||
{actionType.replace('_', ' ')}
|
||||
|
||||
@@ -36,7 +36,7 @@ export function ProjectProgress(props: ProjectProgressType) {
|
||||
target="_blank"
|
||||
>
|
||||
<ProjectStatus projectStatus={projectStatus} />
|
||||
<span className="ml-2 flex-grow truncate">{projectStatus?.title}</span>
|
||||
<span className="ml-2 grow truncate">{projectStatus?.title}</span>
|
||||
<span className="inline-flex items-center gap-1 text-xs text-gray-400">
|
||||
{projectStatus.upvotes}
|
||||
<ThumbsUp className="size-2.5 stroke-[2.5px]" />
|
||||
|
||||
@@ -73,7 +73,7 @@ export function ResourceProgress(props: ResourceProgressType) {
|
||||
showActions ? 'pr-7' : '',
|
||||
)}
|
||||
>
|
||||
<span className="flex-grow truncate">{title}</span>
|
||||
<span className="grow truncate">{title}</span>
|
||||
<span className="text-xs text-gray-400">
|
||||
{parseInt(progressPercentage, 10)}%
|
||||
</span>
|
||||
|
||||
@@ -69,7 +69,7 @@ export function AddTeamRoadmap(props: AddTeamRoadmapProps) {
|
||||
<div className="relative h-full w-full max-w-md p-4 md:h-auto">
|
||||
<div
|
||||
ref={popupBodyEl}
|
||||
className="popup-body relative rounded-lg bg-white p-4 shadow"
|
||||
className="popup-body relative rounded-lg bg-white p-4 shadow-sm"
|
||||
>
|
||||
{isLoading && (
|
||||
<>
|
||||
@@ -99,7 +99,7 @@ export function AddTeamRoadmap(props: AddTeamRoadmapProps) {
|
||||
<button
|
||||
onClick={onClose}
|
||||
type="button"
|
||||
className="flex-grow cursor-pointer rounded-lg bg-gray-200 py-2 text-center hover:bg-gray-300"
|
||||
className="grow cursor-pointer rounded-lg bg-gray-200 py-2 text-center hover:bg-gray-300"
|
||||
>
|
||||
Done
|
||||
</button>
|
||||
@@ -110,7 +110,7 @@ export function AddTeamRoadmap(props: AddTeamRoadmapProps) {
|
||||
setIsLoading(false);
|
||||
}}
|
||||
type="button"
|
||||
className="flex-grow cursor-pointer rounded-lg bg-black py-2 text-center text-white"
|
||||
className="grow cursor-pointer rounded-lg bg-black py-2 text-center text-white"
|
||||
>
|
||||
+ Add More
|
||||
</button>
|
||||
@@ -126,7 +126,7 @@ export function AddTeamRoadmap(props: AddTeamRoadmapProps) {
|
||||
<button
|
||||
onClick={onClose}
|
||||
type="button"
|
||||
className="flex-grow cursor-pointer rounded-lg bg-gray-200 py-2 text-center hover:bg-gray-300"
|
||||
className="grow cursor-pointer rounded-lg bg-gray-200 py-2 text-center hover:bg-gray-300"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
@@ -152,7 +152,7 @@ export function AddTeamRoadmap(props: AddTeamRoadmapProps) {
|
||||
setSelectedRoadmap(roadmapId);
|
||||
});
|
||||
}}
|
||||
inputClassName="mt-2 mb-2 block w-full rounded-md border border-gray-300 px-3 py-2 outline-none placeholder:text-gray-400 focus:border-gray-400"
|
||||
inputClassName="mt-2 mb-2 block w-full rounded-md border border-gray-300 px-3 py-2 outline-hidden placeholder:text-gray-400 focus:border-gray-400"
|
||||
placeholder={'Search for roadmap'}
|
||||
/>
|
||||
|
||||
@@ -160,7 +160,7 @@ export function AddTeamRoadmap(props: AddTeamRoadmapProps) {
|
||||
<button
|
||||
onClick={onClose}
|
||||
type="button"
|
||||
className="flex-grow cursor-pointer rounded-lg bg-gray-200 py-2 text-center hover:bg-gray-300"
|
||||
className="grow cursor-pointer rounded-lg bg-gray-200 py-2 text-center hover:bg-gray-300"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
|
||||
@@ -30,7 +30,7 @@ function Input(props: InputProps) {
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
rows={rows}
|
||||
className="mt-1 block w-full rounded-md border border-gray-300 p-2 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"
|
||||
className="mt-1 block w-full rounded-md border border-gray-300 p-2 shadow-xs focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"
|
||||
autoComplete="off"
|
||||
data-1p-ignore=""
|
||||
data-form-type="other"
|
||||
@@ -45,7 +45,7 @@ function Input(props: InputProps) {
|
||||
value={value}
|
||||
onChange={onChange}
|
||||
required={required}
|
||||
className="mt-1 block w-full rounded-md border border-gray-300 p-2 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"
|
||||
className="mt-1 block w-full rounded-md border border-gray-300 p-2 shadow-xs focus:border-indigo-500 focus:ring-indigo-500 sm:text-sm"
|
||||
autoComplete="off"
|
||||
data-1p-ignore=""
|
||||
data-form-type="other"
|
||||
@@ -120,7 +120,7 @@ export function AdvertiseForm() {
|
||||
Ready to learn more? Fill out the form below to get started!
|
||||
</h2>
|
||||
{error && (
|
||||
<div className="relative mb-4 rounded border border-red-400 bg-red-100 px-4 py-3 text-red-700">
|
||||
<div className="relative mb-4 rounded-sm border border-red-400 bg-red-100 px-4 py-3 text-red-700">
|
||||
{error}
|
||||
</div>
|
||||
)}
|
||||
@@ -199,7 +199,7 @@ export function AdvertiseForm() {
|
||||
type="checkbox"
|
||||
checked={formData.updates}
|
||||
onChange={handleInputChange}
|
||||
className="h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-500"
|
||||
className="h-4 w-4 rounded-sm border-gray-300 text-indigo-600 focus:ring-indigo-500"
|
||||
/>
|
||||
</div>
|
||||
<div className="ml-3 text-sm">
|
||||
@@ -213,7 +213,7 @@ export function AdvertiseForm() {
|
||||
<div>
|
||||
<button
|
||||
type="submit"
|
||||
className="flex justify-center rounded-md border border-transparent bg-indigo-600 px-4 py-2 text-sm font-medium text-white shadow-sm hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
|
||||
className="flex justify-center rounded-md border border-transparent bg-indigo-600 px-4 py-2 text-sm font-medium text-white shadow-xs hover:bg-indigo-700 focus:outline-hidden focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
|
||||
>
|
||||
Send
|
||||
</button>
|
||||
|
||||
@@ -115,7 +115,7 @@ export function CourseLoginPopup(props: CourseLoginPopupProps) {
|
||||
<div className="flex flex-row gap-2">
|
||||
{!isUsingEmail && (
|
||||
<button
|
||||
className="flex-grow rounded-md border border-gray-400 px-4 py-2 text-sm text-gray-600 hover:bg-gray-100"
|
||||
className="grow rounded-md border border-gray-400 px-4 py-2 text-sm text-gray-600 hover:bg-gray-100"
|
||||
onClick={() => setIsUsingEmail(true)}
|
||||
>
|
||||
Use your email address
|
||||
@@ -124,13 +124,13 @@ export function CourseLoginPopup(props: CourseLoginPopupProps) {
|
||||
{isUsingEmail && (
|
||||
<>
|
||||
<button
|
||||
className="flex-grow rounded-md border border-gray-400 px-4 py-2 text-sm text-gray-600 hover:bg-gray-100"
|
||||
className="grow rounded-md border border-gray-400 px-4 py-2 text-sm text-gray-600 hover:bg-gray-100"
|
||||
onClick={() => setEmailNature('login')}
|
||||
>
|
||||
Already have an account
|
||||
</button>
|
||||
<button
|
||||
className="flex-grow rounded-md border border-gray-400 px-4 py-2 text-sm text-gray-600 hover:bg-gray-100"
|
||||
className="grow rounded-md border border-gray-400 px-4 py-2 text-sm text-gray-600 hover:bg-gray-100"
|
||||
onClick={() => setEmailNature('signup')}
|
||||
>
|
||||
Create an account
|
||||
|
||||
@@ -70,7 +70,7 @@ export function EmailLoginForm(props: EmailLoginFormProps) {
|
||||
type="email"
|
||||
autoComplete="email"
|
||||
required
|
||||
className="block w-full rounded-lg border border-gray-300 px-3 py-2 shadow-sm outline-none placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
|
||||
className="block w-full rounded-lg border border-gray-300 px-3 py-2 shadow-xs outline-hidden placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
|
||||
placeholder="Email Address"
|
||||
value={email}
|
||||
onInput={(e) => setEmail(String((e.target as any).value))}
|
||||
@@ -84,7 +84,7 @@ export function EmailLoginForm(props: EmailLoginFormProps) {
|
||||
type="password"
|
||||
autoComplete="current-password"
|
||||
required
|
||||
className="mt-2 block w-full rounded-lg border border-gray-300 px-3 py-2 shadow-sm outline-none placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
|
||||
className="mt-2 block w-full rounded-lg border border-gray-300 px-3 py-2 shadow-xs outline-hidden placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
|
||||
placeholder="Password"
|
||||
value={password}
|
||||
onInput={(e) => setPassword(String((e.target as any).value))}
|
||||
@@ -106,7 +106,7 @@ export function EmailLoginForm(props: EmailLoginFormProps) {
|
||||
<button
|
||||
type="submit"
|
||||
disabled={isLoading || isDisabled}
|
||||
className="inline-flex w-full items-center justify-center rounded-lg bg-black p-2 py-3 text-sm font-medium text-white outline-none focus:ring-2 focus:ring-black focus:ring-offset-1 disabled:bg-gray-400"
|
||||
className="inline-flex w-full items-center justify-center rounded-lg bg-black p-2 py-3 text-sm font-medium text-white outline-hidden focus:ring-2 focus:ring-black focus:ring-offset-1 disabled:bg-gray-400"
|
||||
>
|
||||
{isLoading ? 'Please wait...' : 'Continue'}
|
||||
</button>
|
||||
|
||||
@@ -80,7 +80,7 @@ export function EmailSignupForm(props: EmailSignupFormProps) {
|
||||
min={3}
|
||||
max={50}
|
||||
required
|
||||
className="block w-full rounded-lg border border-gray-300 px-3 py-2 outline-none placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
|
||||
className="block w-full rounded-lg border border-gray-300 px-3 py-2 outline-hidden placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
|
||||
placeholder="Full Name"
|
||||
value={name}
|
||||
onInput={(e) => setName(String((e.target as any).value))}
|
||||
@@ -93,7 +93,7 @@ export function EmailSignupForm(props: EmailSignupFormProps) {
|
||||
type="email"
|
||||
autoComplete="email"
|
||||
required
|
||||
className="block w-full rounded-lg border border-gray-300 px-3 py-2 outline-none placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
|
||||
className="block w-full rounded-lg border border-gray-300 px-3 py-2 outline-hidden placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
|
||||
placeholder="Email Address"
|
||||
value={email}
|
||||
onInput={(e) => setEmail(String((e.target as any).value))}
|
||||
@@ -108,7 +108,7 @@ export function EmailSignupForm(props: EmailSignupFormProps) {
|
||||
min={6}
|
||||
max={50}
|
||||
required
|
||||
className="block w-full rounded-lg border border-gray-300 px-3 py-2 outline-none placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
|
||||
className="block w-full rounded-lg border border-gray-300 px-3 py-2 outline-hidden placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
|
||||
placeholder="Password"
|
||||
value={password}
|
||||
onInput={(e) => setPassword(String((e.target as any).value))}
|
||||
@@ -121,7 +121,7 @@ export function EmailSignupForm(props: EmailSignupFormProps) {
|
||||
<button
|
||||
type="submit"
|
||||
disabled={isLoading || isDisabled}
|
||||
className="inline-flex w-full items-center justify-center rounded-lg bg-black p-2 py-3 text-sm font-medium text-white outline-none focus:ring-2 focus:ring-black focus:ring-offset-1 disabled:bg-gray-400"
|
||||
className="inline-flex w-full items-center justify-center rounded-lg bg-black p-2 py-3 text-sm font-medium text-white outline-hidden focus:ring-2 focus:ring-black focus:ring-offset-1 disabled:bg-gray-400"
|
||||
>
|
||||
{isLoading ? 'Please wait...' : 'Continue to Verify Email'}
|
||||
</button>
|
||||
|
||||
@@ -33,7 +33,7 @@ export function ForgotPasswordForm() {
|
||||
<input
|
||||
type="email"
|
||||
name="email"
|
||||
className="mt-2 block w-full appearance-none rounded-lg border border-gray-300 px-3 py-2 shadow-sm outline-none transition duration-150 ease-in-out placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
|
||||
className="mt-2 block w-full appearance-none rounded-lg border border-gray-300 px-3 py-2 shadow-xs outline-hidden transition duration-150 ease-in-out placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
|
||||
required
|
||||
placeholder="Email Address"
|
||||
value={email}
|
||||
@@ -55,7 +55,7 @@ export function ForgotPasswordForm() {
|
||||
<button
|
||||
type="submit"
|
||||
disabled={isLoading}
|
||||
className="mt-3 inline-flex w-full items-center justify-center rounded-lg bg-black p-2 py-3 text-sm font-medium text-white outline-none focus:ring-2 focus:ring-black focus:ring-offset-1 disabled:bg-gray-400"
|
||||
className="mt-3 inline-flex w-full items-center justify-center rounded-lg bg-black p-2 py-3 text-sm font-medium text-white outline-hidden focus:ring-2 focus:ring-black focus:ring-offset-1 disabled:bg-gray-400"
|
||||
>
|
||||
{isLoading ? 'Please wait...' : 'Continue'}
|
||||
</button>
|
||||
|
||||
@@ -148,7 +148,7 @@ export function GitHubButton(props: GitHubButtonProps) {
|
||||
<>
|
||||
<button
|
||||
className={cn(
|
||||
'inline-flex h-10 w-full items-center justify-center gap-2 rounded border border-slate-300 bg-white p-2 text-sm font-medium text-black outline-none hover:border-gray-400 hover:bg-gray-50 focus:ring-2 focus:ring-[#333] focus:ring-offset-1 disabled:cursor-not-allowed disabled:opacity-60',
|
||||
'inline-flex h-10 w-full items-center justify-center gap-2 rounded-sm border border-slate-300 bg-white p-2 text-sm font-medium text-black outline-hidden hover:border-gray-400 hover:bg-gray-50 focus:ring-2 focus:ring-[#333] focus:ring-offset-1 disabled:cursor-not-allowed disabled:opacity-60',
|
||||
className,
|
||||
)}
|
||||
disabled={isLoading || isDisabled}
|
||||
|
||||
@@ -147,7 +147,7 @@ export function GoogleButton(props: GoogleButtonProps) {
|
||||
<>
|
||||
<button
|
||||
className={cn(
|
||||
'inline-flex h-10 w-full items-center justify-center gap-2 rounded border border-slate-300 bg-white p-2 text-sm font-medium text-black outline-none hover:border-gray-400 hover:bg-gray-50 focus:ring-2 focus:ring-[#333] focus:ring-offset-1 disabled:cursor-not-allowed disabled:opacity-60',
|
||||
'inline-flex h-10 w-full items-center justify-center gap-2 rounded-sm border border-slate-300 bg-white p-2 text-sm font-medium text-black outline-hidden hover:border-gray-400 hover:bg-gray-50 focus:ring-2 focus:ring-[#333] focus:ring-offset-1 disabled:cursor-not-allowed disabled:opacity-60',
|
||||
className,
|
||||
)}
|
||||
disabled={isLoading || isDisabled}
|
||||
|
||||
@@ -152,7 +152,7 @@ export function LinkedInButton(props: LinkedInButtonProps) {
|
||||
<>
|
||||
<button
|
||||
className={cn(
|
||||
'inline-flex h-10 w-full items-center justify-center gap-2 rounded border border-slate-300 bg-white p-2 text-sm font-medium text-black outline-none hover:border-gray-400 focus:ring-2 focus:ring-[#333] focus:ring-offset-1 disabled:cursor-not-allowed disabled:opacity-60',
|
||||
'inline-flex h-10 w-full items-center justify-center gap-2 rounded-sm border border-slate-300 bg-white p-2 text-sm font-medium text-black outline-hidden hover:border-gray-400 focus:ring-2 focus:ring-[#333] focus:ring-offset-1 disabled:cursor-not-allowed disabled:opacity-60',
|
||||
className,
|
||||
)}
|
||||
disabled={isLoading || isDisabled}
|
||||
|
||||
@@ -61,7 +61,7 @@ export function ResetPasswordForm() {
|
||||
<form className="mx-auto w-full" onSubmit={handleSubmit}>
|
||||
<input
|
||||
type="password"
|
||||
className="mb-2 mt-2 block w-full appearance-none rounded-lg border border-gray-300 px-3 py-2 shadow-sm outline-none transition duration-150 ease-in-out placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
|
||||
className="mb-2 mt-2 block w-full appearance-none rounded-lg border border-gray-300 px-3 py-2 shadow-xs outline-hidden transition duration-150 ease-in-out placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
|
||||
required
|
||||
minLength={6}
|
||||
placeholder="New Password"
|
||||
@@ -71,7 +71,7 @@ export function ResetPasswordForm() {
|
||||
|
||||
<input
|
||||
type="password"
|
||||
className="mt-2 block w-full appearance-none rounded-lg border border-gray-300 px-3 py-2 shadow-sm outline-none transition duration-150 ease-in-out placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
|
||||
className="mt-2 block w-full appearance-none rounded-lg border border-gray-300 px-3 py-2 shadow-xs outline-hidden transition duration-150 ease-in-out placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
|
||||
required
|
||||
minLength={6}
|
||||
placeholder="Confirm New Password"
|
||||
@@ -88,7 +88,7 @@ export function ResetPasswordForm() {
|
||||
<button
|
||||
type="submit"
|
||||
disabled={isLoading}
|
||||
className="mt-2 inline-flex w-full items-center justify-center rounded-lg bg-black p-2 py-3 text-sm font-medium text-white outline-none focus:ring-2 focus:ring-black focus:ring-offset-1 disabled:bg-gray-400"
|
||||
className="mt-2 inline-flex w-full items-center justify-center rounded-lg bg-black p-2 py-3 text-sm font-medium text-white outline-hidden focus:ring-2 focus:ring-black focus:ring-offset-1 disabled:bg-gray-400"
|
||||
>
|
||||
{isLoading ? 'Please wait...' : 'Reset Password'}
|
||||
</button>
|
||||
|
||||
+15
-15
@@ -125,7 +125,7 @@ export function Befriend() {
|
||||
<div>
|
||||
<a
|
||||
href="/"
|
||||
className="flex-grow cursor-pointer rounded-lg bg-gray-200 px-3 py-2 text-center"
|
||||
className="grow cursor-pointer rounded-lg bg-gray-200 px-3 py-2 text-center"
|
||||
>
|
||||
Back to home
|
||||
</a>
|
||||
@@ -141,7 +141,7 @@ export function Befriend() {
|
||||
const isMe = currentUser?.id === user.id;
|
||||
|
||||
return (
|
||||
<div className="container !max-w-[400px] text-center">
|
||||
<div className="container max-w-[400px]! text-center">
|
||||
<img
|
||||
alt={'join team'}
|
||||
src={userAvatar}
|
||||
@@ -169,7 +169,7 @@ export function Befriend() {
|
||||
});
|
||||
}}
|
||||
type="button"
|
||||
className="w-full flex-grow cursor-pointer rounded-lg bg-black px-3 py-2 text-center text-white disabled:cursor-not-allowed disabled:opacity-40"
|
||||
className="w-full grow cursor-pointer rounded-lg bg-black px-3 py-2 text-center text-white disabled:cursor-not-allowed disabled:opacity-40"
|
||||
>
|
||||
{isMe ? "You can't add yourself" : 'Add Friend'}
|
||||
</button>
|
||||
@@ -177,7 +177,7 @@ export function Befriend() {
|
||||
|
||||
{user.status === 'sent' && (
|
||||
<>
|
||||
<span className="flex w-full flex-grow cursor-default items-center justify-center rounded-lg border border-gray-300 px-3 py-2 text-center text-black">
|
||||
<span className="flex w-full grow cursor-default items-center justify-center rounded-lg border border-gray-300 px-3 py-2 text-center text-black">
|
||||
<CheckIcon additionalClasses="mr-2 h-4 w-4" />
|
||||
Request Sent
|
||||
</span>
|
||||
@@ -188,7 +188,7 @@ export function Befriend() {
|
||||
setIsConfirming(true);
|
||||
}}
|
||||
type="button"
|
||||
className="flex w-full flex-grow cursor-pointer items-center justify-center rounded-lg border border-red-600 bg-red-600 px-3 py-2 text-center text-white hover:bg-red-700"
|
||||
className="flex w-full grow cursor-pointer items-center justify-center rounded-lg border border-red-600 bg-red-600 px-3 py-2 text-center text-white hover:bg-red-700"
|
||||
>
|
||||
<DeleteUserIcon additionalClasses="mr-2 h-[19px] w-[19px]" />
|
||||
Withdraw Request
|
||||
@@ -196,7 +196,7 @@ export function Befriend() {
|
||||
)}
|
||||
|
||||
{isConfirming && (
|
||||
<span className="flex w-full flex-grow cursor-default items-center justify-center rounded-lg border border-red-600 px-3 py-2.5 text-center text-sm text-red-600">
|
||||
<span className="flex w-full grow cursor-default items-center justify-center rounded-lg border border-red-600 px-3 py-2.5 text-center text-sm text-red-600">
|
||||
Are you sure?{' '}
|
||||
<button
|
||||
className="ml-2 text-red-700 underline"
|
||||
@@ -225,7 +225,7 @@ export function Befriend() {
|
||||
|
||||
{user.status === 'accepted' && (
|
||||
<>
|
||||
<span className="flex w-full flex-grow cursor-default items-center justify-center rounded-lg border border-gray-300 px-3 py-2 text-center text-black">
|
||||
<span className="flex w-full grow cursor-default items-center justify-center rounded-lg border border-gray-300 px-3 py-2 text-center text-black">
|
||||
<AddedUserIcon additionalClasses="mr-2 h-5 w-5" />
|
||||
You are friends
|
||||
</span>
|
||||
@@ -236,7 +236,7 @@ export function Befriend() {
|
||||
setIsConfirming(true);
|
||||
}}
|
||||
type="button"
|
||||
className="flex w-full flex-grow cursor-pointer items-center justify-center rounded-lg border border-red-600 bg-red-600 px-3 py-2 text-center text-white hover:bg-red-700"
|
||||
className="flex w-full grow cursor-pointer items-center justify-center rounded-lg border border-red-600 bg-red-600 px-3 py-2 text-center text-white hover:bg-red-700"
|
||||
>
|
||||
<DeleteUserIcon additionalClasses="mr-2 h-[19px] w-[19px]" />
|
||||
Remove Friend
|
||||
@@ -244,7 +244,7 @@ export function Befriend() {
|
||||
)}
|
||||
|
||||
{isConfirming && (
|
||||
<span className="flex w-full flex-grow cursor-default items-center justify-center rounded-lg border border-red-600 px-3 py-2.5 text-center text-sm text-red-600">
|
||||
<span className="flex w-full grow cursor-default items-center justify-center rounded-lg border border-red-600 px-3 py-2.5 text-center text-sm text-red-600">
|
||||
Are you sure?{' '}
|
||||
<button
|
||||
className="ml-2 text-red-700 underline"
|
||||
@@ -271,12 +271,12 @@ export function Befriend() {
|
||||
|
||||
{user.status === 'rejected' && (
|
||||
<>
|
||||
<span className="flex w-full flex-grow cursor-default items-center justify-center rounded-lg border border-gray-300 px-3 py-2 text-center text-black">
|
||||
<span className="flex w-full grow cursor-default items-center justify-center rounded-lg border border-gray-300 px-3 py-2 text-center text-black">
|
||||
<DeleteUserIcon additionalClasses="mr-2 h-4 w-4" />
|
||||
Request Rejected
|
||||
</span>
|
||||
|
||||
<span className="flex w-full flex-grow cursor-default items-center justify-center rounded-lg border border-red-600 px-3 py-2.5 text-center text-sm text-red-600">
|
||||
<span className="flex w-full grow cursor-default items-center justify-center rounded-lg border border-red-600 px-3 py-2.5 text-center text-sm text-red-600">
|
||||
Changed your mind?{' '}
|
||||
<button
|
||||
className="ml-2 text-red-700 underline"
|
||||
@@ -296,7 +296,7 @@ export function Befriend() {
|
||||
|
||||
{user.status === 'got_rejected' && (
|
||||
<>
|
||||
<span className="flex w-full flex-grow cursor-default items-center justify-center rounded-lg border border-red-500 px-3 py-2 text-center text-red-500">
|
||||
<span className="flex w-full grow cursor-default items-center justify-center rounded-lg border border-red-500 px-3 py-2 text-center text-red-500">
|
||||
<StopIcon additionalClasses="mr-2 h-4 w-4" />
|
||||
Request Rejected
|
||||
</span>
|
||||
@@ -311,7 +311,7 @@ export function Befriend() {
|
||||
pageProgressMessage.set('');
|
||||
});
|
||||
}}
|
||||
className="flex w-full flex-grow cursor-pointer items-center justify-center rounded-lg border border-gray-800 bg-gray-800 px-3 py-2 text-center text-white hover:bg-black"
|
||||
className="flex w-full grow cursor-pointer items-center justify-center rounded-lg border border-gray-800 bg-gray-800 px-3 py-2 text-center text-white hover:bg-black"
|
||||
>
|
||||
<CheckIcon additionalClasses="mr-2 h-4 w-4" />
|
||||
Accept Request
|
||||
@@ -323,7 +323,7 @@ export function Befriend() {
|
||||
setIsConfirming(true);
|
||||
}}
|
||||
type="button"
|
||||
className="flex w-full flex-grow cursor-pointer items-center justify-center rounded-lg border border-red-600 bg-white px-3 py-2 text-center text-red-600 hover:bg-red-100"
|
||||
className="flex w-full grow cursor-pointer items-center justify-center rounded-lg border border-red-600 bg-white px-3 py-2 text-center text-red-600 hover:bg-red-100"
|
||||
>
|
||||
<DeleteUserIcon additionalClasses="mr-2 h-[19px] w-[19px]" />
|
||||
Reject Request
|
||||
@@ -331,7 +331,7 @@ export function Befriend() {
|
||||
)}
|
||||
|
||||
{isConfirming && (
|
||||
<span className="flex w-full flex-grow cursor-default items-center justify-center rounded-lg border border-red-600 px-3 py-2.5 text-center text-sm text-red-600">
|
||||
<span className="flex w-full grow cursor-default items-center justify-center rounded-lg border border-red-600 px-3 py-2.5 text-center text-sm text-red-600">
|
||||
Are you sure?{' '}
|
||||
<button
|
||||
className="ml-2 text-red-700 underline"
|
||||
|
||||
@@ -27,7 +27,7 @@ const isBestPracticeReady = !isUpcoming;
|
||||
<MarkFavorite
|
||||
resourceId={bestPracticeId}
|
||||
resourceType="best-practice"
|
||||
className="text-gray-500 !opacity-100 hover:text-gray-600 [&>svg]:stroke-[0.4] [&>svg]:stroke-gray-400 hover:[&>svg]:stroke-gray-600 [&>svg]:h-4 [&>svg]:w-4 sm:[&>svg]:h-5 sm:[&>svg]:w-5 ml-1.5 relative focus:outline-0"
|
||||
className="text-gray-500 opacity-100! hover:text-gray-600 [&>svg]:stroke-[0.4] [&>svg]:stroke-gray-400 [&>svg]:hover:stroke-gray-600 [&>svg]:h-4 [&>svg]:w-4 sm:[&>svg]:h-5 sm:[&>svg]:w-5 ml-1.5 relative focus:outline-0"
|
||||
client:load
|
||||
/>
|
||||
</h1>
|
||||
|
||||
@@ -190,7 +190,7 @@ export function BillingPage() {
|
||||
<div className="mt-8 flex gap-3 max-sm:flex-col">
|
||||
{!isCanceled && (
|
||||
<button
|
||||
className="inline-flex items-center justify-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 shadow-sm transition-colors hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-black focus:ring-offset-2 max-sm:flex-grow"
|
||||
className="inline-flex items-center justify-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 shadow-xs transition-colors hover:bg-gray-50 focus:outline-hidden focus:ring-2 focus:ring-black focus:ring-offset-2 max-sm:grow"
|
||||
onClick={() => {
|
||||
setShowUpgradeModal(true);
|
||||
}}
|
||||
@@ -201,7 +201,7 @@ export function BillingPage() {
|
||||
)}
|
||||
|
||||
<button
|
||||
className="inline-flex items-center justify-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 shadow-sm transition-colors hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-black focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
|
||||
className="inline-flex items-center justify-center rounded-md border border-gray-300 bg-white px-4 py-2 text-sm font-medium text-gray-700 shadow-xs transition-colors hover:bg-gray-50 focus:outline-hidden focus:ring-2 focus:ring-black focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
|
||||
onClick={() => {
|
||||
createCustomerPortal({});
|
||||
}}
|
||||
|
||||
@@ -59,7 +59,7 @@ export function EmptyBillingScreen(props: EmptyBillingScreenProps) {
|
||||
|
||||
<button
|
||||
onClick={onUpgrade}
|
||||
className="inline-flex items-center justify-center rounded-lg bg-black px-6 py-2.5 text-sm font-medium text-white transition-colors hover:opacity-80 focus:outline-none focus:ring-2 focus:ring-black focus:ring-offset-2"
|
||||
className="inline-flex items-center justify-center rounded-lg bg-black px-6 py-2.5 text-sm font-medium text-white transition-colors hover:opacity-80 focus:outline-hidden focus:ring-2 focus:ring-black focus:ring-offset-2"
|
||||
>
|
||||
Upgrade Account
|
||||
</button>
|
||||
|
||||
@@ -236,12 +236,12 @@ export function UpgradeAccountModal(props: UpgradeAccountModalProps) {
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex-grow"></div>
|
||||
<div className="grow"></div>
|
||||
|
||||
<div>
|
||||
<button
|
||||
className={cn(
|
||||
'flex min-h-9 w-full items-center justify-center rounded-md py-2 text-sm font-medium transition-colors focus:outline-none focus-visible:ring-2 focus-visible:ring-yellow-400 disabled:cursor-not-allowed disabled:opacity-60 sm:min-h-11 sm:py-2.5 sm:text-base',
|
||||
'flex min-h-9 w-full items-center justify-center rounded-md py-2 text-sm font-medium transition-colors focus:outline-hidden focus-visible:ring-2 focus-visible:ring-yellow-400 disabled:cursor-not-allowed disabled:opacity-60 sm:min-h-11 sm:py-2.5 sm:text-base',
|
||||
'bg-yellow-400 text-black hover:bg-yellow-500',
|
||||
)}
|
||||
disabled={
|
||||
|
||||
@@ -17,11 +17,11 @@ const formattedDate = DateTime.fromISO(frontmatter.date).toFormat(
|
||||
|
||||
<div class='relative mb-6' id={changelog.id}>
|
||||
<span
|
||||
class='absolute -left-6 top-2 h-2 w-2 flex-shrink-0 rounded-full bg-gray-300'
|
||||
class='absolute -left-6 top-2 h-2 w-2 shrink-0 rounded-full bg-gray-300'
|
||||
></span>
|
||||
|
||||
<div class='mb-3 flex flex-col sm:flex-row items-start sm:items-center gap-0.5 sm:gap-2'>
|
||||
<span class='flex-shrink-0 text-xs tracking-wide text-gray-400'>
|
||||
<span class='shrink-0 text-xs tracking-wide text-gray-400'>
|
||||
{formattedDate}
|
||||
</span>
|
||||
<span class='truncate text-base font-medium text-balance'>
|
||||
|
||||
@@ -6,13 +6,13 @@ const formattedDate = DateTime.fromISO('2024-09-13').toFormat('dd LLL, yyyy');
|
||||
|
||||
<div class='relative mb-6'>
|
||||
<span
|
||||
class='absolute -left-6 top-2 h-2 w-2 flex-shrink-0 rounded-full bg-gray-300'
|
||||
class='absolute -left-6 top-2 h-2 w-2 shrink-0 rounded-full bg-gray-300'
|
||||
></span>
|
||||
|
||||
<div
|
||||
class='mb-3 flex flex-col items-start gap-0.5 sm:flex-row sm:items-center sm:gap-2'
|
||||
>
|
||||
<span class='flex-shrink-0 text-xs tracking-wide text-gray-400'>
|
||||
<span class='shrink-0 text-xs tracking-wide text-gray-400'>
|
||||
{formattedDate}
|
||||
</span>
|
||||
<span class='truncate text-balance text-base font-medium'>
|
||||
|
||||
@@ -7,7 +7,7 @@ const top10Changelogs = allChangelogs.slice(0, 10);
|
||||
---
|
||||
|
||||
<div class='border-t bg-white py-6 text-left sm:py-16 sm:text-center'>
|
||||
<div class='container !max-w-[650px]'>
|
||||
<div class='container max-w-[650px]!'>
|
||||
<p class='text-2xl font-bold sm:text-5xl'>
|
||||
<img
|
||||
src='/images/gifs/rocket.gif'
|
||||
@@ -40,10 +40,10 @@ const top10Changelogs = allChangelogs.slice(0, 10);
|
||||
href={`/changelog#${changelog.id}`}
|
||||
class='flex flex-col items-start sm:flex-row sm:items-center'
|
||||
>
|
||||
<span class='flex-shrink-0 pr-0 text-right text-sm tracking-wide text-gray-400 sm:w-[120px] sm:pr-4'>
|
||||
<span class='shrink-0 pr-0 text-right text-sm tracking-wide text-gray-400 sm:w-[120px] sm:pr-4'>
|
||||
{formattedDate}
|
||||
</span>
|
||||
<span class='hidden h-3 w-3 flex-shrink-0 rounded-full bg-gray-300 sm:block' />
|
||||
<span class='hidden h-3 w-3 shrink-0 rounded-full bg-gray-300 sm:block' />
|
||||
<span class='text-balance text-base font-medium text-gray-900 sm:pl-8'>
|
||||
{changelog.frontmatter.title}
|
||||
</span>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ChevronLeft, ChevronRight, MoveRight } from 'lucide-react';
|
||||
import { ChevronLeft, ChevronRight } from 'lucide-react';
|
||||
import React, { useState, useEffect, useCallback } from 'react';
|
||||
|
||||
interface ChangelogImagesProps {
|
||||
@@ -63,17 +63,17 @@ const ChangelogImages: React.FC<ChangelogImagesProps> = ({ images }) => {
|
||||
alt={title}
|
||||
className="h-[120px] w-full object-cover object-left-top"
|
||||
/>
|
||||
<span className="absolute group-hover:opacity-0 inset-0 bg-gradient-to-b from-transparent to-black/40" />
|
||||
<span className="absolute group-hover:opacity-0 inset-0 bg-linear-to-b from-transparent to-black/40" />
|
||||
|
||||
<div className="absolute font-medium inset-x-0 top-full group-hover:inset-y-0 flex items-center justify-center px-2 text-center text-xs bg-black/50 text-white py-0.5 opacity-0 group-hover:opacity-100 cursor-pointer">
|
||||
<span className='bg-black py-0.5 rounded px-1'>{title}</span>
|
||||
<span className='bg-black py-0.5 rounded-sm px-1'>{title}</span>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
{enlargedImage && (
|
||||
<div
|
||||
className="fixed inset-0 z-[999] flex items-center justify-center bg-black bg-opacity-75"
|
||||
className="fixed inset-0 z-999 flex items-center justify-center bg-black/75"
|
||||
onClick={handleCloseEnlarged}
|
||||
>
|
||||
<img
|
||||
@@ -82,7 +82,7 @@ const ChangelogImages: React.FC<ChangelogImagesProps> = ({ images }) => {
|
||||
className="max-h-[90%] max-w-[90%] rounded-xl object-contain"
|
||||
/>
|
||||
<button
|
||||
className="absolute left-4 top-1/2 -translate-y-1/2 transform rounded-full bg-white hover:bg-opacity-100 bg-opacity-50 p-2"
|
||||
className="absolute left-4 top-1/2 -translate-y-1/2 transform rounded-full bg-white/50 hover:bg-white/100 p-2"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleNavigation('prev');
|
||||
@@ -91,7 +91,7 @@ const ChangelogImages: React.FC<ChangelogImagesProps> = ({ images }) => {
|
||||
<ChevronLeft size={24} />
|
||||
</button>
|
||||
<button
|
||||
className="absolute right-4 top-1/2 -translate-y-1/2 transform rounded-full bg-white hover:bg-opacity-100 bg-opacity-50 p-2"
|
||||
className="absolute right-4 top-1/2 -translate-y-1/2 transform rounded-full bg-white/50 hover:bg-white/100 p-2"
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
handleNavigation('next');
|
||||
|
||||
@@ -194,13 +194,13 @@ export function CommandMenu() {
|
||||
return (
|
||||
<div className="fixed left-0 right-0 top-0 z-50 flex h-full justify-center overflow-y-auto overflow-x-hidden bg-black/50">
|
||||
<div className="relative top-0 h-full w-full max-w-lg p-2 sm:mt-20 md:h-auto">
|
||||
<div className="relative rounded-lg bg-white shadow" ref={modalRef}>
|
||||
<div className="relative rounded-lg bg-white shadow-sm" ref={modalRef}>
|
||||
<input
|
||||
ref={inputRef}
|
||||
autoFocus={true}
|
||||
type="text"
|
||||
value={searchedText}
|
||||
className="w-full rounded-t-md border-b p-4 text-sm focus:bg-gray-50 focus:outline-none"
|
||||
className="w-full rounded-t-md border-b p-4 text-sm focus:bg-gray-50 focus:outline-hidden"
|
||||
placeholder="Search roadmaps, guides or pages .."
|
||||
autoComplete="off"
|
||||
onInput={(e) => {
|
||||
@@ -249,7 +249,7 @@ export function CommandMenu() {
|
||||
)}
|
||||
<a
|
||||
className={cn(
|
||||
'flex w-full items-center rounded p-2 text-sm',
|
||||
'flex w-full items-center rounded-sm p-2 text-sm',
|
||||
counter === activeCounter ? 'bg-gray-100' : '',
|
||||
)}
|
||||
onMouseOver={() => setActiveCounter(counter)}
|
||||
|
||||
@@ -286,7 +286,7 @@ export function RoadmapSelector(props: RoadmapSelectorProps) {
|
||||
className="relative flex flex-col items-start overflow-hidden rounded-md border border-gray-300"
|
||||
key={resourceId}
|
||||
>
|
||||
<div className={'w-full flex-grow px-3 pb-2 pt-4'}>
|
||||
<div className={'w-full grow px-3 pb-2 pt-4'}>
|
||||
<span className="mb-0.5 block text-base font-medium leading-snug text-black">
|
||||
{roadmapTitle}
|
||||
</span>
|
||||
@@ -341,7 +341,7 @@ export function RoadmapSelector(props: RoadmapSelectorProps) {
|
||||
<button
|
||||
type="button"
|
||||
className={
|
||||
'text-xs text-gray-500 underline hover:text-black focus:outline-none'
|
||||
'text-xs text-gray-500 underline hover:text-black focus:outline-hidden'
|
||||
}
|
||||
onClick={() => {
|
||||
if (isCustomResource) {
|
||||
|
||||
@@ -68,11 +68,11 @@ export function SelectRoadmapModal(props: SelectRoadmapModalProps) {
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="fixed left-0 right-0 top-0 z-[100] h-full items-center justify-center overflow-y-auto overflow-x-hidden overscroll-contain bg-black/50">
|
||||
<div className="fixed left-0 right-0 top-0 z-100 h-full items-center justify-center overflow-y-auto overflow-x-hidden overscroll-contain bg-black/50">
|
||||
<div className="relative mx-auto h-full w-full max-w-2xl p-4 md:h-auto">
|
||||
<div
|
||||
ref={popupBodyEl}
|
||||
className="popup-body relative mt-4 overflow-hidden rounded-lg bg-white shadow"
|
||||
className="popup-body relative mt-4 overflow-hidden rounded-lg bg-white shadow-sm"
|
||||
>
|
||||
<button
|
||||
type="button"
|
||||
@@ -86,7 +86,7 @@ export function SelectRoadmapModal(props: SelectRoadmapModalProps) {
|
||||
ref={searchInputEl}
|
||||
type="text"
|
||||
placeholder="Search roadmaps"
|
||||
className="block w-full border-b px-5 pb-3.5 pt-4 outline-none placeholder:text-gray-400"
|
||||
className="block w-full border-b px-5 pb-3.5 pt-4 outline-hidden placeholder:text-gray-400"
|
||||
value={searchText}
|
||||
onInput={(e) => setSearchText((e.target as HTMLInputElement).value)}
|
||||
/>
|
||||
|
||||
@@ -76,7 +76,7 @@ export function Step0(props: Step0Props) {
|
||||
{validTeamTypes.map((validTeamType) => (
|
||||
<button
|
||||
key={validTeamType.value}
|
||||
className={`flex flex-grow flex-col items-center rounded-lg border px-5 pb-10 pt-12 ${
|
||||
className={`flex grow flex-col items-center rounded-lg border px-5 pb-10 pt-12 ${
|
||||
validTeamType.value == selectedTeamType
|
||||
? 'border-gray-400 bg-gray-100'
|
||||
: 'border-gray-300 hover:border-gray-400 hover:bg-gray-50'
|
||||
|
||||
@@ -135,7 +135,7 @@ export function Step1(props: Step1Props) {
|
||||
ref={nameRef as any}
|
||||
autoFocus={true}
|
||||
id="name"
|
||||
className="mt-2 block w-full rounded-lg border border-gray-300 px-3 py-2 shadow-sm outline-none placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
|
||||
className="mt-2 block w-full rounded-lg border border-gray-300 px-3 py-2 shadow-xs outline-hidden placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
|
||||
placeholder="Roadmap Inc."
|
||||
disabled={isLoading}
|
||||
required
|
||||
@@ -157,7 +157,7 @@ export function Step1(props: Step1Props) {
|
||||
name="website"
|
||||
required
|
||||
id="website"
|
||||
className="mt-2 block w-full rounded-lg border border-gray-300 px-3 py-2 shadow-sm outline-none placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
|
||||
className="mt-2 block w-full rounded-lg border border-gray-300 px-3 py-2 shadow-xs outline-hidden placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
|
||||
placeholder="https://roadmap.sh"
|
||||
disabled={isLoading}
|
||||
value={website}
|
||||
@@ -178,7 +178,7 @@ export function Step1(props: Step1Props) {
|
||||
type="url"
|
||||
name="website"
|
||||
id="website"
|
||||
className="mt-2 block w-full rounded-lg border border-gray-300 px-3 py-2 shadow-sm outline-none placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
|
||||
className="mt-2 block w-full rounded-lg border border-gray-300 px-3 py-2 shadow-xs outline-hidden placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
|
||||
placeholder="https://www.linkedin.com/company/roadmapsh"
|
||||
disabled={isLoading}
|
||||
value={linkedInUrl}
|
||||
@@ -200,7 +200,7 @@ export function Step1(props: Step1Props) {
|
||||
type="url"
|
||||
name="website"
|
||||
id="website"
|
||||
className="mt-2 block w-full rounded-lg border border-gray-300 px-3 py-2 shadow-sm outline-none placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
|
||||
className="mt-2 block w-full rounded-lg border border-gray-300 px-3 py-2 shadow-xs outline-hidden placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
|
||||
placeholder="https://github.com/roadmapsh"
|
||||
disabled={isLoading}
|
||||
value={gitHubUrl}
|
||||
@@ -219,7 +219,7 @@ export function Step1(props: Step1Props) {
|
||||
<select
|
||||
name="team-size"
|
||||
id="team-size"
|
||||
className="mt-2 block w-full rounded-lg border border-gray-300 px-3 py-2 shadow-sm outline-none placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
|
||||
className="mt-2 block w-full rounded-lg border border-gray-300 px-3 py-2 shadow-xs outline-hidden placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
|
||||
required={selectedTeamType === 'company'}
|
||||
disabled={isLoading}
|
||||
value={teamSize}
|
||||
|
||||
@@ -50,7 +50,7 @@ export function Step2(props: Step2Props) {
|
||||
onClick={onNext}
|
||||
disabled={teamResourceConfig.length !== 0}
|
||||
className={
|
||||
'flex-grow rounded-md border border-gray-300 bg-white px-4 py-2 text-gray-500 hover:border-gray-400 hover:text-black md:flex-auto disabled:opacity-50 disabled:pointer-events-none'
|
||||
'grow rounded-md border border-gray-300 bg-white px-4 py-2 text-gray-500 hover:border-gray-400 hover:text-black md:flex-auto disabled:opacity-50 disabled:pointer-events-none'
|
||||
}
|
||||
>
|
||||
Skip for Now
|
||||
|
||||
@@ -109,7 +109,7 @@ export function Step3(props: Step3Props) {
|
||||
|
||||
setUsers(newUsers);
|
||||
}}
|
||||
className="flex-grow rounded-md border border-gray-200 bg-white px-4 py-2 text-gray-900"
|
||||
className="grow rounded-md border border-gray-200 bg-white px-4 py-2 text-gray-900"
|
||||
/>
|
||||
<RoleDropdown
|
||||
selectedRole={user.role}
|
||||
@@ -180,7 +180,7 @@ export function Step3(props: Step3Props) {
|
||||
onClick={onNext}
|
||||
disabled={users.filter((u) => u.email).length !== 0}
|
||||
className={
|
||||
'rounded-md flex-grow md:flex-auto border border-gray-300 bg-white px-4 py-2 text-gray-500 hover:border-gray-400 hover:text-black disabled:opacity-50 disabled:pointer-events-none'
|
||||
'rounded-md grow md:flex-auto border border-gray-300 bg-white px-4 py-2 text-gray-500 hover:border-gray-400 hover:text-black disabled:opacity-50 disabled:pointer-events-none'
|
||||
}
|
||||
>
|
||||
Skip for Now
|
||||
|
||||
@@ -148,12 +148,12 @@ export function UpdateTeamResourceModal(props: ProgressMapProps) {
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="fixed left-0 right-0 top-0 z-[100] h-full items-center justify-center overflow-y-auto overflow-x-hidden overscroll-contain bg-black/50">
|
||||
<div className="fixed left-0 right-0 top-0 z-100 h-full items-center justify-center overflow-y-auto overflow-x-hidden overscroll-contain bg-black/50">
|
||||
<div className="relative mx-auto h-full w-full max-w-4xl p-4 md:h-auto">
|
||||
<div
|
||||
id={'customized-roadmap'}
|
||||
ref={popupBodyEl}
|
||||
className="popup-body relative rounded-lg bg-white shadow"
|
||||
className="popup-body relative rounded-lg bg-white shadow-sm"
|
||||
>
|
||||
<div
|
||||
className={
|
||||
|
||||
@@ -179,7 +179,7 @@ export function CreateRoadmapModal(props: CreateRoadmapModalProps) {
|
||||
name="title"
|
||||
id="title"
|
||||
required
|
||||
className="block w-full rounded-md border border-gray-300 px-2.5 py-2 text-black outline-none focus:border-black sm:text-sm"
|
||||
className="block w-full rounded-md border border-gray-300 px-2.5 py-2 text-black outline-hidden focus:border-black sm:text-sm"
|
||||
placeholder="Enter Title"
|
||||
value={title}
|
||||
onChange={(e) => setTitle(e.target.value)}
|
||||
@@ -199,7 +199,7 @@ export function CreateRoadmapModal(props: CreateRoadmapModalProps) {
|
||||
name="description"
|
||||
required
|
||||
className={cn(
|
||||
'block h-24 w-full resize-none rounded-md border border-gray-300 px-2.5 py-2 text-black outline-none focus:border-black sm:text-sm',
|
||||
'block h-24 w-full resize-none rounded-md border border-gray-300 px-2.5 py-2 text-black outline-hidden focus:border-black sm:text-sm',
|
||||
isInvalidDescription && 'border-red-300 bg-red-100',
|
||||
)}
|
||||
placeholder="Enter Description"
|
||||
@@ -219,7 +219,7 @@ export function CreateRoadmapModal(props: CreateRoadmapModalProps) {
|
||||
onClick={onClose}
|
||||
type="button"
|
||||
className={cn(
|
||||
'block h-9 rounded-md border border-gray-200 bg-white px-4 py-2 text-sm font-medium text-black outline-none hover:border-gray-300 hover:bg-gray-50 focus:border-gray-300 focus:bg-gray-100',
|
||||
'block h-9 rounded-md border border-gray-200 bg-white px-4 py-2 text-sm font-medium text-black outline-hidden hover:border-gray-300 hover:bg-gray-50 focus:border-gray-300 focus:bg-gray-100',
|
||||
!teamId && 'w-full',
|
||||
)}
|
||||
>
|
||||
@@ -232,7 +232,7 @@ export function CreateRoadmapModal(props: CreateRoadmapModalProps) {
|
||||
disabled={isLoading}
|
||||
type="button"
|
||||
onClick={(e) => handleSubmit(e, false)}
|
||||
className="flex h-9 items-center justify-center rounded-md border border-black bg-white px-4 py-2 text-sm font-medium text-black outline-none hover:bg-black hover:text-white focus:bg-black focus:text-white"
|
||||
className="flex h-9 items-center justify-center rounded-md border border-black bg-white px-4 py-2 text-sm font-medium text-black outline-hidden hover:bg-black hover:text-white focus:bg-black focus:text-white"
|
||||
>
|
||||
{isLoading ? (
|
||||
<Loader2 size={16} className="animate-spin" />
|
||||
@@ -246,7 +246,7 @@ export function CreateRoadmapModal(props: CreateRoadmapModalProps) {
|
||||
disabled={isLoading}
|
||||
type="submit"
|
||||
className={cn(
|
||||
'flex h-9 items-center justify-center rounded-md border border-transparent bg-black px-4 py-2 text-sm font-medium text-white outline-none hover:bg-gray-800 focus:bg-gray-800',
|
||||
'flex h-9 items-center justify-center rounded-md border border-transparent bg-black px-4 py-2 text-sm font-medium text-white outline-hidden hover:bg-gray-800 focus:bg-gray-800',
|
||||
teamId ? 'hidden sm:flex' : 'w-full',
|
||||
)}
|
||||
>
|
||||
|
||||
@@ -53,7 +53,7 @@ export function EmbedRoadmapModal(props: ShareRoadmapModalProps) {
|
||||
<div className="flex items-center justify-between px-4 pb-4 pt-2">
|
||||
<button
|
||||
className={cn(
|
||||
'flex h-9 w-full items-center justify-center rounded-md border border-transparent px-4 py-2 text-sm font-medium text-white outline-none',
|
||||
'flex h-9 w-full items-center justify-center rounded-md border border-transparent px-4 py-2 text-sm font-medium text-white outline-hidden',
|
||||
{
|
||||
'bg-green-500 hover:bg-green-600 focus:bg-green-600': isCopied,
|
||||
'bg-gray-900 hover:bg-gray-800 focus:bg-gray-800': !isCopied,
|
||||
|
||||
@@ -34,7 +34,7 @@ export function PersonalRoadmapActionDropdown(
|
||||
<button
|
||||
disabled={false}
|
||||
onClick={() => setIsOpen(!isOpen)}
|
||||
className="flex items-center gap-1 rounded-md border border-gray-300 bg-white px-2 py-1.5 text-xs hover:bg-gray-50 focus:outline-none sm:hidden"
|
||||
className="flex items-center gap-1 rounded-md border border-gray-300 bg-white px-2 py-1.5 text-xs hover:bg-gray-50 focus:outline-hidden sm:hidden"
|
||||
>
|
||||
<MoreVertical size={14} />
|
||||
Options
|
||||
@@ -53,7 +53,7 @@ export function PersonalRoadmapActionDropdown(
|
||||
setIsOpen(false);
|
||||
onUpdateSharing();
|
||||
}}
|
||||
className="flex w-full cursor-pointer items-center rounded p-2 text-sm font-medium text-slate-100 hover:bg-slate-700"
|
||||
className="flex w-full cursor-pointer items-center rounded-sm p-2 text-sm font-medium text-slate-100 hover:bg-slate-700"
|
||||
>
|
||||
<Lock size={14} className="mr-2" />
|
||||
Sharing
|
||||
@@ -67,7 +67,7 @@ export function PersonalRoadmapActionDropdown(
|
||||
setIsOpen(false);
|
||||
onCustomize();
|
||||
}}
|
||||
className="flex w-full cursor-pointer items-center rounded p-2 text-sm font-medium text-slate-100 hover:bg-slate-700"
|
||||
className="flex w-full cursor-pointer items-center rounded-sm p-2 text-sm font-medium text-slate-100 hover:bg-slate-700"
|
||||
>
|
||||
<Shapes size={14} className="mr-2" />
|
||||
Customize
|
||||
@@ -81,7 +81,7 @@ export function PersonalRoadmapActionDropdown(
|
||||
setIsOpen(false);
|
||||
onDelete();
|
||||
}}
|
||||
className="flex w-full cursor-pointer items-center rounded p-2 text-sm font-medium text-slate-100 hover:bg-slate-700"
|
||||
className="flex w-full cursor-pointer items-center rounded-sm p-2 text-sm font-medium text-slate-100 hover:bg-slate-700"
|
||||
>
|
||||
<Trash2 size={14} className="mr-2" />
|
||||
Delete
|
||||
|
||||
@@ -176,7 +176,7 @@ function CustomRoadmapItem(props: CustomRoadmapItemProps) {
|
||||
<a
|
||||
href={editorLink}
|
||||
className={
|
||||
'ml-2 flex items-center gap-2 rounded-md border border-gray-300 bg-white px-2.5 py-1.5 text-xs text-black hover:bg-gray-50 focus:outline-none'
|
||||
'ml-2 flex items-center gap-2 rounded-md border border-gray-300 bg-white px-2.5 py-1.5 text-xs text-black hover:bg-gray-50 focus:outline-hidden'
|
||||
}
|
||||
target={'_blank'}
|
||||
>
|
||||
@@ -186,7 +186,7 @@ function CustomRoadmapItem(props: CustomRoadmapItemProps) {
|
||||
<a
|
||||
href={`/r/${roadmap?.slug}`}
|
||||
className={
|
||||
'ml-2 flex items-center gap-2 rounded-md border border-blue-400 bg-white px-2 py-1.5 text-xs text-blue-600 hover:bg-blue-50 focus:outline-none'
|
||||
'ml-2 flex items-center gap-2 rounded-md border border-blue-400 bg-white px-2 py-1.5 text-xs text-blue-600 hover:bg-blue-50 focus:outline-hidden'
|
||||
}
|
||||
target={'_blank'}
|
||||
>
|
||||
|
||||
@@ -231,7 +231,7 @@ export function RateRoadmapForm(props: RateRoadmapFormProps) {
|
||||
</label>
|
||||
<textarea
|
||||
id="rating-feedback"
|
||||
className="min-h-24 rounded-md border p-2 text-sm outline-none focus:border-gray-500"
|
||||
className="min-h-24 rounded-md border p-2 text-sm outline-hidden focus:border-gray-500"
|
||||
placeholder="Share your thoughts with the roadmap creator"
|
||||
value={userFeedback}
|
||||
onChange={(e) => {
|
||||
|
||||
@@ -55,7 +55,7 @@ export function ResourceProgressStats(props: ResourceProgressStatsProps) {
|
||||
className="flex text-sm opacity-0 transition-opacity duration-300"
|
||||
data-progress-nums=""
|
||||
>
|
||||
<span className="mr-2.5 rounded-sm bg-yellow-200 px-1 py-0.5 text-xs font-medium uppercase text-yellow-900">
|
||||
<span className="mr-2.5 rounded-xs bg-yellow-200 px-1 py-0.5 text-xs font-medium uppercase text-yellow-900">
|
||||
<span data-progress-percentage="">0</span>% Done
|
||||
</span>
|
||||
|
||||
|
||||
@@ -32,7 +32,7 @@ export function RoadmapActionButton(props: RoadmapActionButtonProps) {
|
||||
{isOpen && (
|
||||
<div
|
||||
ref={menuRef}
|
||||
className="align-right absolute right-0 top-full z-[9999] mt-1 w-[140px] rounded-md bg-slate-800 px-2 py-2 text-white shadow-md"
|
||||
className="align-right absolute right-0 top-full z-9999 mt-1 w-[140px] rounded-md bg-slate-800 px-2 py-2 text-white shadow-md"
|
||||
>
|
||||
<ul>
|
||||
{onCustomize && (
|
||||
@@ -42,7 +42,7 @@ export function RoadmapActionButton(props: RoadmapActionButtonProps) {
|
||||
setIsOpen(false);
|
||||
onCustomize();
|
||||
}}
|
||||
className="flex w-full cursor-pointer items-center rounded p-2 text-sm font-medium text-slate-100 hover:bg-slate-700"
|
||||
className="flex w-full cursor-pointer items-center rounded-sm p-2 text-sm font-medium text-slate-100 hover:bg-slate-700"
|
||||
>
|
||||
<PenSquare size={14} className="mr-2" />
|
||||
Edit
|
||||
@@ -56,7 +56,7 @@ export function RoadmapActionButton(props: RoadmapActionButtonProps) {
|
||||
setIsOpen(false);
|
||||
onUpdateSharing();
|
||||
}}
|
||||
className="flex w-full cursor-pointer items-center rounded p-2 text-sm font-medium text-slate-100 hover:bg-slate-700"
|
||||
className="flex w-full cursor-pointer items-center rounded-sm p-2 text-sm font-medium text-slate-100 hover:bg-slate-700"
|
||||
>
|
||||
<Lock size={14} className="mr-2" />
|
||||
Sharing
|
||||
@@ -70,7 +70,7 @@ export function RoadmapActionButton(props: RoadmapActionButtonProps) {
|
||||
setIsOpen(false);
|
||||
onDelete();
|
||||
}}
|
||||
className="flex w-full cursor-pointer items-center rounded p-2 text-sm font-medium text-slate-100 hover:bg-slate-700"
|
||||
className="flex w-full cursor-pointer items-center rounded-sm p-2 text-sm font-medium text-slate-100 hover:bg-slate-700"
|
||||
>
|
||||
<Trash2 size={14} className="mr-2" />
|
||||
Delete
|
||||
|
||||
@@ -128,7 +128,7 @@ export function ShareRoadmapModal(props: ShareRoadmapModalProps) {
|
||||
<div className="flex items-center justify-between p-4">
|
||||
<button
|
||||
disabled={isLoading}
|
||||
className="flex h-9 items-center rounded-md border border-gray-200 bg-white px-4 py-2 text-sm font-medium text-black outline-none hover:border-gray-300 hover:bg-gray-50 focus:border-gray-300 focus:bg-gray-100 disabled:cursor-not-allowed disabled:opacity-70"
|
||||
className="flex h-9 items-center rounded-md border border-gray-200 bg-white px-4 py-2 text-sm font-medium text-black outline-hidden hover:border-gray-300 hover:bg-gray-50 focus:border-gray-300 focus:bg-gray-100 disabled:cursor-not-allowed disabled:opacity-70"
|
||||
onClick={onClose}
|
||||
>
|
||||
{isLoading ? (
|
||||
@@ -141,7 +141,7 @@ export function ShareRoadmapModal(props: ShareRoadmapModalProps) {
|
||||
)}
|
||||
</button>
|
||||
<button
|
||||
className="flex h-9 items-center justify-center rounded-md border border-transparent bg-gray-900 px-4 py-2 text-sm font-medium text-white outline-none hover:bg-gray-800 focus:bg-gray-800"
|
||||
className="flex h-9 items-center justify-center rounded-md border border-transparent bg-gray-900 px-4 py-2 text-sm font-medium text-white outline-hidden hover:bg-gray-800 focus:bg-gray-800"
|
||||
onClick={handleCopy}
|
||||
>
|
||||
{isCopied ? (
|
||||
|
||||
@@ -92,7 +92,7 @@ export function SharedRoadmapList(props: SharedRoadmapListProps) {
|
||||
>
|
||||
<a
|
||||
href={`/r/=${roadmap?.slug}`}
|
||||
className="group inline-grid w-full grid-cols-[auto,16px] items-center justify-between gap-2 px-3 py-2 text-sm text-gray-600 transition-colors hover:bg-gray-100 hover:text-black"
|
||||
className="group inline-grid w-full grid-cols-[auto_16px] items-center justify-between gap-2 px-3 py-2 text-sm text-gray-600 transition-colors hover:bg-gray-100 hover:text-black"
|
||||
target={'_blank'}
|
||||
>
|
||||
<span className="w-full truncate">
|
||||
|
||||
@@ -79,7 +79,7 @@ export function SubmitShowcaseWarning(props: SubmitShowcaseWarningProps) {
|
||||
|
||||
<div className="mt-4 grid grid-cols-2 gap-2">
|
||||
<button
|
||||
className="flex-grow cursor-pointer rounded-lg bg-gray-200 py-2 text-center text-sm hover:bg-gray-300"
|
||||
className="grow cursor-pointer rounded-lg bg-gray-200 py-2 text-center text-sm hover:bg-gray-300"
|
||||
onClick={onClose}
|
||||
disabled={submit.isPending}
|
||||
>
|
||||
|
||||
@@ -53,7 +53,7 @@ export function DashboardAiRoadmaps(props: DashboardAiRoadmapsProps) {
|
||||
<a
|
||||
key={roadmap.id}
|
||||
href={`/ai-roadmaps/${roadmap.slug}`}
|
||||
className="relative truncate rounded-md border bg-white p-2.5 text-left text-sm shadow-sm hover:border-gray-400 hover:bg-gray-50"
|
||||
className="relative truncate rounded-md border bg-white p-2.5 text-left text-sm shadow-xs hover:border-gray-400 hover:bg-gray-50"
|
||||
>
|
||||
{roadmap.title}
|
||||
</a>
|
||||
|
||||
@@ -15,7 +15,7 @@ export function DashboardCardLink(props: DashboardCardLinkProps) {
|
||||
return (
|
||||
<a
|
||||
className={cn(
|
||||
'relative mt-4 flex min-h-[220px] flex-col justify-end rounded-lg border border-gray-300 bg-gradient-to-br from-white to-gray-50 py-5 px-6 hover:border-gray-400 hover:from-white hover:to-gray-100',
|
||||
'relative mt-4 flex min-h-[220px] flex-col justify-end rounded-lg border border-gray-300 bg-linear-to-br from-white to-gray-50 py-5 px-6 hover:border-gray-400 hover:from-white hover:to-gray-100',
|
||||
className,
|
||||
)}
|
||||
href={href}
|
||||
|
||||
@@ -36,7 +36,7 @@ export function DashboardCustomProgressCard(props: DashboardCustomProgressCardPr
|
||||
return (
|
||||
<a
|
||||
href={url}
|
||||
className="group relative flex min-h-[80px] w-full flex-col justify-between overflow-hidden rounded-md border bg-white p-3 text-left text-sm shadow-sm transition-all hover:border-gray-400 hover:bg-gray-50"
|
||||
className="group relative flex min-h-[80px] w-full flex-col justify-between overflow-hidden rounded-md border bg-white p-3 text-left text-sm shadow-xs transition-all hover:border-gray-400 hover:bg-gray-50"
|
||||
>
|
||||
<h4 className="truncate font-medium text-gray-900">{resourceTitle}</h4>
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ export function DashboardProgressCard(props: DashboardProgressCardProps) {
|
||||
key={resourceId}
|
||||
className="group relative flex w-full items-center justify-between overflow-hidden rounded-md border border-gray-300 bg-white px-3 py-2 text-left text-sm transition-all hover:border-gray-400"
|
||||
>
|
||||
<span className="flex-grow truncate">{resourceTitle}</span>
|
||||
<span className="grow truncate">{resourceTitle}</span>
|
||||
<span className="text-xs text-gray-400">
|
||||
{parseInt(progressPercentage, 10)}%
|
||||
</span>
|
||||
|
||||
@@ -25,7 +25,7 @@ export function DashboardProjectCard(props: DashboardProjectCardProps) {
|
||||
>
|
||||
<span
|
||||
className={cn(
|
||||
'flex h-5 w-5 flex-shrink-0 items-center justify-center rounded-full',
|
||||
'flex h-5 w-5 shrink-0 items-center justify-center rounded-full',
|
||||
{
|
||||
'border border-green-500 bg-green-500 group-hover:border-green-600 group-hover:bg-green-600':
|
||||
status === 'submitted',
|
||||
@@ -41,8 +41,8 @@ export function DashboardProjectCard(props: DashboardProjectCardProps) {
|
||||
/>
|
||||
)}
|
||||
</span>
|
||||
<span className="flex-grow truncate group-hover:underline">{title.replace(/(System)|(Service)/, '')}</span>
|
||||
<span className="flex-shrink-0 bg-transparent text-xs text-gray-400 no-underline">
|
||||
<span className="grow truncate group-hover:underline">{title.replace(/(System)|(Service)/, '')}</span>
|
||||
<span className="shrink-0 bg-transparent text-xs text-gray-400 no-underline">
|
||||
{!!startedAt &&
|
||||
status === 'started' &&
|
||||
getRelativeTimeString(startedAt)}
|
||||
|
||||
@@ -206,7 +206,7 @@ export function DashboardTeamRoadmaps(props: DashboardTeamRoadmapsProps) {
|
||||
const roadmapHeading = (
|
||||
<div className="mb-3 flex h-[20px] items-center justify-between gap-2 text-xs">
|
||||
<h2 className="uppercase text-gray-400">Roadmaps</h2>
|
||||
<span className="mx-3 h-[1px] flex-grow bg-gray-200" />
|
||||
<span className="mx-3 h-[1px] grow bg-gray-200" />
|
||||
{canManageCurrentTeam && (
|
||||
<a
|
||||
href={`/team/roadmaps?t=${teamId}`}
|
||||
|
||||
@@ -17,7 +17,7 @@ export function EmptyStackMessage(props: EmptyStackMessageProps) {
|
||||
<div className="absolute inset-0 flex items-center justify-center rounded-md bg-black/50">
|
||||
<div
|
||||
className={cn(
|
||||
'flex max-w-[200px] flex-col items-center justify-center rounded-md bg-white p-4 shadow-sm',
|
||||
'flex max-w-[200px] flex-col items-center justify-center rounded-md bg-white p-4 shadow-xs',
|
||||
bodyClassName,
|
||||
)}
|
||||
>
|
||||
|
||||
@@ -392,7 +392,7 @@ export function PersonalDashboard(props: PersonalDashboardProps) {
|
||||
isLoading={isLoading}
|
||||
/>
|
||||
|
||||
<div className="bg-gradient-to-b from-slate-900 to-black pb-12">
|
||||
<div className="bg-linear-to-b from-slate-900 to-black pb-12">
|
||||
<div className="relative mt-6 border-t border-t-[#1e293c] pt-12">
|
||||
<div className="container">
|
||||
<h2
|
||||
|
||||
@@ -67,7 +67,7 @@ function ProgressLane(props: ProgressLaneProps) {
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
'flex h-full flex-col rounded-md border bg-white px-4 py-3 shadow-sm',
|
||||
'flex h-full flex-col rounded-md border bg-white px-4 py-3 shadow-xs',
|
||||
className,
|
||||
)}
|
||||
>
|
||||
@@ -92,7 +92,7 @@ function ProgressLane(props: ProgressLaneProps) {
|
||||
</div>
|
||||
)}
|
||||
|
||||
<div className="mt-4 flex flex-grow flex-col gap-1.5">
|
||||
<div className="mt-4 flex grow flex-col gap-1.5">
|
||||
{isLoading && (
|
||||
<div
|
||||
className={cn('grid grid-cols-2 gap-2', loadingWrapperClassName)}
|
||||
@@ -105,7 +105,7 @@ function ProgressLane(props: ProgressLaneProps) {
|
||||
{!isLoading && children}
|
||||
|
||||
{!isLoading && isEmpty && (
|
||||
<div className="flex flex-grow flex-col items-center justify-center text-gray-500">
|
||||
<div className="flex grow flex-col items-center justify-center text-gray-500">
|
||||
<EmptyIcon
|
||||
size={37}
|
||||
strokeWidth={1.5}
|
||||
@@ -201,7 +201,7 @@ export function ProgressStack(props: ProgressStackProps) {
|
||||
emptyLinkHref={'/roadmaps'}
|
||||
emptyLinkText={'Explore Roadmaps'}
|
||||
>
|
||||
<div className="grid flex-grow auto-rows-min grid-cols-2 items-start gap-2">
|
||||
<div className="grid grow auto-rows-min grid-cols-2 items-start gap-2">
|
||||
{userProgressesToShow.length > 0 && (
|
||||
<>
|
||||
{userProgressesToShow.map((progress) => {
|
||||
@@ -351,7 +351,7 @@ function StatsCard(props: StatsCardProps) {
|
||||
const { title, value, isLoading = false } = props;
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-1 rounded-md border bg-white p-4 shadow-sm">
|
||||
<div className="flex flex-col gap-1 rounded-md border bg-white p-4 shadow-xs">
|
||||
<h3 className="mb-1 text-xs uppercase text-gray-500">{title}</h3>
|
||||
{isLoading ? (
|
||||
<CardSkeleton className="h-8" />
|
||||
|
||||
@@ -111,7 +111,7 @@ export function TeamDashboard(props: TeamDashboardProps) {
|
||||
|
||||
<h2 className="mb-3 mt-6 flex h-[20px] items-center justify-between text-xs uppercase text-gray-400">
|
||||
Team Members
|
||||
<span className="flex-grow h-[1px] bg-gray-200 mx-3" />
|
||||
<span className="grow h-[1px] bg-gray-200 mx-3" />
|
||||
{canManageCurrentTeam && (
|
||||
<a
|
||||
href={`/team/members?t=${teamId}`}
|
||||
|
||||
@@ -10,7 +10,7 @@ import DeleteAccountPopup from "./DeleteAccountPopup.astro";
|
||||
|
||||
<button
|
||||
data-popup='delete-account-popup'
|
||||
class="mt-4 w-full rounded-lg bg-red-600 py-2 text-base font-regular text-white outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-1"
|
||||
class="mt-4 w-full rounded-lg bg-red-600 py-2 text-base font-regular text-white outline-hidden focus:ring-2 focus:ring-red-500 focus:ring-offset-1"
|
||||
>
|
||||
Delete Account
|
||||
</button>
|
||||
@@ -53,7 +53,7 @@ export function DeleteAccountForm() {
|
||||
type="text"
|
||||
name="delete-account"
|
||||
id="delete-account"
|
||||
className="mt-2 block w-full rounded-md border border-gray-300 px-3 py-2 outline-none placeholder:text-gray-400 focus:border-gray-400"
|
||||
className="mt-2 block w-full rounded-md border border-gray-300 px-3 py-2 outline-hidden placeholder:text-gray-400 focus:border-gray-400"
|
||||
placeholder={'Type "delete" to confirm'}
|
||||
required
|
||||
autoFocus
|
||||
@@ -72,14 +72,14 @@ export function DeleteAccountForm() {
|
||||
type="button"
|
||||
disabled={isLoading}
|
||||
onClick={handleClosePopup}
|
||||
className="flex-grow cursor-pointer rounded-lg bg-gray-200 py-2 text-center"
|
||||
className="grow cursor-pointer rounded-lg bg-gray-200 py-2 text-center"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
type="submit"
|
||||
disabled={isLoading || confirmationText.toUpperCase() !== 'DELETE'}
|
||||
className="flex-grow cursor-pointer rounded-lg bg-red-500 py-2 text-white disabled:opacity-40"
|
||||
className="grow cursor-pointer rounded-lg bg-red-500 py-2 text-white disabled:opacity-40"
|
||||
>
|
||||
{isLoading ? 'Please wait ..' : 'Confirm'}
|
||||
</button>
|
||||
|
||||
@@ -73,7 +73,7 @@ export function DeleteTeamPopup(props: DeleteTeamPopupProps) {
|
||||
<div className="relative h-full w-full max-w-md p-4 md:h-auto">
|
||||
<div
|
||||
ref={popupBodyEl}
|
||||
className="popup-body relative rounded-lg bg-white p-4 shadow"
|
||||
className="popup-body relative rounded-lg bg-white p-4 shadow-sm"
|
||||
>
|
||||
<h2 className="text-2xl font-semibold text-black">Delete Team</h2>
|
||||
<p className="text-gray-500">
|
||||
@@ -90,7 +90,7 @@ export function DeleteTeamPopup(props: DeleteTeamPopupProps) {
|
||||
type="text"
|
||||
name="delete-account"
|
||||
id="delete-account"
|
||||
className="mt-2 block w-full rounded-md border border-gray-300 px-3 py-2 outline-none placeholder:text-gray-400 focus:border-gray-400"
|
||||
className="mt-2 block w-full rounded-md border border-gray-300 px-3 py-2 outline-hidden placeholder:text-gray-400 focus:border-gray-400"
|
||||
placeholder={'Type "delete" to confirm'}
|
||||
required
|
||||
autoFocus
|
||||
@@ -111,7 +111,7 @@ export function DeleteTeamPopup(props: DeleteTeamPopupProps) {
|
||||
type="button"
|
||||
disabled={isLoading}
|
||||
onClick={handleClosePopup}
|
||||
className="flex-grow cursor-pointer rounded-lg bg-gray-200 py-2 text-center"
|
||||
className="grow cursor-pointer rounded-lg bg-gray-200 py-2 text-center"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
@@ -120,7 +120,7 @@ export function DeleteTeamPopup(props: DeleteTeamPopupProps) {
|
||||
disabled={
|
||||
isLoading || confirmationText.toUpperCase() !== 'DELETE'
|
||||
}
|
||||
className="flex-grow cursor-pointer rounded-lg bg-red-500 py-2 text-white disabled:opacity-40"
|
||||
className="grow cursor-pointer rounded-lg bg-red-500 py-2 text-white disabled:opacity-40"
|
||||
>
|
||||
{isLoading ? 'Please wait ..' : 'Confirm'}
|
||||
</button>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ArrowDownWideNarrow, Check, ChevronDown } from 'lucide-react';
|
||||
import { Check, ChevronDown } from 'lucide-react';
|
||||
import { useRef, useState } from 'react';
|
||||
import { useOutsideClick } from '../../hooks/use-outside-click';
|
||||
import type { SortByValues } from './DiscoverRoadmaps';
|
||||
@@ -41,11 +41,11 @@ export function DiscoverRoadmapSorting(props: DiscoverRoadmapSortingProps) {
|
||||
|
||||
return (
|
||||
<div
|
||||
className="min-auto relative flex flex-shrink-0 sm:min-w-[140px]"
|
||||
className="min-auto relative flex shrink-0 sm:min-w-[140px]"
|
||||
ref={dropdownRef}
|
||||
>
|
||||
<button
|
||||
className="py-15 flex w-full items-center justify-between gap-2 rounded-md border px-2 text-sm bg-white"
|
||||
className="flex w-full items-center justify-between gap-2 rounded-md border bg-white px-2 text-sm"
|
||||
onClick={() => setIsOpen(!isOpen)}
|
||||
>
|
||||
<span>{selectedValue?.label}</span>
|
||||
@@ -56,7 +56,7 @@ export function DiscoverRoadmapSorting(props: DiscoverRoadmapSortingProps) {
|
||||
</button>
|
||||
|
||||
{isOpen && (
|
||||
<div className="absolute right-0 top-10 z-10 min-w-40 overflow-hidden rounded-md border border-gray-200 bg-white shadow-lg">
|
||||
<div className="absolute top-10 right-0 z-10 min-w-40 overflow-hidden rounded-md border border-gray-200 bg-white shadow-lg">
|
||||
{sortingLabels.map((item) => (
|
||||
<button
|
||||
key={item.value}
|
||||
|
||||
@@ -53,7 +53,7 @@ export function SearchRoadmap(props: SearchRoadmapProps) {
|
||||
type="text"
|
||||
minLength={3}
|
||||
placeholder="Type 3 or more characters to search..."
|
||||
className="w-full rounded-md border border-gray-200 px-3 py-2 pl-9 text-sm transition-colors focus:border-black focus:outline-none"
|
||||
className="w-full rounded-md border border-gray-200 px-3 py-2 pl-9 text-sm transition-colors focus:border-black focus:outline-hidden"
|
||||
value={term}
|
||||
onChange={(e) => setTerm(e.target.value)}
|
||||
/>
|
||||
@@ -64,7 +64,7 @@ export function SearchRoadmap(props: SearchRoadmapProps) {
|
||||
)}
|
||||
</form>
|
||||
{total > 0 && (
|
||||
<p className="hidden flex-shrink-0 text-sm text-gray-500 sm:block">
|
||||
<p className="hidden shrink-0 text-sm text-gray-500 sm:block">
|
||||
{Intl.NumberFormat('en-US', {
|
||||
notation: 'compact',
|
||||
}).format(total)}{' '}
|
||||
|
||||
@@ -35,7 +35,7 @@ export function AIRoadmapsList(props: AIRoadmapsListProps) {
|
||||
className="flex min-h-[95px] flex-col rounded-md border transition-colors hover:bg-gray-100"
|
||||
target={'_blank'}
|
||||
>
|
||||
<h2 className="flex-grow px-2.5 py-2.5 text-base font-medium leading-tight">
|
||||
<h2 className="grow px-2.5 py-2.5 text-base font-medium leading-tight">
|
||||
{roadmap.title}
|
||||
</h2>
|
||||
<div className="flex items-center justify-between gap-2 px-2.5 py-2">
|
||||
|
||||
@@ -46,7 +46,7 @@ export function ExploreAISearch(props: ExploreAISearchProps) {
|
||||
name="search"
|
||||
type="text"
|
||||
placeholder="Type 3 or more characters to search..."
|
||||
className="w-full rounded-md border border-gray-200 px-3 py-2 pl-9 text-sm transition-colors focus:border-black focus:outline-none"
|
||||
className="w-full rounded-md border border-gray-200 px-3 py-2 pl-9 text-sm transition-colors focus:border-black focus:outline-hidden"
|
||||
value={term}
|
||||
onChange={(e) => setTerm(e.target.value)}
|
||||
/>
|
||||
@@ -57,7 +57,7 @@ export function ExploreAISearch(props: ExploreAISearchProps) {
|
||||
)}
|
||||
</div>
|
||||
{total > 0 && (
|
||||
<p className="flex-shrink-0 text-sm text-gray-500 hidden sm:block">
|
||||
<p className="shrink-0 text-sm text-gray-500 hidden sm:block">
|
||||
{Intl.NumberFormat('en-US', {
|
||||
notation: 'compact',
|
||||
}).format(total)}{' '}
|
||||
|
||||
@@ -37,7 +37,7 @@ export function ExploreAISorting(props: ExploreAISortingProps) {
|
||||
|
||||
return (
|
||||
<div
|
||||
className="min-auto relative flex flex-shrink-0 sm:min-w-[140px]"
|
||||
className="min-auto relative flex shrink-0 sm:min-w-[140px]"
|
||||
ref={dropdownRef}
|
||||
>
|
||||
<button
|
||||
|
||||
@@ -33,7 +33,7 @@ export function FeaturedGuideList(props: FeaturedGuidesProps) {
|
||||
|
||||
<a
|
||||
href="/guides"
|
||||
className="hidden rounded-full bg-gradient-to-r from-slate-600 to-black px-3 py-2 text-xs font-medium text-white transition-colors hover:from-blue-600 hover:to-blue-800 sm:inline"
|
||||
className="hidden rounded-full bg-linear-to-r from-slate-600 to-black px-3 py-2 text-xs font-medium text-white transition-colors hover:from-blue-600 hover:to-blue-800 sm:inline"
|
||||
>
|
||||
View All Guides →
|
||||
</a>
|
||||
|
||||
@@ -36,7 +36,7 @@ export function GuideListItem(props: GuideListItemProps) {
|
||||
{frontmatter.title}
|
||||
|
||||
{frontmatter.isNew && (
|
||||
<span className="ml-2.5 rounded-sm bg-green-300 px-1.5 py-0.5 text-xs font-medium uppercase text-green-900">
|
||||
<span className="ml-2.5 rounded-xs bg-green-300 px-1.5 py-0.5 text-xs font-medium uppercase text-green-900">
|
||||
New
|
||||
<span className="hidden sm:inline">
|
||||
·
|
||||
|
||||
@@ -21,7 +21,7 @@ export function FeaturedVideoList(props: FeaturedVideoListProps) {
|
||||
|
||||
<a
|
||||
href="/videos"
|
||||
className="hidden rounded-full bg-gradient-to-r from-slate-600 to-black px-3 py-2 text-xs font-medium text-white transition-colors hover:from-blue-600 hover:to-blue-800 sm:inline"
|
||||
className="hidden rounded-full bg-linear-to-r from-slate-600 to-black px-3 py-2 text-xs font-medium text-white transition-colors hover:from-blue-600 hover:to-blue-800 sm:inline"
|
||||
>
|
||||
View All Videos →
|
||||
</a>
|
||||
|
||||
@@ -17,7 +17,7 @@ export function VideoListItem(props: VideoListItemProps) {
|
||||
{frontmatter.title}
|
||||
|
||||
{frontmatter.isNew && (
|
||||
<span className="bg-green-300 text-green-900 text-xs font-medium px-1.5 py-0.5 rounded-sm uppercase ml-1.5">
|
||||
<span className="bg-green-300 text-green-900 text-xs font-medium px-1.5 py-0.5 rounded-xs uppercase ml-1.5">
|
||||
New
|
||||
<span className="hidden sm:inline">
|
||||
·
|
||||
|
||||
@@ -68,7 +68,7 @@ export function SubmitFeedbackPopup(props: SubmitFeedbackPopupProps) {
|
||||
<div className="relative h-full w-full max-w-md p-4 md:h-auto">
|
||||
<div
|
||||
ref={popupBodyEl}
|
||||
className="popup-body relative rounded-lg bg-white p-4 shadow"
|
||||
className="popup-body relative rounded-lg bg-white p-4 shadow-sm"
|
||||
>
|
||||
{!isSuccess && (
|
||||
<>
|
||||
@@ -84,7 +84,7 @@ export function SubmitFeedbackPopup(props: SubmitFeedbackPopupProps) {
|
||||
ref={inputEl}
|
||||
name="submit-feedback"
|
||||
id="submit-feedback"
|
||||
className="mt-2 block min-h-[150px] w-full resize-none rounded-md border border-gray-300 px-3 py-2 outline-none placeholder:text-gray-400"
|
||||
className="mt-2 block min-h-[150px] w-full resize-none rounded-md border border-gray-300 px-3 py-2 outline-hidden placeholder:text-gray-400"
|
||||
placeholder="Enter your feedback"
|
||||
required
|
||||
autoFocus
|
||||
@@ -105,14 +105,14 @@ export function SubmitFeedbackPopup(props: SubmitFeedbackPopupProps) {
|
||||
type="button"
|
||||
disabled={isLoading}
|
||||
onClick={handleClosePopup}
|
||||
className="flex-grow cursor-pointer rounded-md bg-gray-200 py-2 text-center"
|
||||
className="grow cursor-pointer rounded-md bg-gray-200 py-2 text-center"
|
||||
>
|
||||
Cancel
|
||||
</button>
|
||||
<button
|
||||
disabled={isLoading}
|
||||
type="submit"
|
||||
className="flex-grow cursor-pointer rounded-md bg-black py-2 text-white disabled:opacity-40"
|
||||
className="grow cursor-pointer rounded-md bg-black py-2 text-white disabled:opacity-40"
|
||||
>
|
||||
{isLoading ? 'Please wait ..' : 'Send'}
|
||||
</button>
|
||||
@@ -133,7 +133,7 @@ export function SubmitFeedbackPopup(props: SubmitFeedbackPopupProps) {
|
||||
<button
|
||||
type="button"
|
||||
onClick={handleClosePopup}
|
||||
className="mt-4 w-full flex-grow cursor-pointer rounded-lg bg-black py-2 text-center text-white disabled:opacity-40"
|
||||
className="mt-4 w-full grow cursor-pointer rounded-lg bg-black py-2 text-center text-white disabled:opacity-40"
|
||||
>
|
||||
Close
|
||||
</button>
|
||||
|
||||
@@ -88,7 +88,7 @@ export function ProgressNudge(props: ProgressNudgeProps) {
|
||||
}}
|
||||
className="group relative flex items-center gap-2 rounded-full bg-stone-900 px-3 text-sm text-yellow-400"
|
||||
>
|
||||
<Calendar className="h-4 w-4 flex-shrink-0" strokeWidth={2.5} />
|
||||
<Calendar className="h-4 w-4 shrink-0" strokeWidth={2.5} />
|
||||
</button>
|
||||
)}
|
||||
<button
|
||||
@@ -97,7 +97,7 @@ export function ProgressNudge(props: ProgressNudgeProps) {
|
||||
}}
|
||||
className="group relative flex items-center gap-2 rounded-full bg-stone-900 px-3 text-sm text-yellow-400"
|
||||
>
|
||||
<X className="h-4 w-4 flex-shrink-0" strokeWidth={2.5} />
|
||||
<X className="h-4 w-4 shrink-0" strokeWidth={2.5} />
|
||||
</button>
|
||||
</div>
|
||||
</>
|
||||
|
||||
@@ -28,7 +28,7 @@ export function EmptyFriends(props: EmptyFriendsProps) {
|
||||
}}
|
||||
type="text"
|
||||
value={befriendUrl}
|
||||
className="w-full border-none bg-transparent px-1.5 outline-none"
|
||||
className="w-full border-none bg-transparent px-1.5 outline-hidden"
|
||||
readOnly
|
||||
/>
|
||||
<button
|
||||
|
||||
@@ -98,7 +98,7 @@ export function FriendProgressItem(props: FriendProgressItemProps) {
|
||||
progress?.renderer,
|
||||
)
|
||||
}
|
||||
className="group relative overflow-hidden rounded-md border p-2 hover:border-gray-300 hover:text-black focus:outline-none"
|
||||
className="group relative overflow-hidden rounded-md border p-2 hover:border-gray-300 hover:text-black focus:outline-hidden"
|
||||
key={progress.resourceId}
|
||||
>
|
||||
<span className="relative z-10 flex items-center justify-between text-sm">
|
||||
@@ -186,7 +186,7 @@ export function FriendProgressItem(props: FriendProgressItemProps) {
|
||||
{friend.status === 'rejected' && (
|
||||
<>
|
||||
<div
|
||||
className={'flex w-full flex-grow items-center justify-center'}
|
||||
className={'flex w-full grow items-center justify-center'}
|
||||
>
|
||||
<span className=" flex flex-col items-center text-red-500">
|
||||
<DeleteUserIcon additionalClasses="mr-2 h-8 w-8 mb-1" />
|
||||
@@ -214,7 +214,7 @@ export function FriendProgressItem(props: FriendProgressItemProps) {
|
||||
{friend.status === 'got_rejected' && (
|
||||
<>
|
||||
<div
|
||||
className={'flex w-full flex-grow items-center justify-center'}
|
||||
className={'flex w-full grow items-center justify-center'}
|
||||
>
|
||||
<span className=" flex flex-col items-center text-sm text-red-500">
|
||||
<DeleteUserIcon additionalClasses="mr-2 h-8 w-8 mb-1" />
|
||||
@@ -242,7 +242,7 @@ export function FriendProgressItem(props: FriendProgressItemProps) {
|
||||
{friend.status === 'sent' && (
|
||||
<>
|
||||
<div
|
||||
className={'flex w-full flex-grow items-center justify-center'}
|
||||
className={'flex w-full grow items-center justify-center'}
|
||||
>
|
||||
<span className=" flex flex-col items-center text-green-500">
|
||||
<AddedUserIcon additionalClasses="mr-2 h-8 w-8 mb-1" />
|
||||
@@ -296,7 +296,7 @@ export function FriendProgressItem(props: FriendProgressItemProps) {
|
||||
<>
|
||||
<div
|
||||
className={
|
||||
'flex w-full flex-grow flex-col items-center justify-center px-4'
|
||||
'flex w-full grow flex-col items-center justify-center px-4'
|
||||
}
|
||||
>
|
||||
<AddUserIcon additionalClasses="mr-2 h-8 w-8 mb-1 text-green-500" />
|
||||
|
||||
@@ -27,7 +27,7 @@ export function InviteFriendPopup(props: InviteFriendPopupProps) {
|
||||
<div className="relative h-full w-full max-w-md p-4 md:h-auto">
|
||||
<div
|
||||
ref={popupBodyRef}
|
||||
className="popup-body relative rounded-lg bg-white p-4 shadow"
|
||||
className="popup-body relative rounded-lg bg-white p-4 shadow-sm"
|
||||
>
|
||||
<h3 className="mb-1.5 text-xl font-medium sm:text-2xl">Invite URL</h3>
|
||||
<p className="mb-3 hidden text-sm leading-none text-gray-400 sm:block">
|
||||
@@ -37,7 +37,7 @@ export function InviteFriendPopup(props: InviteFriendPopupProps) {
|
||||
<div className="mt-4 flex flex-col gap-2 sm:mt-4">
|
||||
<input
|
||||
readOnly={true}
|
||||
className="mt-2 block w-full rounded-md border border-gray-300 px-3 py-2 outline-none placeholder:text-gray-400 focus:border-gray-400"
|
||||
className="mt-2 block w-full rounded-md border border-gray-300 px-3 py-2 outline-hidden placeholder:text-gray-400 focus:border-gray-400"
|
||||
value={befriendUrl}
|
||||
onClick={(e: MouseEvent<HTMLInputElement>) => {
|
||||
(e?.target as HTMLInputElement)?.select();
|
||||
|
||||
@@ -72,7 +72,7 @@ export function AICourse(props: AICourseProps) {
|
||||
}
|
||||
|
||||
return (
|
||||
<section className="flex flex-grow flex-col bg-gray-100">
|
||||
<section className="flex grow flex-col bg-gray-100">
|
||||
<div className="container mx-auto flex max-w-3xl flex-col py-24 max-sm:py-4">
|
||||
<h1 className="mb-2.5 text-center text-4xl font-bold max-sm:mb-2 max-sm:text-left max-sm:text-xl">
|
||||
Learn anything with AI
|
||||
@@ -107,7 +107,7 @@ export function AICourse(props: AICourseProps) {
|
||||
onChange={(e) => setKeyword(e.target.value)}
|
||||
onKeyDown={handleKeyDown}
|
||||
placeholder="e.g., Algebra, JavaScript, Photography"
|
||||
className="w-full rounded-md border border-gray-300 bg-white p-3 pl-10 text-gray-900 focus:outline-none focus:ring-1 focus:ring-gray-500 max-sm:placeholder:text-base"
|
||||
className="w-full rounded-md border border-gray-300 bg-white p-3 pl-10 text-gray-900 focus:outline-hidden focus:ring-1 focus:ring-gray-500 max-sm:placeholder:text-base"
|
||||
maxLength={50}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -216,7 +216,7 @@ export function AICourseContent(props: AICourseContentProps) {
|
||||
const isViewingLesson = viewMode === 'module';
|
||||
|
||||
return (
|
||||
<section className="flex h-screen flex-grow flex-col overflow-hidden bg-gray-50">
|
||||
<section className="flex h-screen grow flex-col overflow-hidden bg-gray-50">
|
||||
{modals}
|
||||
|
||||
<div className="border-b border-gray-200 bg-gray-100">
|
||||
@@ -246,7 +246,7 @@ export function AICourseContent(props: AICourseContentProps) {
|
||||
{viewMode === 'module' && (
|
||||
<button
|
||||
onClick={() => setIsAIChatsOpen(!isAIChatsOpen)}
|
||||
className="flex items-center justify-center text-gray-400 shadow-sm transition-colors hover:bg-gray-50 hover:text-gray-900 lg:hidden"
|
||||
className="flex items-center justify-center text-gray-400 shadow-xs transition-colors hover:bg-gray-50 hover:text-gray-900 lg:hidden"
|
||||
>
|
||||
{isAIChatsOpen ? (
|
||||
<MessageCircleOffIcon size={17} strokeWidth={3} />
|
||||
@@ -258,7 +258,7 @@ export function AICourseContent(props: AICourseContentProps) {
|
||||
|
||||
<button
|
||||
onClick={() => setSidebarOpen(!sidebarOpen)}
|
||||
className="flex items-center justify-center text-gray-400 shadow-sm transition-colors hover:bg-gray-50 hover:text-gray-900 lg:hidden"
|
||||
className="flex items-center justify-center text-gray-400 shadow-xs transition-colors hover:bg-gray-50 hover:text-gray-900 lg:hidden"
|
||||
>
|
||||
{sidebarOpen ? (
|
||||
<X size={17} strokeWidth={3} />
|
||||
@@ -272,7 +272,7 @@ export function AICourseContent(props: AICourseContentProps) {
|
||||
<header className="flex items-center justify-between border-b border-gray-200 bg-white px-6 max-lg:py-4 lg:h-[80px]">
|
||||
<div className="flex items-center">
|
||||
<div className="flex flex-col">
|
||||
<h1 className="text-balance text-xl font-bold !leading-tight text-gray-900 max-lg:mb-0.5 max-lg:text-lg">
|
||||
<h1 className="text-balance text-xl font-bold leading-tight! text-gray-900 max-lg:mb-0.5 max-lg:text-lg">
|
||||
{course.title || 'Loading Course...'}
|
||||
</h1>
|
||||
<div className="mt-1 flex flex-row items-center gap-2 text-sm text-gray-600 max-lg:text-xs">
|
||||
@@ -354,7 +354,7 @@ export function AICourseContent(props: AICourseContentProps) {
|
||||
setViewMode('outline');
|
||||
}}
|
||||
className={cn(
|
||||
'flex items-center gap-1 rounded px-2 py-1 text-xs transition-colors',
|
||||
'flex items-center gap-1 rounded-sm px-2 py-1 text-xs transition-colors',
|
||||
viewMode === 'outline'
|
||||
? 'bg-gray-200 text-gray-900'
|
||||
: 'text-gray-600 hover:bg-gray-50',
|
||||
@@ -369,7 +369,7 @@ export function AICourseContent(props: AICourseContentProps) {
|
||||
setViewMode('roadmap');
|
||||
}}
|
||||
className={cn(
|
||||
'flex items-center gap-1 rounded px-2 py-1 text-xs transition-colors',
|
||||
'flex items-center gap-1 rounded-sm px-2 py-1 text-xs transition-colors',
|
||||
viewMode === 'roadmap'
|
||||
? 'bg-gray-200 text-gray-900'
|
||||
: 'text-gray-600 hover:bg-gray-50',
|
||||
@@ -475,7 +475,7 @@ export function AICourseContent(props: AICourseContentProps) {
|
||||
|
||||
{sidebarOpen && (
|
||||
<div
|
||||
className="fixed inset-0 z-10 bg-gray-900 bg-opacity-50 lg:hidden"
|
||||
className="fixed inset-0 z-10 bg-gray-900/50 lg:hidden"
|
||||
onClick={() => setSidebarOpen(false)}
|
||||
></div>
|
||||
)}
|
||||
|
||||
@@ -278,7 +278,7 @@ export function AICourseLesson(props: AICourseLessonProps) {
|
||||
defaultSize={isAIChatsOpen ? 70 : 100}
|
||||
minSize={40}
|
||||
id="course-text-content"
|
||||
className="h-full !overflow-y-scroll bg-white"
|
||||
className="h-full overflow-y-scroll! bg-white"
|
||||
order={1}
|
||||
>
|
||||
<div className="relative mx-auto max-w-5xl">
|
||||
@@ -402,7 +402,7 @@ export function AICourseLesson(props: AICourseLessonProps) {
|
||||
|
||||
{!isLoggedIn() && (
|
||||
<div className="mt-8 flex min-h-[152px] flex-col items-center justify-center gap-3 rounded-lg border border-gray-200 p-8">
|
||||
<LockIcon className="size-7 stroke-[2] text-gray-400/90" />
|
||||
<LockIcon className="size-7 stroke-2 text-gray-400/90" />
|
||||
<p className="text-sm text-gray-500">
|
||||
Please login to generate course content
|
||||
</p>
|
||||
|
||||
@@ -345,7 +345,7 @@ export function AICourseLessonChat(props: AICourseLessonChatProps) {
|
||||
)}
|
||||
<TextareaAutosize
|
||||
className={cn(
|
||||
'h-full min-h-[41px] grow resize-none bg-transparent px-4 py-2 focus:outline-none',
|
||||
'h-full min-h-[41px] grow resize-none bg-transparent px-4 py-2 focus:outline-hidden',
|
||||
isDisabled ? 'cursor-not-allowed opacity-50' : 'cursor-auto',
|
||||
)}
|
||||
placeholder="Ask AI anything about the lesson..."
|
||||
|
||||
@@ -35,7 +35,7 @@ export function AICourseOutlineView(props: AICourseOutlineViewProps) {
|
||||
const aiCourseProgress = course.done || [];
|
||||
|
||||
return (
|
||||
<div className="mx-auto rounded-xl border border-gray-200 bg-white shadow-sm lg:max-w-5xl">
|
||||
<div className="mx-auto rounded-xl border border-gray-200 bg-white shadow-xs lg:max-w-5xl">
|
||||
<AICourseOutlineHeader
|
||||
course={course}
|
||||
isLoading={isLoading}
|
||||
@@ -82,7 +82,7 @@ export function AICourseOutlineView(props: AICourseOutlineViewProps) {
|
||||
{!isCompleted && (
|
||||
<span
|
||||
className={cn(
|
||||
'flex size-6 flex-shrink-0 items-center justify-center rounded-full bg-gray-200 text-sm font-medium text-gray-800 max-lg:size-5 max-lg:text-xs',
|
||||
'flex size-6 shrink-0 items-center justify-center rounded-full bg-gray-200 text-sm font-medium text-gray-800 max-lg:size-5 max-lg:text-xs',
|
||||
)}
|
||||
>
|
||||
{lessonIdx + 1}
|
||||
@@ -90,7 +90,7 @@ export function AICourseOutlineView(props: AICourseOutlineViewProps) {
|
||||
)}
|
||||
|
||||
{isCompleted && (
|
||||
<CheckIcon additionalClasses="size-6 flex-shrink-0 text-green-500" />
|
||||
<CheckIcon additionalClasses="size-6 shrink-0 text-green-500" />
|
||||
)}
|
||||
|
||||
<p className="flex-1 truncate text-base text-gray-800 max-lg:text-sm">
|
||||
|
||||
@@ -206,7 +206,7 @@ export function AICourseRoadmapView(props: AICourseRoadmapViewProps) {
|
||||
);
|
||||
|
||||
return (
|
||||
<div className="relative mx-auto min-h-[500px] rounded-xl border border-gray-200 bg-white shadow-sm lg:max-w-5xl">
|
||||
<div className="relative mx-auto min-h-[500px] rounded-xl border border-gray-200 bg-white shadow-xs lg:max-w-5xl">
|
||||
<AICourseOutlineHeader
|
||||
course={course}
|
||||
isLoading={isLoading}
|
||||
|
||||
@@ -36,7 +36,7 @@ export function AICourseSearch(props: AICourseSearchProps) {
|
||||
</div>
|
||||
<input
|
||||
type="text"
|
||||
className="block w-full rounded-md border border-gray-200 bg-white py-1.5 pl-10 pr-3 leading-5 placeholder-gray-500 focus:border-gray-300 focus:outline-none focus:ring-blue-500 disabled:opacity-70 sm:text-sm"
|
||||
className="block w-full rounded-md border border-gray-200 bg-white py-1.5 pl-10 pr-3 leading-5 placeholder-gray-500 focus:border-gray-300 focus:outline-hidden focus:ring-blue-500 disabled:opacity-70 sm:text-sm"
|
||||
placeholder="Search your courses..."
|
||||
value={searchTerm}
|
||||
onChange={(e) => setSearchTerm(e.target.value)}
|
||||
|
||||
@@ -96,7 +96,7 @@ export function AICourseSidebarModuleList(props: AICourseModuleListProps) {
|
||||
)}
|
||||
>
|
||||
<div className="flex min-w-0 flex-1 items-center gap-2">
|
||||
<div className="flex-shrink-0">
|
||||
<div className="shrink-0">
|
||||
<CircularProgress
|
||||
percentage={percentage}
|
||||
isVisible={!isModuleCompleted}
|
||||
@@ -105,7 +105,7 @@ export function AICourseSidebarModuleList(props: AICourseModuleListProps) {
|
||||
>
|
||||
<span
|
||||
className={cn(
|
||||
'flex size-[21px] flex-shrink-0 items-center justify-center rounded-full bg-gray-400/70 text-xs font-semibold text-white',
|
||||
'flex size-[21px] shrink-0 items-center justify-center rounded-full bg-gray-400/70 text-xs font-semibold text-white',
|
||||
{
|
||||
'bg-black': isActive,
|
||||
'bg-green-600': isModuleCompleted,
|
||||
@@ -114,7 +114,7 @@ export function AICourseSidebarModuleList(props: AICourseModuleListProps) {
|
||||
>
|
||||
{!isModuleCompleted && moduleIdx + 1}
|
||||
{isModuleCompleted && (
|
||||
<Check className="size-3 stroke-[3] text-white" />
|
||||
<Check className="size-3 stroke-3 text-white" />
|
||||
)}
|
||||
</span>
|
||||
</CircularProgress>
|
||||
@@ -125,9 +125,9 @@ export function AICourseSidebarModuleList(props: AICourseModuleListProps) {
|
||||
</div>
|
||||
<div className="ml-auto self-center">
|
||||
{expandedModules[moduleIdx] ? (
|
||||
<ChevronDownIcon size={16} className="flex-shrink-0" />
|
||||
<ChevronDownIcon size={16} className="shrink-0" />
|
||||
) : (
|
||||
<ChevronRightIcon size={16} className="flex-shrink-0" />
|
||||
<ChevronRightIcon size={16} className="shrink-0" />
|
||||
)}
|
||||
</div>
|
||||
</button>
|
||||
@@ -167,7 +167,7 @@ export function AICourseSidebarModuleList(props: AICourseModuleListProps) {
|
||||
{isCompleted ? (
|
||||
<CheckIcon
|
||||
additionalClasses={cn(
|
||||
'size-[18px] relative bg-white rounded-full top-[2px] flex-shrink-0 text-green-600',
|
||||
'size-[18px] relative bg-white rounded-full top-[2px] shrink-0 text-green-600',
|
||||
{
|
||||
'text-black':
|
||||
activeModuleIndex === moduleIdx &&
|
||||
@@ -178,7 +178,7 @@ export function AICourseSidebarModuleList(props: AICourseModuleListProps) {
|
||||
) : (
|
||||
<span
|
||||
className={cn(
|
||||
'flex size-[18px] flex-shrink-0 items-center justify-center rounded-full bg-gray-400/70 text-xs font-semibold text-white',
|
||||
'flex size-[18px] shrink-0 items-center justify-center rounded-full bg-gray-400/70 text-xs font-semibold text-white',
|
||||
{
|
||||
'bg-black':
|
||||
activeModuleIndex === moduleIdx &&
|
||||
|
||||
@@ -15,7 +15,7 @@ export function AIRoadmapViewSwitch(props: AIRoadmapViewSwitchProps) {
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
'grid shrink-0 grid-cols-2 gap-0.5 rounded-md border border-gray-300 bg-white p-0.5 shadow-sm',
|
||||
'grid shrink-0 grid-cols-2 gap-0.5 rounded-md border border-gray-300 bg-white p-0.5 shadow-xs',
|
||||
)}
|
||||
>
|
||||
<SwitchButton
|
||||
@@ -61,7 +61,7 @@ export function SwitchButton(props: SwitchButtonProps) {
|
||||
return (
|
||||
<button
|
||||
className={cn(
|
||||
'flex items-center justify-center gap-1.5 rounded text-sm hover:bg-gray-100 disabled:cursor-not-allowed',
|
||||
'flex items-center justify-center gap-1.5 rounded-sm text-sm hover:bg-gray-100 disabled:cursor-not-allowed',
|
||||
isActive && 'bg-gray-100 text-gray-800',
|
||||
variant === 'text' ? 'px-2 py-1.5' : 'p-[5px]',
|
||||
)}
|
||||
|
||||
@@ -28,7 +28,7 @@ export function CircularProgress(props: CircularProgressProps) {
|
||||
const strokeDashoffset = circumference - (percentage / 100) * circumference;
|
||||
|
||||
return (
|
||||
<div className="relative flex h-[28px] w-[28px] flex-shrink-0 items-center justify-center">
|
||||
<div className="relative flex h-[28px] w-[28px] shrink-0 items-center justify-center">
|
||||
{isVisible && !isLoading && (
|
||||
<svg className="absolute h-full w-full -rotate-90">
|
||||
<circle
|
||||
|
||||
@@ -19,7 +19,7 @@ function Question(props: QuestionProps) {
|
||||
</label>
|
||||
<textarea
|
||||
placeholder={placeholder}
|
||||
className="min-h-[80px] w-full resize-none px-4 py-3 text-gray-700 placeholder:text-gray-400 focus:outline-none"
|
||||
className="min-h-[80px] w-full resize-none px-4 py-3 text-gray-700 placeholder:text-gray-400 focus:outline-hidden"
|
||||
value={value}
|
||||
onChange={(e) => onChange(e.target.value)}
|
||||
autoFocus={autoFocus}
|
||||
@@ -56,7 +56,7 @@ export function FineTuneCourse(props: FineTuneCourseProps) {
|
||||
<div className="flex flex-col overflow-hidden rounded-lg border border-gray-200 transition-all">
|
||||
<label
|
||||
className={cn(
|
||||
'group flex cursor-pointer select-none flex-row items-center gap-2.5 px-4 py-3 text-left text-gray-500 transition-colors hover:bg-gray-100 focus:outline-none',
|
||||
'group flex cursor-pointer select-none flex-row items-center gap-2.5 px-4 py-3 text-left text-gray-500 transition-colors hover:bg-gray-100 focus:outline-hidden',
|
||||
hasFineTuneData && 'bg-gray-100',
|
||||
)}
|
||||
>
|
||||
|
||||
@@ -26,13 +26,13 @@ const ResizableHandle = ({
|
||||
}) => (
|
||||
<ResizablePrimitive.PanelResizeHandle
|
||||
className={cn(
|
||||
'relative flex w-px items-center justify-center bg-gray-200 after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-offset-1 data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:-translate-y-1/2 data-[panel-group-direction=vertical]:after:translate-x-0 [&[data-panel-group-direction=vertical]>div]:rotate-90',
|
||||
'relative flex w-px items-center justify-center bg-gray-200 after:absolute after:inset-y-0 after:left-1/2 after:w-1 after:-translate-x-1/2 focus-visible:outline-hidden focus-visible:ring-1 focus-visible:ring-offset-1 data-[panel-group-direction=vertical]:h-px data-[panel-group-direction=vertical]:w-full data-[panel-group-direction=vertical]:after:left-0 data-[panel-group-direction=vertical]:after:h-1 data-[panel-group-direction=vertical]:after:w-full data-[panel-group-direction=vertical]:after:-translate-y-1/2 data-[panel-group-direction=vertical]:after:translate-x-0 [&[data-panel-group-direction=vertical]>div]:rotate-90',
|
||||
className,
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{withHandle && (
|
||||
<div className="z-10 flex h-[30px] w-3 items-center justify-center rounded-sm bg-gray-200 text-black hover:bg-gray-300">
|
||||
<div className="z-10 flex h-[30px] w-3 items-center justify-center rounded-xs bg-gray-200 text-black hover:bg-gray-300">
|
||||
<GripVertical className="size-5" />
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -120,7 +120,7 @@ export function TestMyKnowledgeAction(props: TestMyKnowledgeActionProps) {
|
||||
<div className="flex items-center gap-2">
|
||||
<button
|
||||
className={cn(
|
||||
'group flex flex-shrink-0 items-center gap-2 rounded-xl border border-gray-200 bg-white px-6 py-3 text-sm font-medium text-gray-700 transition-all hover:border-black hover:bg-gray-50 hover:text-gray-900',
|
||||
'group flex shrink-0 items-center gap-2 rounded-xl border border-gray-200 bg-white px-6 py-3 text-sm font-medium text-gray-700 transition-all hover:border-black hover:bg-gray-50 hover:text-gray-900',
|
||||
{
|
||||
'bg-gray-100 text-gray-900': isKnowledgeTestOpen,
|
||||
},
|
||||
@@ -333,7 +333,7 @@ export function QuizItem(props: QuizItemProps) {
|
||||
},
|
||||
)}
|
||||
>
|
||||
<div className="flex items-center gap-4 rounded-t-xl border-b bg-gradient-to-r from-gray-50 to-white p-5">
|
||||
<div className="flex items-center gap-4 rounded-t-xl border-b bg-linear-to-r from-gray-50 to-white p-5">
|
||||
<span className="text-sm font-medium text-gray-700">
|
||||
Question {counter} of {totalQuestions}
|
||||
</span>
|
||||
@@ -406,14 +406,14 @@ export function QuizItem(props: QuizItemProps) {
|
||||
|
||||
<div className="flex gap-2">
|
||||
<button
|
||||
className="group flex h-10 items-center justify-center gap-1 rounded-lg border border-gray-200 p-2 pr-4 text-sm text-black transition-all hover:border-black hover:bg-black hover:text-white focus:outline-none max-sm:pr-2"
|
||||
className="group flex h-10 items-center justify-center gap-1 rounded-lg border border-gray-200 p-2 pr-4 text-sm text-black transition-all hover:border-black hover:bg-black hover:text-white focus:outline-hidden max-sm:pr-2"
|
||||
onClick={onPrevious}
|
||||
>
|
||||
<ChevronLeftIcon className="size-5 shrink-0 transition-transform group-hover:-translate-x-0.5" />
|
||||
<span className="max-sm:hidden">Previous</span>
|
||||
</button>
|
||||
<button
|
||||
className="group flex h-10 items-center justify-center gap-1 rounded-lg border border-gray-200 p-2 pl-4 text-sm text-black transition-all hover:border-black hover:bg-black hover:text-white focus:outline-none max-sm:pl-2"
|
||||
className="group flex h-10 items-center justify-center gap-1 rounded-lg border border-gray-200 p-2 pl-4 text-sm text-black transition-all hover:border-black hover:bg-black hover:text-white focus:outline-hidden max-sm:pl-2"
|
||||
onClick={onNext}
|
||||
>
|
||||
<span className="max-sm:hidden">Next</span>
|
||||
@@ -424,7 +424,7 @@ export function QuizItem(props: QuizItemProps) {
|
||||
</div>
|
||||
|
||||
{isLoading && (
|
||||
<div className="absolute bg-white right-3 top-3 flex h-8 items-center justify-center gap-1 rounded-lg border border-gray-200 p-2 text-sm text-black hover:bg-black hover:text-white focus:outline-none">
|
||||
<div className="absolute bg-white right-3 top-3 flex h-8 items-center justify-center gap-1 rounded-lg border border-gray-200 p-2 text-sm text-black hover:bg-black hover:text-white focus:outline-hidden">
|
||||
<Loader2Icon className="size-5 animate-spin text-gray-400" />
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -176,7 +176,7 @@ export function AITermSuggestionInput(props: AITermSuggestionInputProps) {
|
||||
type="text"
|
||||
value={defaultValue}
|
||||
className={cn(
|
||||
'w-full rounded-md border border-gray-400 px-3 py-2.5 pr-8 transition-colors focus:border-black focus:outline-none',
|
||||
'w-full rounded-md border border-gray-400 px-3 py-2.5 pr-8 transition-colors focus:border-black focus:outline-hidden',
|
||||
inputClassName,
|
||||
)}
|
||||
placeholder={placeholder}
|
||||
@@ -240,7 +240,7 @@ export function AITermSuggestionInput(props: AITermSuggestionInputProps) {
|
||||
searchResults.length > 0 &&
|
||||
searchedText.length > 0 && (
|
||||
<div
|
||||
className="absolute top-full z-50 mt-1 w-full rounded-md border bg-white p-1 shadow"
|
||||
className="absolute top-full z-50 mt-1 w-full rounded-md border bg-white p-1 shadow-sm"
|
||||
ref={dropdownRef}
|
||||
>
|
||||
<div className="flex flex-col">
|
||||
@@ -250,7 +250,7 @@ export function AITermSuggestionInput(props: AITermSuggestionInputProps) {
|
||||
key={result?._id}
|
||||
type="button"
|
||||
className={cn(
|
||||
'flex w-full items-start rounded p-2 text-left text-sm',
|
||||
'flex w-full items-start rounded-sm p-2 text-left text-sm',
|
||||
counter === activeCounter ? 'bg-gray-100' : '',
|
||||
)}
|
||||
onMouseOver={() => setActiveCounter(counter)}
|
||||
|
||||
@@ -527,7 +527,7 @@ export function GenerateRoadmap(props: GenerateRoadmapProps) {
|
||||
/>
|
||||
)}
|
||||
|
||||
<section className="flex flex-grow flex-col bg-gray-100">
|
||||
<section className="flex grow flex-col bg-gray-100">
|
||||
<div className="flex items-center justify-center border-b bg-white py-3 sm:py-6">
|
||||
{isLoading && (
|
||||
<span className="flex items-center gap-2 rounded-full bg-black px-3 py-1 text-white">
|
||||
@@ -536,7 +536,7 @@ export function GenerateRoadmap(props: GenerateRoadmapProps) {
|
||||
</span>
|
||||
)}
|
||||
{!isLoading && (
|
||||
<div className="container flex flex-grow flex-col items-start">
|
||||
<div className="container flex grow flex-col items-start">
|
||||
<AIRoadmapAlert />
|
||||
{isKeyOnly && isAuthenticatedUser && !isPaidUser && (
|
||||
<div className="flex flex-row gap-4">
|
||||
@@ -601,7 +601,7 @@ export function GenerateRoadmap(props: GenerateRoadmapProps) {
|
||||
<button
|
||||
type={'submit'}
|
||||
className={cn(
|
||||
'flex min-w-[127px] flex-shrink-0 items-center justify-center gap-2 rounded-md bg-black px-4 py-2.5 text-white',
|
||||
'flex min-w-[127px] shrink-0 items-center justify-center gap-2 rounded-md bg-black px-4 py-2.5 text-white',
|
||||
'disabled:cursor-not-allowed disabled:opacity-50',
|
||||
)}
|
||||
onClick={(e) => {
|
||||
@@ -719,7 +719,7 @@ export function GenerateRoadmap(props: GenerateRoadmapProps) {
|
||||
/>
|
||||
{!isAuthenticatedUser && (
|
||||
<div className="absolute bottom-0 left-0 right-0">
|
||||
<div className="h-80 w-full bg-gradient-to-t from-gray-100 to-transparent" />
|
||||
<div className="h-80 w-full bg-linear-to-t from-gray-100 to-transparent" />
|
||||
<div className="bg-gray-100">
|
||||
<div className="mx-auto max-w-[600px] flex-col items-center justify-center bg-gray-100 px-5 pt-px">
|
||||
<div className="mt-8 text-center">
|
||||
|
||||
@@ -48,7 +48,7 @@ export function IncreaseRoadmapLimit(props: IncreaseRoadmapLimitProps) {
|
||||
<label className="mt-4 flex flex-col gap-2">
|
||||
<input
|
||||
ref={inputRef}
|
||||
className="w-full rounded-md border bg-gray-100 p-2 px-2.5 text-gray-700 focus:outline-none"
|
||||
className="w-full rounded-md border bg-gray-100 p-2 px-2.5 text-gray-700 focus:outline-hidden"
|
||||
value={referralLink}
|
||||
readOnly={true}
|
||||
onClick={handleCopy}
|
||||
|
||||
@@ -22,7 +22,7 @@ export function PayToBypass(props: PayToBypassProps) {
|
||||
<div className="p-4">
|
||||
<button
|
||||
onClick={onBack}
|
||||
className="mb-5 flex items-center gap-1.5 text-sm leading-none opacity-40 transition-opacity hover:opacity-100 focus:outline-none"
|
||||
className="mb-5 flex items-center gap-1.5 text-sm leading-none opacity-40 transition-opacity hover:opacity-100 focus:outline-hidden"
|
||||
>
|
||||
<ChevronLeft size={16} />
|
||||
Back to options
|
||||
@@ -46,7 +46,7 @@ export function PayToBypass(props: PayToBypassProps) {
|
||||
id={userId}
|
||||
name={userId}
|
||||
type="text"
|
||||
className="block w-full rounded-lg border border-gray-300 px-3 py-2 shadow-sm outline-none placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
|
||||
className="block w-full rounded-lg border border-gray-300 px-3 py-2 shadow-xs outline-hidden placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
|
||||
value={user?.id}
|
||||
readOnly
|
||||
/>
|
||||
@@ -59,7 +59,7 @@ export function PayToBypass(props: PayToBypassProps) {
|
||||
id={nameId}
|
||||
name={nameId}
|
||||
type="text"
|
||||
className="block w-full rounded-lg border border-gray-300 px-3 py-2 shadow-sm outline-none placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
|
||||
className="block w-full rounded-lg border border-gray-300 px-3 py-2 shadow-xs outline-hidden placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
|
||||
value={user?.name}
|
||||
readOnly
|
||||
/>
|
||||
@@ -72,7 +72,7 @@ export function PayToBypass(props: PayToBypassProps) {
|
||||
id={emailId}
|
||||
name={emailId}
|
||||
type="email"
|
||||
className="block w-full rounded-lg border border-gray-300 px-3 py-2 shadow-sm outline-none placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
|
||||
className="block w-full rounded-lg border border-gray-300 px-3 py-2 shadow-xs outline-hidden placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
|
||||
value={user?.email}
|
||||
readOnly
|
||||
/>
|
||||
@@ -90,7 +90,7 @@ export function PayToBypass(props: PayToBypassProps) {
|
||||
name={amountId}
|
||||
type="text"
|
||||
required
|
||||
className="block w-full rounded-lg border p-3 py-2 shadow-sm outline-none placeholder:text-sm placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
|
||||
className="block w-full rounded-lg border p-3 py-2 shadow-xs outline-hidden placeholder:text-sm placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
|
||||
placeholder="How much are you willing to pay for this?"
|
||||
/>
|
||||
</div>
|
||||
@@ -105,7 +105,7 @@ export function PayToBypass(props: PayToBypassProps) {
|
||||
id={roadmapCountId}
|
||||
name={roadmapCountId}
|
||||
required
|
||||
className="placeholder-text-gray-400 block w-full rounded-lg border border-gray-300 px-3 py-2 shadow-sm outline-none placeholder:text-sm focus:ring-2 focus:ring-black focus:ring-offset-1"
|
||||
className="placeholder-text-gray-400 block w-full rounded-lg border border-gray-300 px-3 py-2 shadow-xs outline-hidden placeholder:text-sm focus:ring-2 focus:ring-black focus:ring-offset-1"
|
||||
placeholder="How many roadmaps you will be generating (daily, or monthly)?"
|
||||
/>
|
||||
</div>
|
||||
@@ -117,7 +117,7 @@ export function PayToBypass(props: PayToBypassProps) {
|
||||
id={usageId}
|
||||
name={usageId}
|
||||
required
|
||||
className="placeholder-text-gray-400 block w-full rounded-lg border border-gray-300 px-3 py-2 shadow-sm outline-none placeholder:text-sm focus:ring-2 focus:ring-black focus:ring-offset-1"
|
||||
className="placeholder-text-gray-400 block w-full rounded-lg border border-gray-300 px-3 py-2 shadow-xs outline-hidden placeholder:text-sm focus:ring-2 focus:ring-black focus:ring-offset-1"
|
||||
placeholder="How will you be using this"
|
||||
/>
|
||||
</div>
|
||||
@@ -131,7 +131,7 @@ export function PayToBypass(props: PayToBypassProps) {
|
||||
<textarea
|
||||
id={feedbackId}
|
||||
name={feedbackId}
|
||||
className="placeholder-text-gray-400 block w-full rounded-lg border border-gray-300 px-3 py-2 shadow-sm outline-none placeholder:text-sm focus:ring-2 focus:ring-black focus:ring-offset-1"
|
||||
className="placeholder-text-gray-400 block w-full rounded-lg border border-gray-300 px-3 py-2 shadow-xs outline-hidden placeholder:text-sm focus:ring-2 focus:ring-black focus:ring-offset-1"
|
||||
placeholder="Do you have any feedback?"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -41,7 +41,7 @@ export function ReferYourFriend(props: ReferYourFriendProps) {
|
||||
<label className="mt-4 flex flex-col gap-2">
|
||||
<input
|
||||
ref={inputRef}
|
||||
className="w-full rounded-md border bg-gray-100 p-2 px-2.5 text-gray-700 focus:outline-none"
|
||||
className="w-full rounded-md border bg-gray-100 p-2 px-2.5 text-gray-700 focus:outline-hidden"
|
||||
value={referralLink}
|
||||
readOnly={true}
|
||||
onClick={handleCopy}
|
||||
|
||||
@@ -44,7 +44,7 @@ export function RoadmapSearch(props: RoadmapSearchProps) {
|
||||
const randomTerms = ['OAuth', 'UI / UX', 'SRE', 'DevRel'];
|
||||
|
||||
return (
|
||||
<div className="flex flex-grow flex-col items-center px-4 py-6 sm:px-6 md:my-24 lg:my-32">
|
||||
<div className="flex grow flex-col items-center px-4 py-6 sm:px-6 md:my-24 lg:my-32">
|
||||
{isConfiguring && (
|
||||
<UpgradeAccountModal
|
||||
onClose={() => {
|
||||
@@ -90,7 +90,7 @@ export function RoadmapSearch(props: RoadmapSearchProps) {
|
||||
/>
|
||||
<button
|
||||
className={cn(
|
||||
'flex min-w-[154px] flex-shrink-0 items-center justify-center gap-2 rounded-md bg-black px-4 py-2 text-white',
|
||||
'flex min-w-[154px] shrink-0 items-center justify-center gap-2 rounded-md bg-black px-4 py-2 text-white',
|
||||
'disabled:cursor-not-allowed disabled:opacity-50',
|
||||
)}
|
||||
onClick={(e) => {
|
||||
|
||||
@@ -128,7 +128,7 @@ export function RoadmapTopicDetail(props: RoadmapTopicDetailProps) {
|
||||
const hasContent = topicHtml?.length > 0;
|
||||
|
||||
return (
|
||||
<div className={'relative z-[92]'}>
|
||||
<div className={'relative z-92'}>
|
||||
<div
|
||||
ref={topicRef}
|
||||
tabIndex={0}
|
||||
@@ -246,7 +246,7 @@ export function RoadmapTopicDetail(props: RoadmapTopicDetailProps) {
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
<div className="fixed inset-0 z-30 bg-gray-900 bg-opacity-50 dark:bg-opacity-80"></div>
|
||||
<div className="fixed inset-0 z-30 bg-gray-900/50"></div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -20,7 +20,7 @@ export function RoadmapCard(props: RoadmapCardProps) {
|
||||
|
||||
if (isUpcoming) {
|
||||
return (
|
||||
<div className="group relative block rounded-xl border border-gray-300 bg-gradient-to-br from-gray-100 to-gray-50 p-5 overflow-hidden">
|
||||
<div className="group relative block rounded-xl border border-gray-300 bg-linear-to-br from-gray-100 to-gray-50 p-5 overflow-hidden">
|
||||
<div className="mb-2 sm:mb-5 flex flex-row items-center">
|
||||
<div className="flex h-7 w-7 sm:h-9 sm:w-9 items-center justify-center rounded-full bg-gray-900 text-white">
|
||||
<Icon className="h-3 sm:h-5" />
|
||||
@@ -52,8 +52,8 @@ export function RoadmapCard(props: RoadmapCardProps) {
|
||||
<a
|
||||
href={link}
|
||||
target={'_blank'}
|
||||
className="group relative block rounded-xl border border-gray-300 bg-gradient-to-br from-gray-100 to-gray-50
|
||||
p-3.5 sm:p-5 transition-colors duration-200 ease-in-out hover:cursor-pointer hover:border-black/30 hover:bg-gray-50/70 hover:shadow-sm"
|
||||
className="group relative block rounded-xl border border-gray-300 bg-linear-to-br from-gray-100 to-gray-50
|
||||
p-3.5 sm:p-5 transition-colors duration-200 ease-in-out hover:cursor-pointer hover:border-black/30 hover:bg-gray-50/70 hover:shadow-xs"
|
||||
>
|
||||
<div className="mb-2 sm:mb-5 flex flex-row items-center">
|
||||
<div className="flex h-7 w-7 sm:h-9 sm:w-9 items-center justify-center rounded-full bg-gray-900 text-white">
|
||||
|
||||
@@ -16,7 +16,7 @@ export function RoadmapMultiCard(props: RoadmapMultiCardProps) {
|
||||
const { roadmaps, description, secondaryRoadmaps, secondaryDescription } = props;
|
||||
return (
|
||||
<div
|
||||
className="relative flex flex-col overflow-hidden rounded-xl border border-gray-300 bg-gradient-to-br from-gray-100
|
||||
className="relative flex flex-col overflow-hidden rounded-xl border border-gray-300 bg-linear-to-br from-gray-100
|
||||
to-gray-50 ease-in-out"
|
||||
>
|
||||
<div className="flex flex-col divide-y">
|
||||
@@ -25,7 +25,7 @@ export function RoadmapMultiCard(props: RoadmapMultiCardProps) {
|
||||
target={'_blank'}
|
||||
key={index}
|
||||
href={roadmap.link}
|
||||
className="group text-sm sm:text-base flex w-full items-center justify-between gap-2 bg-gradient-to-br from-gray-100 to-gray-50 px-4 sm:px-5 py-2 transition-colors duration-200"
|
||||
className="group text-sm sm:text-base flex w-full items-center justify-between gap-2 bg-linear-to-br from-gray-100 to-gray-50 px-4 sm:px-5 py-2 transition-colors duration-200"
|
||||
>
|
||||
{roadmap.title}
|
||||
<ExternalLink className="lucide lucide-external-link h-4 text-gray-300 transition group-hover:text-gray-700" />
|
||||
@@ -33,7 +33,7 @@ export function RoadmapMultiCard(props: RoadmapMultiCardProps) {
|
||||
))}
|
||||
</div>
|
||||
|
||||
<p className="flex-grow bg-gray-200/70 p-4 sm:p-5 text-sm text-gray-500">
|
||||
<p className="grow bg-gray-200/70 p-4 sm:p-5 text-sm text-gray-500">
|
||||
{description}
|
||||
</p>
|
||||
|
||||
@@ -44,7 +44,7 @@ export function RoadmapMultiCard(props: RoadmapMultiCardProps) {
|
||||
target={'_blank'}
|
||||
key={index}
|
||||
href={roadmap.link}
|
||||
className="group text-sm sm:text-base flex w-full items-center justify-between gap-2 bg-gradient-to-br from-gray-100 to-gray-50 px-5 py-2 transition-colors duration-200"
|
||||
className="group text-sm sm:text-base flex w-full items-center justify-between gap-2 bg-linear-to-br from-gray-100 to-gray-50 px-5 py-2 transition-colors duration-200"
|
||||
>
|
||||
{roadmap.title}
|
||||
<ExternalLink className="lucide lucide-external-link h-4 text-gray-300 transition group-hover:text-gray-700" />
|
||||
@@ -54,7 +54,7 @@ export function RoadmapMultiCard(props: RoadmapMultiCardProps) {
|
||||
)}
|
||||
|
||||
{secondaryDescription && (
|
||||
<p className="flex-grow bg-gray-200/70 p-4 sm:p-5 text-sm text-gray-500">
|
||||
<p className="grow bg-gray-200/70 p-4 sm:p-5 text-sm text-gray-500">
|
||||
{secondaryDescription}
|
||||
</p>
|
||||
)}
|
||||
|
||||
@@ -12,7 +12,7 @@ export function RoleRoadmaps(props: RoleRoadmapsProps) {
|
||||
const { badge, title, description, children } = props;
|
||||
|
||||
return (
|
||||
<div className="bg-gradient-to-b from-gray-100 to-white py-5 sm:py-8 md:py-12">
|
||||
<div className="bg-linear-to-b from-gray-100 to-white py-5 sm:py-8 md:py-12">
|
||||
<div className="container">
|
||||
<div className="text-left">
|
||||
<SectionBadge title={badge} />
|
||||
|
||||
@@ -27,7 +27,7 @@ const { url, title, description, isNew } = Astro.props;
|
||||
|
||||
{
|
||||
isNew && (
|
||||
<span class='flex items-center gap-1.5 absolute bottom-1.5 right-1 rounded-sm text-xs font-semibold uppercase text-purple-500 sm:px-1.5'>
|
||||
<span class='flex items-center gap-1.5 absolute bottom-1.5 right-1 rounded-xs text-xs font-semibold uppercase text-purple-500 sm:px-1.5'>
|
||||
<span class='relative flex h-2 w-2'>
|
||||
<span class='absolute inline-flex h-full w-full animate-ping rounded-full bg-purple-400 opacity-75' />
|
||||
<span class='relative inline-flex h-2 w-2 rounded-full bg-purple-500' />
|
||||
|
||||
@@ -22,7 +22,7 @@ const { frontmatter: guideFrontmatter, author } = guide;
|
||||
<article class='lg:grid lg:max-w-full lg:grid-cols-[1fr_minmax(0,700px)_1fr]'>
|
||||
{
|
||||
(showTableOfContent || showRelatedGuides) && (
|
||||
<div class='sticky top-0 lg:relative bg-gradient-to-r from-gray-50 py-0 lg:col-start-3 lg:col-end-4 lg:row-start-1'>
|
||||
<div class='sticky top-0 lg:relative bg-linear-to-r from-gray-50 py-0 lg:col-start-3 lg:col-end-4 lg:row-start-1'>
|
||||
<RelatedGuides
|
||||
relatedTitle={guideFrontmatter?.relatedTitle}
|
||||
relatedGuides={guide?.relatedGuides || {}}
|
||||
|
||||
@@ -42,7 +42,7 @@ export function RelatedGuides(props: RelatedGuidesProps) {
|
||||
|
||||
<ol
|
||||
className={cn(
|
||||
'mt-0.5 space-y-0 max-lg:absolute max-lg:top-full max-lg:z-10 max-lg:mt-0 max-lg:w-full max-lg:bg-white max-lg:shadow',
|
||||
'mt-0.5 space-y-0 max-lg:absolute max-lg:top-full max-lg:z-10 max-lg:mt-0 max-lg:w-full max-lg:bg-white max-lg:shadow-sm',
|
||||
!isOpen && 'hidden lg:block',
|
||||
isOpen && 'block',
|
||||
)}
|
||||
|
||||
@@ -21,7 +21,7 @@ export function HeroProject({ project }: HeroProjectProps) {
|
||||
</h3>
|
||||
<span
|
||||
className={cn(
|
||||
'absolute -right-2 -top-2 flex flex-shrink-0 items-center gap-1 rounded-full text-xs uppercase tracking-wide',
|
||||
'absolute -right-2 -top-2 flex shrink-0 items-center gap-1 rounded-full text-xs uppercase tracking-wide',
|
||||
{
|
||||
'text-green-600/50': project.submittedAt && project.repositoryUrl,
|
||||
'text-yellow-600': !project.submittedAt || !project.repositoryUrl,
|
||||
@@ -43,9 +43,9 @@ export function HeroProject({ project }: HeroProjectProps) {
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="absolute inset-0 rounded-md bg-gradient-to-br from-slate-800/50 via-transparent to-transparent" />
|
||||
<div className="absolute inset-0 rounded-md bg-linear-to-br from-slate-800/50 via-transparent to-transparent" />
|
||||
{project.submittedAt && project.repositoryUrl && (
|
||||
<div className="absolute inset-0 rounded-md bg-gradient-to-br from-green-950/20 via-transparent to-transparent" />
|
||||
<div className="absolute inset-0 rounded-md bg-linear-to-br from-green-950/20 via-transparent to-transparent" />
|
||||
)}
|
||||
</a>
|
||||
);
|
||||
|
||||
@@ -14,7 +14,7 @@ import { FeatureAnnouncement } from "../FeatureAnnouncement";
|
||||
</p>
|
||||
|
||||
<h1
|
||||
class='mb-2 bg-gradient-to-b from-amber-50 to-purple-500 bg-clip-text text-2xl font-bold text-transparent sm:mb-4 sm:text-5xl sm:leading-tight'
|
||||
class='mb-2 bg-linear-to-b from-amber-50 to-purple-500 bg-clip-text text-2xl font-bold text-transparent sm:mb-4 sm:text-5xl sm:leading-tight'
|
||||
>
|
||||
Developer Roadmaps
|
||||
</h1>
|
||||
|
||||
@@ -112,7 +112,7 @@ function LeaderboardLane(props: LeaderboardLaneProps) {
|
||||
const { users: usersToShow, emptyIcon, emptyText } = activeTab;
|
||||
|
||||
return (
|
||||
<div className="flex min-h-[450px] flex-col overflow-hidden rounded-xl border bg-white shadow-sm">
|
||||
<div className="flex min-h-[450px] flex-col overflow-hidden rounded-xl border bg-white shadow-xs">
|
||||
<div className="mb-3 flex items-center justify-between gap-2 px-3 py-3">
|
||||
<h3 className="text-sm font-medium">
|
||||
{title}{' '}
|
||||
@@ -149,7 +149,7 @@ function LeaderboardLane(props: LeaderboardLaneProps) {
|
||||
</div>
|
||||
|
||||
{usersToShow.length === 0 && emptyText && (
|
||||
<div className="flex flex-grow flex-col items-center justify-center p-8">
|
||||
<div className="flex grow flex-col items-center justify-center p-8">
|
||||
{emptyIcon}
|
||||
<p className="mt-4 text-sm text-gray-500">{emptyText}</p>
|
||||
</div>
|
||||
|
||||
@@ -8,7 +8,7 @@ const { class: className } = Astro.props;
|
||||
|
||||
<div
|
||||
class:list={[
|
||||
'container prose prose-xl prose-h2:mb-3 prose-h2:mt-10 prose-h2:scroll-mt-5 prose-h2:text-balance prose-h2:text-3xl prose-h3:mt-2 prose-h4:text-2xl prose-h3:scroll-mt-5 prose-h3:text-balance prose-h4:text-balance prose-h5:text-balance prose-h5:font-medium prose-blockquote:font-normal prose-code:bg-transparent prose-img:mt-1 prose-h2:sm:scroll-mt-10 prose-h3:sm:scroll-mt-10',
|
||||
'container prose prose-xl prose-h2:mb-3 prose-h2:mt-10 prose-h2:scroll-mt-5 prose-h2:text-balance prose-h2:text-3xl prose-h3:mt-2 prose-h4:text-2xl prose-h3:scroll-mt-5 prose-h3:text-balance prose-h4:text-balance prose-h5:text-balance prose-h5:font-medium prose-blockquote:font-normal prose-code:bg-transparent prose-img:mt-1 sm:prose-h2:scroll-mt-10 sm:prose-h3:scroll-mt-10',
|
||||
className,
|
||||
]}
|
||||
>
|
||||
|
||||
Loaded 100 of 239 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user