11"use client" ;
2-
32import Image from "next/image" ;
43import React , { useState , useEffect } from "react" ;
54import { BasicToggleButton , GoogleLoginButton , ZButton } from "./Buttons" ;
@@ -83,10 +82,28 @@ function copy(text: string) {
8382 }
8483}
8584
85+ const forbiddenWords = [
86+ "vishvanathan" ,
87+ "vishwanathan" ,
88+ "viswanathan" ,
89+ "vishva" ,
90+ "viswa" ,
91+ "vit" ,
92+ "vellore institute of technology" ,
93+ "vitstudent" ,
94+ "vit.ac.in" ,
95+ "vit vellore" ,
96+ "vit chennai" ,
97+ "vit bhopal" ,
98+ "vit ap" ,
99+ "vit university" ,
100+ "vtop" ,
101+ ] ;
102+
86103export default function Popup ( {
87104 type,
88105 dataTitle,
89- dataBody,
106+ dataBody = "" ,
90107 dataTT,
91108 closeLink,
92109 action,
@@ -106,14 +123,16 @@ export default function Popup({
106123 shareEnabledDefault !== undefined ? shareEnabledDefault : true ;
107124 const [ shareState ] = useState < "on" | "off" > ( shareEnabled ? "on" : "off" ) ;
108125
126+ const [ isInvalid , setIsInvalid ] = useState ( false ) ;
127+
109128 useEffect ( ( ) => {
110129 document . body . style . overflow = "hidden" ;
111-
112130 return ( ) => {
113131 document . body . style . overflow = "" ;
114132 } ;
115133 } , [ ] ) ;
116134
135+
117136 return (
118137 < div className = "fixed inset-0 flex items-center justify-center bg-[#425D5F]/75 backdrop-blur-xs z-50 select-none" >
119138
@@ -365,62 +384,135 @@ export default function Popup({
365384 ) }
366385
367386 { 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- ) }
387+ < div >
388+ < div className = "break-words max-w-lg w-full text-center mt-2 mb-8" >
389+ { text }
390+ </ div >
391+ < div className = "flex flex-row items-center justify-center gap-8 mt-2 mb-4" >
392+ < 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" >
393+ < input
394+ type = "text"
395+ className = { `bg-transparent outline-none w-full text-center font-semibold border-2 rounded-lg py-1 px-3 ${
396+ isInvalid ? "border-red-500" : "border-white"
397+ } `}
398+ placeholder = "Enter timetable name"
399+ value = { dataBody }
400+ onChange = { ( e ) => {
401+ const inputValue = e . target . value ;
402+ const normalized = inputValue . toLowerCase ( ) . replace ( / \s + / g, "" ) ;
403+ const forbiddenWords = [
404+ "vishvanathan" ,
405+ "vishvnathan" ,
406+ "vishwanathan" ,
407+ "viswanathan" ,
408+ "vishva" ,
409+ "viswa" ,
410+ "vit" ,
411+ "vellore institute of technology" ,
412+ "vitstudent" ,
413+ "vit.ac.in" ,
414+ "vit vellore" ,
415+ "vit chennai" ,
416+ "vit bhopal" ,
417+ "vit ap" ,
418+ "vit university" ,
419+ "vtop" ,
420+ ] ;
421+
422+
423+
424+ const containsForbidden = forbiddenWords . some ( ( word ) =>
425+ normalized . includes ( word . replace ( / \s + / g, "" ) )
426+ ) ;
427+
428+
429+ setIsInvalid ( containsForbidden ) ;
430+ if ( ! containsForbidden ) {
431+ onInputChange ?.( inputValue ) ;
432+ }
433+ } }
434+ />
435+ </ div >
436+ < ZButton
437+ type = "regular"
438+ text = "Save"
439+ color = "green"
440+ forceColor = { theme [ 1 ] }
441+ onClick = { action }
442+ />
443+ </ div >
444+ { isInvalid && (
445+ < div className = "text-red-500 text-sm mt-1 text-center" >
446+ This name contains restricted words.
447+ </ div >
448+ ) }
449+ </ div >
450+ ) }
394451
395452 { 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- ) }
453+ < div >
454+ < div className = "break-words max-w-lg w-full text-center mt-2 mb-8" >
455+ { text }
456+ </ div >
457+ < div className = "flex flex-row items-center justify-center gap-8 mt-2 mb-4" >
458+ < 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" >
459+ < input
460+ type = "text"
461+ className = { `bg-transparent outline-none w-full text-center font-semibold border-2 rounded-lg py-1 px-3 ${
462+ isInvalid ? "border-red-500" : "border-white"
463+ } `}
464+ placeholder = "Enter timetable name"
465+ value = { dataBody }
466+ onChange = { ( e ) => {
467+ const inputValue = e . target . value ;
468+ const normalized = inputValue . toLowerCase ( ) . replace ( / \s + / g, "" ) ;
423469
470+ const forbiddenWords = [
471+ "vishvanathan" ,
472+ "vishvnathan" ,
473+ "vishwanathan" ,
474+ "viswanathan" ,
475+ "vishva" ,
476+ "viswa" ,
477+ "vit" ,
478+ "vellore institute of technology" ,
479+ "vitstudent" ,
480+ "vit.ac.in" ,
481+ "vit vellore" ,
482+ "vit chennai" ,
483+ "vit bhopal" ,
484+ "vit ap" ,
485+ "vit university" ,
486+ "vtop" ,
487+ ] ;
488+
489+ const containsForbidden = forbiddenWords . some ( ( word ) =>
490+ normalized . includes ( word . replace ( / \s + / g, "" ) )
491+ ) ;
492+
493+ setIsInvalid ( containsForbidden ) ;
494+ if ( ! containsForbidden ) {
495+ onInputChange ?.( inputValue ) ;
496+ }
497+ } }
498+ autoFocus
499+ />
500+ </ div >
501+ < ZButton
502+ type = "regular"
503+ text = "Save"
504+ color = "green"
505+ forceColor = { theme [ 1 ] }
506+ onClick = { action }
507+ />
508+ </ div >
509+ { isInvalid && (
510+ < div className = "text-red-500 text-sm mt-1 text-center" >
511+ This name contains restricted words.
512+ </ div >
513+ ) }
514+ </ div >
515+ ) }
424516 { type == "view_tt" && (
425517 < div className = "flex flex-col w-full max-h-[90vh] overflow-hidden" >
426518
0 commit comments