mirror of
https://github.com/rzmk/learnhouse.git
synced 2025-12-18 20:09:25 +00:00
Merge pull request #367 from chrishollandaise/fix/limit-inputs-accept-values
fix: file inputs limit to their respective file formats
This commit is contained in:
commit
94c2ed50ab
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 React, { useEffect } from 'react'
|
||||
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() {
|
||||
const session = useLHSession() as any;
|
||||
|
|
@ -242,6 +245,7 @@ function UpdateTaskRef() {
|
|||
<div className="flex justify-center items-center">
|
||||
<input
|
||||
type="file"
|
||||
accept={SUPPORTED_FILES}
|
||||
id="fileInput"
|
||||
style={{ display: 'none' }}
|
||||
onChange={handleFileChange}
|
||||
|
|
@ -255,6 +259,7 @@ function UpdateTaskRef() {
|
|||
<div className="flex justify-center items-center">
|
||||
<input
|
||||
type="file"
|
||||
accept={SUPPORTED_FILES}
|
||||
id="fileInput"
|
||||
style={{ display: 'none' }}
|
||||
onChange={handleFileChange}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import {
|
|||
uploadOrganizationLogo,
|
||||
uploadOrganizationThumbnail,
|
||||
} 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 { useRouter } from 'next/navigation'
|
||||
import { useOrg } from '@components/Contexts/OrgContext'
|
||||
|
|
@ -14,6 +14,9 @@ import { useLHSession } from '@components/Contexts/LHSessionContext'
|
|||
import { getOrgLogoMediaDirectory, getOrgThumbnailMediaDirectory } from '@services/media/media'
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
|
||||
import { Toaster, toast } from 'react-hot-toast';
|
||||
import { constructAcceptValue } from '@/lib/constants';
|
||||
|
||||
const SUPPORTED_FILES = constructAcceptValue(['png', 'jpg'])
|
||||
|
||||
interface OrganizationValues {
|
||||
name: string
|
||||
|
|
@ -174,6 +177,7 @@ function OrgEditGeneral() {
|
|||
<input
|
||||
type="file"
|
||||
id="fileInput"
|
||||
accept={SUPPORTED_FILES}
|
||||
style={{ display: 'none' }}
|
||||
onChange={handleFileChange}
|
||||
/>
|
||||
|
|
@ -205,6 +209,7 @@ function OrgEditGeneral() {
|
|||
<div className="flex justify-center items-center">
|
||||
<input
|
||||
type="file"
|
||||
accept={SUPPORTED_FILES}
|
||||
id="thumbnailInput"
|
||||
style={{ display: 'none' }}
|
||||
onChange={handleThumbnailChange}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,9 @@ import {
|
|||
} from 'lucide-react'
|
||||
import UserAvatar from '@components/Objects/UserAvatar'
|
||||
import { updateUserAvatar } from '@services/users/users'
|
||||
import { constructAcceptValue } from '@/lib/constants';
|
||||
|
||||
const SUPPORTED_FILES = constructAcceptValue(['image'])
|
||||
|
||||
function UserEditGeneral() {
|
||||
const session = useLHSession() as any;
|
||||
|
|
@ -125,6 +128,7 @@ function UserEditGeneral() {
|
|||
<input
|
||||
type="file"
|
||||
id="fileInput"
|
||||
accept={SUPPORTED_FILES}
|
||||
className="hidden"
|
||||
onChange={handleFileChange}
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -9,6 +9,9 @@ import { useCourse } from '@components/Contexts/CourseContext'
|
|||
import { useEditorProvider } from '@components/Contexts/Editor/EditorContext'
|
||||
import { useLHSession } from '@components/Contexts/LHSessionContext'
|
||||
import { FileUploadBlock, FileUploadBlockButton, FileUploadBlockInput } from '../../FileUploadBlock'
|
||||
import { constructAcceptValue } from '@/lib/constants';
|
||||
|
||||
const SUPPORTED_FILES = constructAcceptValue(['image'])
|
||||
|
||||
function ImageBlockComponent(props: any) {
|
||||
const org = useOrg() as any
|
||||
|
|
@ -53,7 +56,7 @@ function ImageBlockComponent(props: any) {
|
|||
return (
|
||||
<NodeViewWrapper className="block-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}/>
|
||||
</FileUploadBlock>
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,9 @@ import { useCourse } from '@components/Contexts/CourseContext'
|
|||
import { useEditorProvider } from '@components/Contexts/Editor/EditorContext'
|
||||
import { useLHSession } from '@components/Contexts/LHSessionContext'
|
||||
import { FileUploadBlock, FileUploadBlockButton, FileUploadBlockInput } from '../../FileUploadBlock'
|
||||
import { constructAcceptValue } from '@/lib/constants';
|
||||
|
||||
const SUPPORTED_FILES = constructAcceptValue(['pdf'])
|
||||
|
||||
function PDFBlockComponent(props: any) {
|
||||
const org = useOrg() as any
|
||||
|
|
@ -49,7 +52,7 @@ function PDFBlockComponent(props: any) {
|
|||
return (
|
||||
<NodeViewWrapper className="block-pdf">
|
||||
<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}/>
|
||||
</FileUploadBlock>
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,9 @@ import { useCourse } from '@components/Contexts/CourseContext'
|
|||
import { useEditorProvider } from '@components/Contexts/Editor/EditorContext'
|
||||
import { useLHSession } from '@components/Contexts/LHSessionContext'
|
||||
import { FileUploadBlock, FileUploadBlockButton, FileUploadBlockInput } from '../../FileUploadBlock'
|
||||
import { constructAcceptValue } from '@/lib/constants';
|
||||
|
||||
const SUPPORTED_FILES = constructAcceptValue(['webm', 'mp4'])
|
||||
|
||||
function VideoBlockComponents(props: any) {
|
||||
const org = useOrg() as any
|
||||
|
|
@ -51,7 +54,7 @@ function VideoBlockComponents(props: any) {
|
|||
return (
|
||||
<NodeViewWrapper className="block-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}/>
|
||||
</FileUploadBlock>
|
||||
|
||||
|
|
|
|||
|
|
@ -9,6 +9,9 @@ import FormLayout, {
|
|||
import React, { useState } from 'react'
|
||||
import * as Form from '@radix-ui/react-form'
|
||||
import BarLoader from 'react-spinners/BarLoader'
|
||||
import { constructAcceptValue } from '@/lib/constants';
|
||||
|
||||
const SUPPORTED_FILES = constructAcceptValue(['pdf'])
|
||||
|
||||
function DocumentPdfModal({ submitFileActivity, chapterId, course }: any) {
|
||||
const [documentpdf, setDocumentPdf] = React.useState(null) as any
|
||||
|
|
@ -64,7 +67,7 @@ function DocumentPdfModal({ submitFileActivity, chapterId, course }: any) {
|
|||
</FormMessage>
|
||||
</Flex>
|
||||
<Form.Control asChild>
|
||||
<input type="file" onChange={handleDocumentPdfChange} required />
|
||||
<input accept={SUPPORTED_FILES} type="file" onChange={handleDocumentPdfChange} required />
|
||||
</Form.Control>
|
||||
</FormField>
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,9 @@ import React, { useState } from 'react'
|
|||
import * as Form from '@radix-ui/react-form'
|
||||
import BarLoader from 'react-spinners/BarLoader'
|
||||
import { Youtube } from 'lucide-react'
|
||||
import { constructAcceptValue } from '@/lib/constants';
|
||||
|
||||
const SUPPORTED_FILES = constructAcceptValue(['mp4', 'webm'])
|
||||
|
||||
interface ExternalVideoObject {
|
||||
name: string
|
||||
|
|
@ -134,7 +137,7 @@ function VideoModal({
|
|||
</FormMessage>
|
||||
</Flex>
|
||||
<Form.Control asChild>
|
||||
<input type="file" onChange={handleVideoChange} required />
|
||||
<input accept={SUPPORTED_FILES} type="file" onChange={handleVideoChange} required />
|
||||
</Form.Control>
|
||||
</FormField>
|
||||
</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