diff --git a/packages/editor/src/core/editor.tsx b/packages/editor/src/core/editor.tsx
index 01c4711e35..6ce042dca3 100644
--- a/packages/editor/src/core/editor.tsx
+++ b/packages/editor/src/core/editor.tsx
@@ -4,6 +4,7 @@ import {
debouncedStoreToLocalStorage,
getStateFromLocalStorage,
} from '@editor/editor-ui/save/local-storage-notice'
+import { WelcomeModal } from '@editor/editor-ui/welcome-modal/welcome-modal'
import { getEditorVersion } from '@editor/package/editor-version'
import { cn } from '@editor/utils/cn'
import { useState, useMemo } from 'react'
@@ -52,6 +53,7 @@ export function Editor(props: EditorProps) {
{/* For non serlo environments, we need to render the toaster
(already gets rendered in the web project) */}
{!isSerlo ? : null}
+
{
+ const [isOpen, setIsOpen] = useState(false)
+
+ useEffect(() => {
+ const localStorageValue = localStorage.getItem(localStorageKey)
+ if (localStorageValue === null) return setIsOpen(true)
+ const hasSeenModal = decodeWelcomeModalData(localStorageValue)
+ if (!hasSeenModal) setIsOpen(true)
+ }, [])
+
+ const handleClose = () => {
+ setIsOpen(false)
+ localStorage.setItem(localStorageKey, 'true')
+ }
+
+ return { isOpen, onClose: handleClose }
+}
+
+const WelcomeModalDataCodec = t.boolean
+
+function decodeWelcomeModalData(input: string) {
+ return pipe(
+ WelcomeModalDataCodec.decode(JSON.parse(input)),
+ fold(
+ () => false,
+ (decoded) => decoded
+ )
+ )
+}
diff --git a/packages/editor/src/editor-ui/welcome-modal/welcome-modal-button.tsx b/packages/editor/src/editor-ui/welcome-modal/welcome-modal-button.tsx
new file mode 100644
index 0000000000..a409d4e329
--- /dev/null
+++ b/packages/editor/src/editor-ui/welcome-modal/welcome-modal-button.tsx
@@ -0,0 +1,20 @@
+import { cn } from '@editor/utils/cn'
+
+interface WelcomeModalButtonProps {
+ isActive: boolean
+ onClick: () => void
+}
+
+export function WelcomeModalButton(props: WelcomeModalButtonProps) {
+ const { isActive, onClick } = props
+
+ return (
+
+ )
+}
diff --git a/packages/editor/src/editor-ui/welcome-modal/welcome-modal.tsx b/packages/editor/src/editor-ui/welcome-modal/welcome-modal.tsx
new file mode 100644
index 0000000000..27479fc903
--- /dev/null
+++ b/packages/editor/src/editor-ui/welcome-modal/welcome-modal.tsx
@@ -0,0 +1,106 @@
+import { EditorModal } from '@editor/editor-ui/editor-modal'
+import { faCircleQuestion } from '@fortawesome/free-regular-svg-icons'
+import { faArrowCircleRight } from '@fortawesome/free-solid-svg-icons'
+import { useState } from 'react'
+
+import { FaIcon } from '../fa-icon'
+import { useWelcomeModal } from './use-welcome-modal'
+import { WelcomeModalButton } from './welcome-modal-button'
+
+export function WelcomeModal() {
+ const { isOpen, onClose } = useWelcomeModal()
+ const [currentStep, setCurrentStep] = useState(1)
+
+ function handleNextButtonClick() {
+ setCurrentStep((previousValue) => {
+ if (previousValue < steps.length) return previousValue + 1
+ return onClose() ?? 1
+ })
+ }
+
+ return (
+
!isOpen && onClose()}
+ >
+
+
+
+
+ Herzlich Willkommen!
+ beim Serlo Editor
+
+
+ Der Serlo Editor hilft Dir,{' '}
+ Texte, Bilder und interaktive Aufgaben direkt zu bearbeiten
+ und sofort sehen, wie sie später aussehen.
+
+
+ So kannst Du Lernmaterialien einfach erstellen,{' '}
+ ohne technische Vorkenntnisse zu benötigen.
+
+
+
+
+
+
+
+
+
+
+ Weitere Erklärungen und Videos findest du jeweils in der
+ Toolbar der einzelnen Plugins. Einfach auf das{' '}
+
+ -Symbol klicken.
+
+
+
+
+
+
+
+ {steps.map((step) => (
+ setCurrentStep(step)}
+ />
+ ))}
+
+
+ {currentStep === steps.length ? "Los geht's!" : 'Weiter'}{' '}
+
+
+
+
+ )
+}
+
+const steps = [1, 2]
+
+const slideWidth = 600
+
+const slideProps = {
+ style: { width: slideWidth },
+ className: 'px-4',
+}
+
+const translateXValuesMap: Record
= {
+ 1: '0',
+ 2: `-${slideWidth}px`,
+}