mirror of
https://github.com/rzmk/learnhouse.git
synced 2025-12-19 04:19:25 +00:00
feat: refactor the entire learnhouse project
This commit is contained in:
parent
f556e41dda
commit
4c215e91d5
247 changed files with 7716 additions and 1013 deletions
|
|
@ -0,0 +1,19 @@
|
|||
import { getBackendUrl } from "@services/config/config";
|
||||
import { getActivityMediaDirectory } from "@services/media/media";
|
||||
import React from "react";
|
||||
|
||||
function DocumentPdfActivity({ activity, course }: { activity: any; course: any }) {
|
||||
|
||||
return (
|
||||
<div className="m-8 bg-zinc-900 rounded-md mt-14">
|
||||
<iframe
|
||||
className="rounded-lg w-full h-[900px]"
|
||||
src={getActivityMediaDirectory(activity.org_id, activity.course_id, activity.activity_id, activity.content.documentpdf.filename, 'documentpdf')}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default DocumentPdfActivity;
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,222 @@
|
|||
import { useEditor, EditorContent } from "@tiptap/react";
|
||||
import StarterKit from "@tiptap/starter-kit";
|
||||
import styled from "styled-components"
|
||||
import Youtube from "@tiptap/extension-youtube";
|
||||
// Custom Extensions
|
||||
import InfoCallout from "@components/Objects/Editor/Extensions/Callout/Info/InfoCallout";
|
||||
import WarningCallout from "@components/Objects/Editor/Extensions/Callout/Warning/WarningCallout";
|
||||
import ImageBlock from "@components/Objects/Editor/Extensions/Image/ImageBlock";
|
||||
import VideoBlock from "@components/Objects/Editor/Extensions/Video/VideoBlock";
|
||||
import MathEquationBlock from "@components/Objects/Editor/Extensions/MathEquation/MathEquationBlock";
|
||||
import PDFBlock from "@components/Objects/Editor/Extensions/PDF/PDFBlock";
|
||||
import { OrderedList } from "@tiptap/extension-ordered-list";
|
||||
import QuizBlock from "@components/Objects/Editor/Extensions/Quiz/QuizBlock";
|
||||
|
||||
// Lowlight
|
||||
import { common, createLowlight } from 'lowlight'
|
||||
const lowlight = createLowlight(common)
|
||||
import CodeBlockLowlight from '@tiptap/extension-code-block-lowlight';
|
||||
import css from 'highlight.js/lib/languages/css'
|
||||
import js from 'highlight.js/lib/languages/javascript'
|
||||
import ts from 'highlight.js/lib/languages/typescript'
|
||||
import html from 'highlight.js/lib/languages/xml'
|
||||
import python from 'highlight.js/lib/languages/python'
|
||||
import java from 'highlight.js/lib/languages/java'
|
||||
|
||||
|
||||
interface Editor {
|
||||
content: string;
|
||||
activity: any;
|
||||
//course: any;
|
||||
}
|
||||
|
||||
function Canva(props: Editor) {
|
||||
const isEditable = false;
|
||||
|
||||
// Code Block Languages for Lowlight
|
||||
lowlight.register('html', html)
|
||||
lowlight.register('css', css)
|
||||
lowlight.register('js', js)
|
||||
lowlight.register('ts', ts)
|
||||
lowlight.register('python', python)
|
||||
lowlight.register('java', java)
|
||||
|
||||
|
||||
const editor: any = useEditor({
|
||||
editable: isEditable,
|
||||
extensions: [
|
||||
StarterKit,
|
||||
// Custom Extensions
|
||||
InfoCallout.configure({
|
||||
editable: isEditable,
|
||||
}),
|
||||
WarningCallout.configure({
|
||||
editable: isEditable,
|
||||
}),
|
||||
ImageBlock.configure({
|
||||
editable: isEditable,
|
||||
activity: props.activity,
|
||||
}),
|
||||
VideoBlock.configure({
|
||||
editable: true,
|
||||
activity: props.activity,
|
||||
}),
|
||||
MathEquationBlock.configure({
|
||||
editable: false,
|
||||
activity: props.activity,
|
||||
}),
|
||||
PDFBlock.configure({
|
||||
editable: true,
|
||||
activity: props.activity,
|
||||
}),
|
||||
QuizBlock.configure({
|
||||
editable: isEditable,
|
||||
activity: props.activity,
|
||||
}),
|
||||
Youtube.configure({
|
||||
controls: true,
|
||||
modestBranding: true,
|
||||
}),
|
||||
OrderedList.configure(),
|
||||
CodeBlockLowlight.configure({
|
||||
lowlight,
|
||||
}),
|
||||
|
||||
],
|
||||
|
||||
content: props.content,
|
||||
});
|
||||
|
||||
return (
|
||||
<CanvaWrapper>
|
||||
<EditorContent editor={editor} />
|
||||
</CanvaWrapper>
|
||||
);
|
||||
}
|
||||
|
||||
const CanvaWrapper = styled.div`
|
||||
width: 100%;
|
||||
margin: 0 auto;
|
||||
|
||||
// disable chrome outline
|
||||
|
||||
.ProseMirror {
|
||||
|
||||
h1 {
|
||||
font-size: 30px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
h2 {
|
||||
font-size: 25px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
h4 {
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
ul, ol {
|
||||
padding: 0 1rem;
|
||||
padding-left: 20px;
|
||||
list-style-type: decimal;
|
||||
}
|
||||
|
||||
|
||||
&:focus {
|
||||
outline: none !important;
|
||||
outline-style: none !important;
|
||||
box-shadow: none !important;
|
||||
}
|
||||
|
||||
// Code Block
|
||||
pre {
|
||||
background: #0d0d0d;
|
||||
border-radius: 0.5rem;
|
||||
color: #fff;
|
||||
font-family: "JetBrainsMono", monospace;
|
||||
padding: 0.75rem 1rem;
|
||||
|
||||
code {
|
||||
background: none;
|
||||
color: inherit;
|
||||
font-size: 0.8rem;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.hljs-comment,
|
||||
.hljs-quote {
|
||||
color: #616161;
|
||||
}
|
||||
|
||||
.hljs-variable,
|
||||
.hljs-template-variable,
|
||||
.hljs-attribute,
|
||||
.hljs-tag,
|
||||
.hljs-name,
|
||||
.hljs-regexp,
|
||||
.hljs-link,
|
||||
.hljs-name,
|
||||
.hljs-selector-id,
|
||||
.hljs-selector-class {
|
||||
color: #f98181;
|
||||
}
|
||||
|
||||
.hljs-number,
|
||||
.hljs-meta,
|
||||
.hljs-built_in,
|
||||
.hljs-builtin-name,
|
||||
.hljs-literal,
|
||||
.hljs-type,
|
||||
.hljs-params {
|
||||
color: #fbbc88;
|
||||
}
|
||||
|
||||
.hljs-string,
|
||||
.hljs-symbol,
|
||||
.hljs-bullet {
|
||||
color: #b9f18d;
|
||||
}
|
||||
|
||||
.hljs-title,
|
||||
.hljs-section {
|
||||
color: #faf594;
|
||||
}
|
||||
|
||||
.hljs-keyword,
|
||||
.hljs-selector-tag {
|
||||
color: #70cff8;
|
||||
}
|
||||
|
||||
.hljs-emphasis {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.hljs-strong {
|
||||
font-weight: 700;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
`;
|
||||
|
||||
export default Canva;
|
||||
73
apps/web/components/Objects/Activities/Video/Video.tsx
Normal file
73
apps/web/components/Objects/Activities/Video/Video.tsx
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
import { getBackendUrl } from "@services/config/config";
|
||||
import React from "react";
|
||||
import styled from "styled-components";
|
||||
import YouTube from 'react-youtube';
|
||||
import { getActivityMediaDirectory } from "@services/media/media";
|
||||
|
||||
function VideoActivity({ activity, course }: { activity: any; course: any }) {
|
||||
const [videoId, setVideoId] = React.useState('');
|
||||
const [videoType, setVideoType] = React.useState('');
|
||||
|
||||
function getYouTubeEmbed(url: any) {
|
||||
// Extract video ID from the YouTube URL
|
||||
var videoId = url.match(/(?:\?v=|\/embed\/|\/\d\/|\/vi\/|\/v\/|https?:\/\/(?:www\.)?youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))([^#\&\?\/]+)/)[1];
|
||||
|
||||
// Create the embed object
|
||||
var embedObject = {
|
||||
videoId: videoId,
|
||||
width: 560,
|
||||
height: 315
|
||||
};
|
||||
|
||||
return embedObject;
|
||||
}
|
||||
|
||||
|
||||
React.useEffect(() => {
|
||||
if (activity.content.video) {
|
||||
setVideoType('video');
|
||||
}
|
||||
if (activity.content.external_video) {
|
||||
setVideoType('external_video');
|
||||
setVideoId(getYouTubeEmbed(activity.content.external_video.uri).videoId);
|
||||
}
|
||||
}, [activity]);
|
||||
|
||||
return (
|
||||
<div>
|
||||
{videoType === 'video' && (
|
||||
<div className="m-8 bg-zinc-900 rounded-md mt-14">
|
||||
<video className="rounded-lg w-full h-[500px]" controls
|
||||
src={getActivityMediaDirectory(activity.org_id, activity.course_id, activity.activity_id, activity.content.video.filename, 'video')}
|
||||
></video>
|
||||
|
||||
</div>
|
||||
)}
|
||||
{videoType === 'external_video' && (
|
||||
<div>
|
||||
<YouTube
|
||||
className="rounded-md overflow-hidden m-8 bg-zinc-900 mt-14"
|
||||
opts={
|
||||
{
|
||||
width: '1300',
|
||||
height: '500',
|
||||
playerVars: {
|
||||
autoplay: 0,
|
||||
},
|
||||
|
||||
}
|
||||
}
|
||||
videoId={videoId} />
|
||||
</div>
|
||||
)}
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
export default VideoActivity;
|
||||
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue