mirror of
https://github.com/rzmk/learnhouse.git
synced 2025-12-19 04:19:25 +00:00
fix: inputs limit to their respective file formats
This commit is contained in:
parent
19cc3ea0d7
commit
b678ac86e8
9 changed files with 55 additions and 6 deletions
|
|
@ -13,6 +13,9 @@ import { Cloud, File, Info, Loader, UploadCloud } from 'lucide-react'
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import React, { useEffect } from 'react'
|
import React, { useEffect } from 'react'
|
||||||
import toast from 'react-hot-toast';
|
import toast from 'react-hot-toast';
|
||||||
|
import { constructAcceptValue } from '@/lib/constants';
|
||||||
|
|
||||||
|
const SUPPORTED_FILES = constructAcceptValue(['pdf', 'docx', 'mp4', 'jpg', 'png', 'pptx', 'zip'])
|
||||||
|
|
||||||
export function AssignmentTaskGeneralEdit() {
|
export function AssignmentTaskGeneralEdit() {
|
||||||
const session = useLHSession() as any;
|
const session = useLHSession() as any;
|
||||||
|
|
@ -242,6 +245,7 @@ function UpdateTaskRef() {
|
||||||
<div className="flex justify-center items-center">
|
<div className="flex justify-center items-center">
|
||||||
<input
|
<input
|
||||||
type="file"
|
type="file"
|
||||||
|
accept={SUPPORTED_FILES}
|
||||||
id="fileInput"
|
id="fileInput"
|
||||||
style={{ display: 'none' }}
|
style={{ display: 'none' }}
|
||||||
onChange={handleFileChange}
|
onChange={handleFileChange}
|
||||||
|
|
@ -255,6 +259,7 @@ function UpdateTaskRef() {
|
||||||
<div className="flex justify-center items-center">
|
<div className="flex justify-center items-center">
|
||||||
<input
|
<input
|
||||||
type="file"
|
type="file"
|
||||||
|
accept={SUPPORTED_FILES}
|
||||||
id="fileInput"
|
id="fileInput"
|
||||||
style={{ display: 'none' }}
|
style={{ display: 'none' }}
|
||||||
onChange={handleFileChange}
|
onChange={handleFileChange}
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ import {
|
||||||
uploadOrganizationLogo,
|
uploadOrganizationLogo,
|
||||||
uploadOrganizationThumbnail,
|
uploadOrganizationThumbnail,
|
||||||
} from '@services/settings/org'
|
} from '@services/settings/org'
|
||||||
import { UploadCloud, Info, Check, FileWarning } from 'lucide-react'
|
import { UploadCloud, Info } from 'lucide-react'
|
||||||
import { revalidateTags } from '@services/utils/ts/requests'
|
import { revalidateTags } from '@services/utils/ts/requests'
|
||||||
import { useRouter } from 'next/navigation'
|
import { useRouter } from 'next/navigation'
|
||||||
import { useOrg } from '@components/Contexts/OrgContext'
|
import { useOrg } from '@components/Contexts/OrgContext'
|
||||||
|
|
@ -14,6 +14,9 @@ import { useLHSession } from '@components/Contexts/LHSessionContext'
|
||||||
import { getOrgLogoMediaDirectory, getOrgThumbnailMediaDirectory } from '@services/media/media'
|
import { getOrgLogoMediaDirectory, getOrgThumbnailMediaDirectory } from '@services/media/media'
|
||||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
|
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
|
||||||
import { Toaster, toast } from 'react-hot-toast';
|
import { Toaster, toast } from 'react-hot-toast';
|
||||||
|
import { constructAcceptValue } from '@/lib/constants';
|
||||||
|
|
||||||
|
const SUPPORTED_FILES = constructAcceptValue(['png', 'jpg'])
|
||||||
|
|
||||||
interface OrganizationValues {
|
interface OrganizationValues {
|
||||||
name: string
|
name: string
|
||||||
|
|
@ -174,6 +177,7 @@ function OrgEditGeneral() {
|
||||||
<input
|
<input
|
||||||
type="file"
|
type="file"
|
||||||
id="fileInput"
|
id="fileInput"
|
||||||
|
accept={SUPPORTED_FILES}
|
||||||
style={{ display: 'none' }}
|
style={{ display: 'none' }}
|
||||||
onChange={handleFileChange}
|
onChange={handleFileChange}
|
||||||
/>
|
/>
|
||||||
|
|
@ -205,6 +209,7 @@ function OrgEditGeneral() {
|
||||||
<div className="flex justify-center items-center">
|
<div className="flex justify-center items-center">
|
||||||
<input
|
<input
|
||||||
type="file"
|
type="file"
|
||||||
|
accept={SUPPORTED_FILES}
|
||||||
id="thumbnailInput"
|
id="thumbnailInput"
|
||||||
style={{ display: 'none' }}
|
style={{ display: 'none' }}
|
||||||
onChange={handleThumbnailChange}
|
onChange={handleThumbnailChange}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,9 @@ import {
|
||||||
} from 'lucide-react'
|
} from 'lucide-react'
|
||||||
import UserAvatar from '@components/Objects/UserAvatar'
|
import UserAvatar from '@components/Objects/UserAvatar'
|
||||||
import { updateUserAvatar } from '@services/users/users'
|
import { updateUserAvatar } from '@services/users/users'
|
||||||
|
import { constructAcceptValue } from '@/lib/constants';
|
||||||
|
|
||||||
|
const SUPPORTED_FILES = constructAcceptValue(['image'])
|
||||||
|
|
||||||
function UserEditGeneral() {
|
function UserEditGeneral() {
|
||||||
const session = useLHSession() as any;
|
const session = useLHSession() as any;
|
||||||
|
|
@ -165,6 +168,7 @@ function UserEditGeneral() {
|
||||||
<input
|
<input
|
||||||
type="file"
|
type="file"
|
||||||
id="fileInput"
|
id="fileInput"
|
||||||
|
accept={SUPPORTED_FILES}
|
||||||
style={{ display: 'none' }}
|
style={{ display: 'none' }}
|
||||||
onChange={handleFileChange}
|
onChange={handleFileChange}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,9 @@ import { useCourse } from '@components/Contexts/CourseContext'
|
||||||
import { useEditorProvider } from '@components/Contexts/Editor/EditorContext'
|
import { useEditorProvider } from '@components/Contexts/Editor/EditorContext'
|
||||||
import { useLHSession } from '@components/Contexts/LHSessionContext'
|
import { useLHSession } from '@components/Contexts/LHSessionContext'
|
||||||
import { FileUploadBlock, FileUploadBlockButton, FileUploadBlockInput } from '../../FileUploadBlock'
|
import { FileUploadBlock, FileUploadBlockButton, FileUploadBlockInput } from '../../FileUploadBlock'
|
||||||
|
import { constructAcceptValue } from '@/lib/constants';
|
||||||
|
|
||||||
|
const SUPPORTED_FILES = constructAcceptValue(['image'])
|
||||||
|
|
||||||
function ImageBlockComponent(props: any) {
|
function ImageBlockComponent(props: any) {
|
||||||
const org = useOrg() as any
|
const org = useOrg() as any
|
||||||
|
|
@ -53,7 +56,7 @@ function ImageBlockComponent(props: any) {
|
||||||
return (
|
return (
|
||||||
<NodeViewWrapper className="block-image">
|
<NodeViewWrapper className="block-image">
|
||||||
<FileUploadBlock isEditable={isEditable} isLoading={isLoading} isEmpty={!blockObject} Icon={Image}>
|
<FileUploadBlock isEditable={isEditable} isLoading={isLoading} isEmpty={!blockObject} Icon={Image}>
|
||||||
<FileUploadBlockInput onChange={handleImageChange} accept="image/*" />
|
<FileUploadBlockInput onChange={handleImageChange} accept={SUPPORTED_FILES} />
|
||||||
<FileUploadBlockButton onClick={handleSubmit} disabled={!image}/>
|
<FileUploadBlockButton onClick={handleSubmit} disabled={!image}/>
|
||||||
</FileUploadBlock>
|
</FileUploadBlock>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,9 @@ import { useCourse } from '@components/Contexts/CourseContext'
|
||||||
import { useEditorProvider } from '@components/Contexts/Editor/EditorContext'
|
import { useEditorProvider } from '@components/Contexts/Editor/EditorContext'
|
||||||
import { useLHSession } from '@components/Contexts/LHSessionContext'
|
import { useLHSession } from '@components/Contexts/LHSessionContext'
|
||||||
import { FileUploadBlock, FileUploadBlockButton, FileUploadBlockInput } from '../../FileUploadBlock'
|
import { FileUploadBlock, FileUploadBlockButton, FileUploadBlockInput } from '../../FileUploadBlock'
|
||||||
|
import { constructAcceptValue } from '@/lib/constants';
|
||||||
|
|
||||||
|
const SUPPORTED_FILES = constructAcceptValue(['pdf'])
|
||||||
|
|
||||||
function PDFBlockComponent(props: any) {
|
function PDFBlockComponent(props: any) {
|
||||||
const org = useOrg() as any
|
const org = useOrg() as any
|
||||||
|
|
@ -49,7 +52,7 @@ function PDFBlockComponent(props: any) {
|
||||||
return (
|
return (
|
||||||
<NodeViewWrapper className="block-pdf">
|
<NodeViewWrapper className="block-pdf">
|
||||||
<FileUploadBlock isEditable={isEditable} isLoading={isLoading} isEmpty={!blockObject} Icon={FileText}>
|
<FileUploadBlock isEditable={isEditable} isLoading={isLoading} isEmpty={!blockObject} Icon={FileText}>
|
||||||
<FileUploadBlockInput onChange={handlePDFChange} accept="application/pdf" />
|
<FileUploadBlockInput onChange={handlePDFChange} accept={SUPPORTED_FILES} />
|
||||||
<FileUploadBlockButton onClick={handleSubmit} disabled={!pdf}/>
|
<FileUploadBlockButton onClick={handleSubmit} disabled={!pdf}/>
|
||||||
</FileUploadBlock>
|
</FileUploadBlock>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,9 @@ import { useCourse } from '@components/Contexts/CourseContext'
|
||||||
import { useEditorProvider } from '@components/Contexts/Editor/EditorContext'
|
import { useEditorProvider } from '@components/Contexts/Editor/EditorContext'
|
||||||
import { useLHSession } from '@components/Contexts/LHSessionContext'
|
import { useLHSession } from '@components/Contexts/LHSessionContext'
|
||||||
import { FileUploadBlock, FileUploadBlockButton, FileUploadBlockInput } from '../../FileUploadBlock'
|
import { FileUploadBlock, FileUploadBlockButton, FileUploadBlockInput } from '../../FileUploadBlock'
|
||||||
|
import { constructAcceptValue } from '@/lib/constants';
|
||||||
|
|
||||||
|
const SUPPORTED_FILES = constructAcceptValue(['webm', 'mp4'])
|
||||||
|
|
||||||
function VideoBlockComponents(props: any) {
|
function VideoBlockComponents(props: any) {
|
||||||
const org = useOrg() as any
|
const org = useOrg() as any
|
||||||
|
|
@ -51,7 +54,7 @@ function VideoBlockComponents(props: any) {
|
||||||
return (
|
return (
|
||||||
<NodeViewWrapper className="block-video">
|
<NodeViewWrapper className="block-video">
|
||||||
<FileUploadBlock isEditable={isEditable} isLoading={isLoading} isEmpty={!blockObject} Icon={Video}>
|
<FileUploadBlock isEditable={isEditable} isLoading={isLoading} isEmpty={!blockObject} Icon={Video}>
|
||||||
<FileUploadBlockInput onChange={handleVideoChange} accept="video/*" />
|
<FileUploadBlockInput onChange={handleVideoChange} accept={SUPPORTED_FILES} />
|
||||||
<FileUploadBlockButton onClick={handleSubmit} disabled={!video}/>
|
<FileUploadBlockButton onClick={handleSubmit} disabled={!video}/>
|
||||||
</FileUploadBlock>
|
</FileUploadBlock>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,9 @@ import FormLayout, {
|
||||||
import React, { useState } from 'react'
|
import React, { useState } from 'react'
|
||||||
import * as Form from '@radix-ui/react-form'
|
import * as Form from '@radix-ui/react-form'
|
||||||
import BarLoader from 'react-spinners/BarLoader'
|
import BarLoader from 'react-spinners/BarLoader'
|
||||||
|
import { constructAcceptValue } from '@/lib/constants';
|
||||||
|
|
||||||
|
const SUPPORTED_FILES = constructAcceptValue(['pdf'])
|
||||||
|
|
||||||
function DocumentPdfModal({ submitFileActivity, chapterId, course }: any) {
|
function DocumentPdfModal({ submitFileActivity, chapterId, course }: any) {
|
||||||
const [documentpdf, setDocumentPdf] = React.useState(null) as any
|
const [documentpdf, setDocumentPdf] = React.useState(null) as any
|
||||||
|
|
@ -64,7 +67,7 @@ function DocumentPdfModal({ submitFileActivity, chapterId, course }: any) {
|
||||||
</FormMessage>
|
</FormMessage>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Form.Control asChild>
|
<Form.Control asChild>
|
||||||
<input type="file" onChange={handleDocumentPdfChange} required />
|
<input accept={SUPPORTED_FILES} type="file" onChange={handleDocumentPdfChange} required />
|
||||||
</Form.Control>
|
</Form.Control>
|
||||||
</FormField>
|
</FormField>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,9 @@ import React, { useState } from 'react'
|
||||||
import * as Form from '@radix-ui/react-form'
|
import * as Form from '@radix-ui/react-form'
|
||||||
import BarLoader from 'react-spinners/BarLoader'
|
import BarLoader from 'react-spinners/BarLoader'
|
||||||
import { Youtube } from 'lucide-react'
|
import { Youtube } from 'lucide-react'
|
||||||
|
import { constructAcceptValue } from '@/lib/constants';
|
||||||
|
|
||||||
|
const SUPPORTED_FILES = constructAcceptValue(['mp4', 'webm'])
|
||||||
|
|
||||||
interface ExternalVideoObject {
|
interface ExternalVideoObject {
|
||||||
name: string
|
name: string
|
||||||
|
|
@ -134,7 +137,7 @@ function VideoModal({
|
||||||
</FormMessage>
|
</FormMessage>
|
||||||
</Flex>
|
</Flex>
|
||||||
<Form.Control asChild>
|
<Form.Control asChild>
|
||||||
<input type="file" onChange={handleVideoChange} required />
|
<input accept={SUPPORTED_FILES} type="file" onChange={handleVideoChange} required />
|
||||||
</Form.Control>
|
</Form.Control>
|
||||||
</FormField>
|
</FormField>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
20
apps/web/lib/constants.ts
Normal file
20
apps/web/lib/constants.ts
Normal file
|
|
@ -0,0 +1,20 @@
|
||||||
|
export const ACCEPTED_FILE_FORMATS = {
|
||||||
|
video: 'video/*',
|
||||||
|
mp4: 'video/mp4',
|
||||||
|
webm: 'video/webm',
|
||||||
|
image: 'image/*',
|
||||||
|
jpg: 'image/jpeg',
|
||||||
|
png: 'image/png',
|
||||||
|
webp: 'image/webp',
|
||||||
|
pdf: 'application/pdf',
|
||||||
|
pptx: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
|
||||||
|
docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
|
||||||
|
zip: 'application/zip,application/x-zip-compressed'
|
||||||
|
} as const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs the 'accept' attribute value for an input element
|
||||||
|
*/
|
||||||
|
export function constructAcceptValue(types : (keyof typeof ACCEPTED_FILE_FORMATS)[]): string {
|
||||||
|
return types.map(type => ACCEPTED_FILE_FORMATS[type]).filter(Boolean).join(",")
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue