11"use client" ;
2-
32import Image from "next/image" ;
43import React , { useState , useEffect } from "react" ;
54import { BasicToggleButton , GoogleLoginButton , ZButton } from "./Buttons" ;
@@ -83,10 +82,12 @@ function copy(text: string) {
8382 }
8483}
8584
85+
86+
8687export default function Popup ( {
8788 type,
8889 dataTitle,
89- dataBody,
90+ dataBody = "" ,
9091 dataTT,
9192 closeLink,
9293 action,
@@ -106,14 +107,16 @@ export default function Popup({
106107 shareEnabledDefault !== undefined ? shareEnabledDefault : true ;
107108 const [ shareState ] = useState < "on" | "off" > ( shareEnabled ? "on" : "off" ) ;
108109
110+ const [ isInvalid , setIsInvalid ] = useState ( false ) ;
111+
109112 useEffect ( ( ) => {
110113 document . body . style . overflow = "hidden" ;
111-
112114 return ( ) => {
113115 document . body . style . overflow = "" ;
114116 } ;
115117 } , [ ] ) ;
116118
119+
117120 return (
118121 < div className = "fixed inset-0 flex items-center justify-center bg-[#425D5F]/75 backdrop-blur-xs z-50 select-none" >
119122
@@ -365,62 +368,135 @@ export default function Popup({
365368 ) }
366369
367370 { type == "save_tt" && (
368- < div >
369- < div className = "break-words max-w-lg w-full text-center mt-2 mb-8" >
370- { text }
371- </ div >
372- < div className = "flex flex-row items-center justify-center gap-8 mt-2 mb-4" >
373- < div className = "border-3 border-black pt-2 pb-2 px-4 rounded-xl shadow-[4px_4px_0_0_black] bg-white text-black font-semibold" >
374- < input
375- type = "text"
376- className = "bg-transparent outline-none w-full text-center font-semibold"
377- placeholder = "Enter timetable name"
378- value = { dataBody }
379- onChange = { ( e ) =>
380- onInputChange && onInputChange ( e . target . value )
381- }
382- />
383- </ div >
384- < ZButton
385- type = "regular"
386- text = "Save"
387- color = "green"
388- forceColor = { theme [ 1 ] }
389- onClick = { action }
390- />
391- </ div >
392- </ div >
393- ) }
371+ < div >
372+ < div className = "break-words max-w-lg w-full text-center mt-2 mb-8" >
373+ { text }
374+ </ div >
375+ < div className = "flex flex-row items-center justify-center gap-8 mt-2 mb-4" >
376+ < div className = "border-3 border-black pt-2 pb-2 px-4 rounded-xl shadow-[4px_4px_0_0_black] bg-white text-black font-semibold" >
377+ < input
378+ type = "text"
379+ className = { `bg-transparent outline-none w-full text-center font-semibold border-2 rounded-lg py-1 px-3 ${
380+ isInvalid ? "border-red-500" : "border-white"
381+ } `}
382+ placeholder = "Enter timetable name"
383+ value = { dataBody }
384+ onChange = { ( e ) => {
385+ const inputValue = e . target . value ;
386+ const normalized = inputValue . toLowerCase ( ) . replace ( / \s + / g, "" ) ;
387+ const forbiddenWords = [
388+ "vishvanathan" ,
389+ "vishvnathan" ,
390+ "vishwanathan" ,
391+ "viswanathan" ,
392+ "vishva" ,
393+ "viswa" ,
394+ "vit" ,
395+ "vellore institute of technology" ,
396+ "vitstudent" ,
397+ "vit.ac.in" ,
398+ "vit vellore" ,
399+ "vit chennai" ,
400+ "vit bhopal" ,
401+ "vit ap" ,
402+ "vit university" ,
403+ "vtop" ,
404+ ] ;
405+
406+
407+
408+ const containsForbidden = forbiddenWords . some ( ( word ) =>
409+ normalized . includes ( word . replace ( / \s + / g, "" ) )
410+ ) ;
411+
412+
413+ setIsInvalid ( containsForbidden ) ;
414+ if ( ! containsForbidden ) {
415+ onInputChange ?.( inputValue ) ;
416+ }
417+ } }
418+ />
419+ </ div >
420+ < ZButton
421+ type = "regular"
422+ text = "Save"
423+ color = "green"
424+ forceColor = { theme [ 1 ] }
425+ onClick = { action }
426+ />
427+ </ div >
428+ { isInvalid && (
429+ < div className = "text-red-500 text-sm mt-1 text-center" >
430+ This name contains restricted words.
431+ </ div >
432+ ) }
433+ </ div >
434+ ) }
394435
395436 { type == "rename_tt" && (
396- < div >
397- < div className = "break-words max-w-lg w-full text-center mt-2 mb-8" >
398- { text }
399- </ div >
400- < div className = "flex flex-row items-center justify-center gap-8 mt-2 mb-4" >
401- < div className = "border-3 border-black pt-2 pb-2 px-4 rounded-xl shadow-[4px_4px_0_0_black] bg-white text-black font-semibold" >
402- < input
403- type = "text"
404- className = "bg-transparent outline-none w-full text-center font-semibold"
405- placeholder = "Enter timetable name"
406- value = { dataBody }
407- onChange = { ( e ) =>
408- onInputChange && onInputChange ( e . target . value )
409- }
410- autoFocus
411- />
412- </ div >
413- < ZButton
414- type = "regular"
415- text = "Save"
416- color = "green"
417- forceColor = { theme [ 1 ] }
418- onClick = { action }
419- />
420- </ div >
421- </ div >
422- ) }
437+ < div >
438+ < div className = "break-words max-w-lg w-full text-center mt-2 mb-8" >
439+ { text }
440+ </ div >
441+ < div className = "flex flex-row items-center justify-center gap-8 mt-2 mb-4" >
442+ < div className = "border-3 border-black pt-2 pb-2 px-4 rounded-xl shadow-[4px_4px_0_0_black] bg-white text-black font-semibold" >
443+ < input
444+ type = "text"
445+ className = { `bg-transparent outline-none w-full text-center font-semibold border-2 rounded-lg py-1 px-3 ${
446+ isInvalid ? "border-red-500" : "border-white"
447+ } `}
448+ placeholder = "Enter timetable name"
449+ value = { dataBody }
450+ onChange = { ( e ) => {
451+ const inputValue = e . target . value ;
452+ const normalized = inputValue . toLowerCase ( ) . replace ( / \s + / g, "" ) ;
423453
454+ const forbiddenWords = [
455+ "vishvanathan" ,
456+ "vishvnathan" ,
457+ "vishwanathan" ,
458+ "viswanathan" ,
459+ "vishva" ,
460+ "viswa" ,
461+ "vit" ,
462+ "vellore institute of technology" ,
463+ "vitstudent" ,
464+ "vit.ac.in" ,
465+ "vit vellore" ,
466+ "vit chennai" ,
467+ "vit bhopal" ,
468+ "vit ap" ,
469+ "vit university" ,
470+ "vtop" ,
471+ ] ;
472+
473+ const containsForbidden = forbiddenWords . some ( ( word ) =>
474+ normalized . includes ( word . replace ( / \s + / g, "" ) )
475+ ) ;
476+
477+ setIsInvalid ( containsForbidden ) ;
478+ if ( ! containsForbidden ) {
479+ onInputChange ?.( inputValue ) ;
480+ }
481+ } }
482+ autoFocus
483+ />
484+ </ div >
485+ < ZButton
486+ type = "regular"
487+ text = "Save"
488+ color = "green"
489+ forceColor = { theme [ 1 ] }
490+ onClick = { action }
491+ />
492+ </ div >
493+ { isInvalid && (
494+ < div className = "text-red-500 text-sm mt-1 text-center" >
495+ This name contains restricted words.
496+ </ div >
497+ ) }
498+ </ div >
499+ ) }
424500 { type == "view_tt" && (
425501 < div className = "flex flex-col w-full max-h-[90vh] overflow-hidden" >
426502
0 commit comments