feat: migrate tailwind to v4

This commit is contained in:
swve 2025-03-10 13:26:53 +01:00
parent 6d770698d0
commit 81c4190b00
87 changed files with 773 additions and 620 deletions

View file

@ -86,7 +86,7 @@ function AIEditorToolkit(props: AIEditorToolkitProps) {
background:
'linear-gradient(0deg, rgba(0, 0, 0, 0.2) 0%, rgba(0, 0, 0, 0.2) 100%), radial-gradient(105.16% 105.16% at 50% -5.16%, rgba(255, 255, 255, 0.18) 0%, rgba(0, 0, 0, 0) 100%), rgb(2 1 25 / 98%)',
}}
className="z-50 rounded-2xl max-w-screen-2xl my-10 mx-auto w-fit fixed bottom-0 left-1/2 transform -translate-x-1/2 shadow-xl ring-1 ring-inset ring-white/10 text-white p-3 flex-col-reverse backdrop-blur-md"
className="z-50 rounded-2xl max-w-(--breakpoint-2xl) my-10 mx-auto w-fit fixed bottom-0 left-1/2 transform -translate-x-1/2 shadow-xl ring-1 ring-inset ring-white/10 text-white p-3 flex-col-reverse backdrop-blur-md"
>
<div className="flex space-x-2">
<div className="pr-1">
@ -447,7 +447,7 @@ const UserFeedbackModal = (props: AIEditorToolkitProps) => {
background:
'linear-gradient(0deg, rgba(0, 0, 0, 0.2) 0%, rgba(0, 0, 0, 0.2) 100%), radial-gradient(105.16% 105.16% at 50% -5.16%, rgba(255, 255, 255, 0.18) 0%, rgba(0, 0, 0, 0) 100%), rgb(2 1 25 / 95%)',
}}
className="backdrop-blur-md z-50 rounded-2xl max-w-screen-2xl my-10 mx-auto w-[500px] h-[200px] fixed bottom-16 left-1/2 transform -translate-x-1/2 shadow-xl ring-1 ring-inset ring-white/10 text-white p-3 flex-col-reverse"
className="backdrop-blur-md z-50 rounded-2xl max-w-(--breakpoint-2xl) my-10 mx-auto w-[500px] h-[200px] fixed bottom-16 left-1/2 transform -translate-x-1/2 shadow-xl ring-1 ring-inset ring-white/10 text-white p-3 flex-col-reverse"
>
<div className="flex space-x-2 justify-center">
<Image
@ -469,7 +469,7 @@ const UserFeedbackModal = (props: AIEditorToolkitProps) => {
value={aiEditorState.chatInputValue}
onChange={handleChange}
placeholder="Ask AI"
className="ring-1 ring-inset ring-white/20 w-full bg-gray-950/20 rounded-lg outline-none px-4 py-2 text-white text-sm placeholder:text-white/30"
className="ring-1 ring-inset ring-white/20 w-full bg-gray-950/20 rounded-lg outline-hidden px-4 py-2 text-white text-sm placeholder:text-white/30"
></input>
<div
onClick={() =>
@ -620,7 +620,7 @@ const AiEditorActionScreen = ({
value={aiEditorState.chatInputValue}
onChange={handleChange}
placeholder="Japanese, Arabic, German, etc. "
className="ring-1 ring-inset ring-white/20 w-full bg-gray-950/20 rounded-lg outline-none px-4 py- text-white text-sm placeholder:text-white/30"
className="ring-1 ring-inset ring-white/20 w-full bg-gray-950/20 rounded-lg outline-hidden px-4 py- text-white text-sm placeholder:text-white/30"
></input>
</div>
<div

View file

@ -182,7 +182,7 @@ function Editor(props: Editor) {
}}
exit={{ opacity: 0 }}
>
<EditorTop className="fixed bg-white bg-opacity-95 backdrop-blur backdrop-brightness-125">
<EditorTop className="fixed bg-white bg-opacity-95 backdrop-blur-sm backdrop-brightness-125">
<EditorDocSection>
<EditorInfoWrapper>
<Link href="/">
@ -254,7 +254,7 @@ function Editor(props: Editor) {
/>
<EditorLeftOptionsSection className="space-x-2 ">
<div
className="bg-sky-600 hover:bg-sky-700 transition-all ease-linear px-3 py-2 font-black text-sm shadow text-teal-100 rounded-lg hover:cursor-pointer"
className="bg-sky-600 hover:bg-sky-700 transition-all ease-linear px-3 py-2 font-black text-sm shadow-sm text-teal-100 rounded-lg hover:cursor-pointer"
onClick={() => props.setContent(editor.getJSON())}
>
{' '}
@ -265,7 +265,7 @@ function Editor(props: Editor) {
target="_blank"
href={`/course/${course_uuid}/activity/${activity_uuid}`}
>
<div className="flex bg-neutral-600 hover:bg-neutral-700 transition-all ease-linear h-9 px-3 py-2 font-black justify-center items-center text-sm shadow text-neutral-100 rounded-lg hover:cursor-pointer">
<div className="flex bg-neutral-600 hover:bg-neutral-700 transition-all ease-linear h-9 px-3 py-2 font-black justify-center items-center text-sm shadow-sm text-neutral-100 rounded-lg hover:cursor-pointer">
<Eye className="mx-auto items-center" size={15} />
</div>
</Link>

View file

@ -164,7 +164,7 @@ const BadgesExtension: React.FC = (props: any) => {
{colors.map((c) => (
<button
key={c}
className={`w-8 h-8 rounded-full ${getBadgeColor(c)} hover:ring-2 hover:ring-opacity-50 focus:outline-none focus:ring-2 focus:ring-opacity-50`}
className={`w-8 h-8 rounded-full ${getBadgeColor(c)} hover:ring-2 hover:ring-opacity-50 focus:outline-hidden focus:ring-2 focus:ring-opacity-50`}
onClick={() => handleColorSelect(c)}
/>
))}

View file

@ -154,7 +154,7 @@ const ButtonsExtension: React.FC = (props: any) => {
{colors.map((c) => (
<button
key={c}
className={`w-6 h-6 rounded-full ${getButtonColor(c)} hover:ring-2 hover:ring-opacity-50 focus:outline-none focus:ring-2 focus:ring-opacity-50`}
className={`w-6 h-6 rounded-full ${getButtonColor(c)} hover:ring-2 hover:ring-opacity-50 focus:outline-hidden focus:ring-2 focus:ring-opacity-50`}
onClick={() => handleColorSelect(c)}
/>
))}

View file

@ -14,7 +14,7 @@ const IconWrapper = styled.div<{ size?: string }>`
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
shrink: 0;
margin-right: 0.5rem;
padding-left: 0.5rem;
@ -126,7 +126,7 @@ function InfoCalloutComponent(props: any) {
<IconWrapper size={options.size}>
<AlertCircle />
</IconWrapper>
<ContentWrapper className="flex-grow">
<ContentWrapper className="grow">
<NodeViewContent contentEditable={isEditable} className="content" />
</ContentWrapper>
{options.dismissible && !isEditable && (

View file

@ -14,7 +14,7 @@ const IconWrapper = styled.div<{ size?: string }>`
display: flex;
align-items: center;
justify-content: center;
flex-shrink: 0;
shrink: 0;
margin-right: 0.5rem;
padding-left: 0.5rem;
@ -126,7 +126,7 @@ function WarningCalloutComponent(props: any) {
<IconWrapper size={options.size}>
<AlertTriangle />
</IconWrapper>
<ContentWrapper className="flex-grow">
<ContentWrapper className="grow">
<NodeViewContent contentEditable={isEditable} className="content" />
</ContentWrapper>
{options.dismissible && !isEditable && (

View file

@ -417,7 +417,7 @@ function EmbedObjectsComponent(props: any) {
{/* Minimal toolbar for existing embeds */}
{isEditable && (
<div className="absolute top-2 right-2 flex items-center gap-1.5 bg-white bg-opacity-90 backdrop-blur-sm rounded-lg p-1 shadow-sm transition-opacity opacity-70 hover:opacity-100">
<div className="absolute top-2 right-2 flex items-center gap-1.5 bg-white bg-opacity-90 backdrop-blur-xs rounded-lg p-1 shadow-xs transition-opacity opacity-70 hover:opacity-100">
<button
onClick={() => setActiveInput(embedType)}
className="p-1.5 rounded-md hover:bg-gray-100 text-gray-600"
@ -487,7 +487,7 @@ function EmbedObjectsComponent(props: any) {
setEmbedType('url');
setActiveInput('url');
}}
className="flex items-center gap-1.5 px-3 py-1.5 bg-white rounded-lg shadow-sm hover:shadow-md transition-all text-sm text-gray-700"
className="flex items-center gap-1.5 px-3 py-1.5 bg-white rounded-lg shadow-xs hover:shadow-md transition-all text-sm text-gray-700"
>
<LinkIcon size={14} />
<span>URL</span>
@ -497,7 +497,7 @@ function EmbedObjectsComponent(props: any) {
setEmbedType('code');
setActiveInput('code');
}}
className="flex items-center gap-1.5 px-3 py-1.5 bg-white rounded-lg shadow-sm hover:shadow-md transition-all text-sm text-gray-700"
className="flex items-center gap-1.5 px-3 py-1.5 bg-white rounded-lg shadow-xs hover:shadow-md transition-all text-sm text-gray-700"
>
<Code size={14} />
<span>Code</span>
@ -509,7 +509,7 @@ function EmbedObjectsComponent(props: any) {
{/* Inline input UI - appears in place without covering content */}
{isEditable && activeInput !== 'none' && (
<div className="absolute inset-0 bg-gray-100 bg-opacity-95 backdrop-blur-sm flex items-center justify-center p-4 z-10">
<div className="absolute inset-0 bg-gray-100 bg-opacity-95 backdrop-blur-xs flex items-center justify-center p-4 z-10">
<form
onSubmit={handleInputSubmit}
className="w-full max-w-lg bg-white rounded-xl shadow-lg p-4"
@ -554,7 +554,7 @@ function EmbedObjectsComponent(props: any) {
type="text"
value={embedUrl}
onChange={handleUrlChange}
className="w-full pl-10 pr-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-blue-500 focus:outline-none transition-all"
className="w-full pl-10 pr-4 py-2.5 bg-gray-50 border border-gray-200 rounded-xl focus:ring-2 focus:ring-blue-500 focus:border-blue-500 focus:outline-hidden transition-all"
placeholder={selectedProduct ? `Paste ${selectedProduct.name} embed URL` : "Paste embed URL (YouTube, Spotify, etc.)"}
autoFocus
/>
@ -586,7 +586,7 @@ function EmbedObjectsComponent(props: any) {
ref={codeInputRef}
value={embedCode}
onChange={handleCodeChange}
className="w-full p-3 bg-gray-50 border border-gray-200 rounded-xl h-32 focus:ring-2 focus:ring-blue-500 focus:border-blue-500 focus:outline-none transition-all font-mono text-sm"
className="w-full p-3 bg-gray-50 border border-gray-200 rounded-xl h-32 focus:ring-2 focus:ring-blue-500 focus:border-blue-500 focus:outline-hidden transition-all font-mono text-sm"
placeholder="Paste embed code (iframe, embed script, etc.)"
autoFocus
/>

View file

@ -110,7 +110,7 @@ function ImageBlockComponent(props: any) {
'imageBlock'
)}`}
alt=""
className="rounded-lg shadow max-w-full h-auto"
className="rounded-lg shadow-sm max-w-full h-auto"
style={{ width: '100%' }}
/>
</Resizable>
@ -129,7 +129,7 @@ function ImageBlockComponent(props: any) {
'imageBlock'
)}`}
alt=""
className="rounded-lg shadow max-w-full h-auto"
className="rounded-lg shadow-sm max-w-full h-auto"
style={{ width: imageSize.width, maxWidth: '100%' }}
/>
</div>

View file

@ -59,7 +59,7 @@ function PDFBlockComponent(props: any) {
{blockObject && (
<BlockPDF>
<iframe
className="shadow rounded-lg h-96 w-full object-scale-down bg-black"
className="shadow-sm rounded-lg h-96 w-full object-scale-down bg-black"
src={`${getActivityBlockMediaDirectory(
org?.org_uuid,
course?.courseStructure.course_uuid,

View file

@ -275,7 +275,7 @@ function QuizBlockComponent(props: any) {
<div key={question.question_id} className="pt-3 space-y-2">
<div className="question">
<div className="flex space-x-2 items-center">
<div className="flex-grow">
<div className="grow">
{isEditable ? (
<input
value={question.question}
@ -310,7 +310,7 @@ function QuizBlockComponent(props: any) {
<div
key={answer.answer_id}
className={twMerge(
'outline outline-2 pr-2 shadow w-full flex items-stretch space-x-2 min-h-[36px] bg-opacity-50 hover:bg-opacity-100 hover:shadow-md rounded-lg bg-white text-sm duration-150 cursor-pointer ease-linear',
'outline outline-2 pr-2 shadow-sm w-full flex items-stretch space-x-2 min-h-[36px] bg-opacity-50 hover:bg-opacity-100 hover:shadow-md rounded-lg bg-white text-sm duration-150 cursor-pointer ease-linear',
answer.correct && isEditable ? 'outline-lime-300' : 'outline-white',
userAnswers.some(
(userAnswer: any) =>
@ -335,16 +335,16 @@ function QuizBlockComponent(props: any) {
className={twMerge(
'font-bold text-base flex items-center justify-center self-stretch w-[40px] rounded-l-md text-slate-800 bg-white',
answer.correct && isEditable
? 'bg-lime-300 text-lime-800 outline-none'
? 'bg-lime-300 text-lime-800 outline-hidden'
: 'bg-white',
userAnswers.some(
(userAnswer: any) =>
userAnswer.question_id === question.question_id &&
userAnswer.answer_id === answer.answer_id &&
!isEditable && !submitted
) ? 'bg-blue-400 text-white outline-none' : '',
) ? 'bg-blue-400 text-white outline-hidden' : '',
submitted && answer.correct
? 'bg-lime-300 text-lime-800 outline-none'
? 'bg-lime-300 text-lime-800 outline-hidden'
: '',
submitted &&
!answer.correct &&
@ -353,7 +353,7 @@ function QuizBlockComponent(props: any) {
userAnswer.question_id === question.question_id &&
userAnswer.answer_id === answer.answer_id
)
? 'bg-red-400 text-red-800 outline-none'
? 'bg-red-400 text-red-800 outline-hidden'
: ''
)}
>

View file

@ -62,7 +62,7 @@ function VideoBlockComponents(props: any) {
<BlockVideo>
<video
controls
className="rounded-lg shadow h-96 w-full object-scale-down bg-black"
className="rounded-lg shadow-sm h-96 w-full object-scale-down bg-black"
src={`${getActivityBlockMediaDirectory(
org?.org_uuid,
course?.courseStructure.course_uuid,