diff options
| author | zwlucas <lucas.oliveira1676@etec.sp.gov.br> | 2025-04-01 17:30:52 +0000 |
|---|---|---|
| committer | zwlucas <lucas.oliveira1676@etec.sp.gov.br> | 2025-04-01 17:30:52 +0000 |
| commit | a7a6e965979f7c46c2511a33cb601172573f3c84 (patch) | |
| tree | fafef5889ca77346cdcbd1c4a3db9cc34268c82f | |
| parent | e99de28b064275cdd0b04b98c6c3f50e85c01d7c (diff) | |
| download | eleicoes-a7a6e965979f7c46c2511a33cb601172573f3c84.tar.gz eleicoes-a7a6e965979f7c46c2511a33cb601172573f3c84.zip | |
removed cpf
| -rw-r--r-- | app/confirmar/page.tsx | 41 | ||||
| -rw-r--r-- | app/listagem/page.tsx | 18 | ||||
| -rw-r--r-- | app/obrigado/page.tsx | 8 | ||||
| -rw-r--r-- | app/page.tsx | 262 | ||||
| -rw-r--r-- | app/votar/page.tsx | 101 | ||||
| -rw-r--r-- | database.sql | 10 |
6 files changed, 163 insertions, 277 deletions
diff --git a/app/confirmar/page.tsx b/app/confirmar/page.tsx index a8b6f1c..5ca80a1 100644 --- a/app/confirmar/page.tsx +++ b/app/confirmar/page.tsx @@ -18,50 +18,22 @@ export default function ConfirmPage() { const searchParams = useSearchParams(); const rm = searchParams.get("rm") || ""; const nome = searchParams.get("nome") || ""; - const cpf = searchParams.get("cpf") || ""; useEffect(() => { - if (!rm || !nome || !cpf) { + if (!rm || !nome) { router.push("/"); return; } - }, [rm, nome, cpf, router]); + }, [rm, nome, router]); const handleConfirm = () => { - router.push(`/votar?rm=${rm}&nome=${encodeURIComponent(nome)}&cpf=${cpf}`); + router.push(`/votar?rm=${rm}&nome=${encodeURIComponent(nome)}`); }; const handleCancel = () => { router.push("/"); }; - const formatCPFDisplay = (cpf: string) => { - if (cpf.includes(".") || cpf.includes("-")) return cpf; - - const cpfClean = cpf.replace(/\D/g, ""); - - if (cpfClean.length === 11) { - return `${cpfClean.substring(0, 3)}.${cpfClean.substring( - 3, - 6 - )}.${cpfClean.substring(6, 9)}-${cpfClean.substring(9, 11)}`; - } - - return cpf; - }; - - const maskCPF = (cpf: string) => { - const formatted = formatCPFDisplay(cpf); - const parts = formatted.split("."); - if (parts.length === 3) { - const lastPart = parts[2].split("-"); - if (lastPart.length === 2) { - return `${parts[0]}.${parts[1]}.${"***"}-${lastPart[1]}`; - } - } - return formatted; - }; - return ( <div className="flex min-h-screen flex-col items-center justify-center bg-[#f0f5fa] px-4 sm:px-6 lg:px-8"> <div className="w-full max-w-md sm:max-w-lg lg:max-w-xl"> @@ -99,13 +71,6 @@ export default function ConfirmPage() { <div className="text-xs sm:text-sm font-bold text-[#004a93]"> {nome} </div> - - <div className="text-xs sm:text-sm font-medium text-[#004a93]"> - CPF: - </div> - <div className="text-xs sm:text-sm font-bold text-[#004a93]"> - {maskCPF(cpf)} - </div> </div> </div> diff --git a/app/listagem/page.tsx b/app/listagem/page.tsx index c15cdf0..fb4ec98 100644 --- a/app/listagem/page.tsx +++ b/app/listagem/page.tsx @@ -31,6 +31,9 @@ export default function ListVotes() { console.error("Erro ao procurar votos:", error); setSaveStatus("error"); + setSieNumberVotes(0); + setLjNumberVotes(0); + setErrorMessage( "Ocorreu um erro ao procurar votos. Por favor, informe ao responsável." ); @@ -39,11 +42,11 @@ export default function ListVotes() { setNumberVotes(data.length); - const sieData = data.filter((vote) => vote.option_voted == "SIE"); + const sieData = data.filter((vote) => vote.option == "SIE"); setSieNumberVotes(sieData.length); const ljData = data.filter( - (vote) => vote.option_voted == "Liderança Jovem" + (vote) => vote.option == "Liderança Jovem" ); setLjNumberVotes(ljData.length); }; @@ -76,18 +79,21 @@ export default function ListVotes() { className="flex h-40 flex-col items-center justify-center border-2 border-[#004a93] bg-white p-4 text-xl font-bold text-[#004a93] hover:bg-[#e6f0fa]" variant="outline" > - <div className="mb-2 text-4xl">{sieNumberVotes}</div> - SIE + <div className="mb-2 text-4xl">{ljNumberVotes}</div> + Liderança Jovem </Button> <Button className="flex h-40 flex-col items-center justify-center border-2 border-[#004a93] bg-white p-4 text-xl font-bold text-[#004a93] hover:bg-[#e6f0fa]" variant="outline" > - <div className="mb-2 text-4xl">{ljNumberVotes}</div> - Liderança Jovem + <div className="mb-2 text-4xl">{sieNumberVotes}</div> + SIE </Button> </div> <div className="mt-4 text-center text-sm text-[#004a93]"> + Votos totais: {numberVotes} + </div> + <div className="mt-4 text-center text-sm text-[#004a93]"> Todos os dados são em tempo real! </div> </CardContent> diff --git a/app/obrigado/page.tsx b/app/obrigado/page.tsx index 7234012..7805719 100644 --- a/app/obrigado/page.tsx +++ b/app/obrigado/page.tsx @@ -16,7 +16,6 @@ export default function ObrigadoPage() { const searchParams = useSearchParams(); const rm = searchParams.get("rm") || ""; const name = searchParams.get("nome") || ""; - const cpf = searchParams.get("cpf") || ""; const option = searchParams.get("option") || ""; const [countdown, setCountdown] = useState(5); @@ -28,7 +27,7 @@ export default function ObrigadoPage() { const hasRun = useRef(false); useEffect(() => { - if (!rm || !name || !cpf || !option) { + if (!rm || !name || !option) { window.location.href = "/"; return; } @@ -41,8 +40,7 @@ export default function ObrigadoPage() { { rm, name, - cpf: cpf.replace(/\D/g, ""), - option_voted: option, + option, }, ]); @@ -89,7 +87,7 @@ export default function ObrigadoPage() { }, 1000); return () => clearInterval(timer); - }, [rm, name, cpf, option]); + }, [rm, name, option]); return ( <div className="flex min-h-screen flex-col items-center justify-center bg-[#f0f5fa] px-4 sm:px-6 lg:px-8"> diff --git a/app/page.tsx b/app/page.tsx index eb00949..1799a26 100644 --- a/app/page.tsx +++ b/app/page.tsx @@ -18,58 +18,28 @@ import { useRouter } from "next/navigation"; export default function Home() { const [rm, setRm] = useState(""); const [nome, setNome] = useState(""); - const [cpf, setCpf] = useState(""); const [errors, setErrors] = useState<{ rm?: string; nome?: string; - cpf?: string; }>({}); const router = useRouter(); - function validateCPF(cpf: string): boolean { - cpf = cpf.replace(/\D/g, ""); - - if (cpf.length !== 11 || /^(\d)\1{10}$/.test(cpf)) return false; - - const calc = (factor: number) => - cpf - .split("") - .slice(0, factor - 1) - .reduce( - (sum, num, index) => sum + parseInt(num) * (factor - index), - 0 - ) % - 11 < - 2 - ? 0 - : 11 - - (cpf - .split("") - .slice(0, factor - 1) - .reduce( - (sum, num, index) => sum + parseInt(num) * (factor - index), - 0 - ) % - 11); - - return calc(10) === parseInt(cpf[9]) && calc(11) === parseInt(cpf[10]); - } - const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); - const newErrors: { rm?: string; nome?: string; cpf?: string } = {}; + const newErrors: { rm?: string; nome?: string } = {}; if (!/^\d{5}$/.test(rm)) { newErrors.rm = "O RM deve conter exatamente 5 dígitos numéricos."; } - if (!nome || nome.trim().length < 3) { - newErrors.nome = "Por favor, insira seu nome completo."; + const validPrefixes = ["22", "23", "24", "25"]; + if (!validPrefixes.includes(rm.substring(0, 2))) { + newErrors.rm = "O RM não é valido"; } - if (!validateCPF(cpf)) { - newErrors.cpf = "CPF inválido. Insira um CPF válido com 11 dígitos."; + if (!nome || nome.trim().length < 3) { + newErrors.nome = "Por favor, insira seu nome completo."; } if (Object.keys(newErrors).length > 0) { @@ -79,150 +49,102 @@ export default function Home() { setErrors({}); - router.push( - `/confirmar?rm=${rm}&nome=${encodeURIComponent(nome)}&cpf=${cpf}` - ); - }; - - const formatCPF = (value: string) => { - const cpfClean = value.replace(/\D/g, ""); - let formatted = cpfClean; - - if (cpfClean.length > 3) { - formatted = cpfClean.substring(0, 3) + "." + cpfClean.substring(3); - } - if (cpfClean.length > 6) { - formatted = formatted.substring(0, 7) + "." + cpfClean.substring(6, 9); - } - if (cpfClean.length > 9) { - formatted = formatted.substring(0, 11) + "-" + cpfClean.substring(9, 11); - } - - return formatted; - }; - - const handleCPFChange = (e: React.ChangeEvent<HTMLInputElement>) => { - const value = e.target.value; - const formatted = formatCPF(value); - setCpf(formatted); - - if (errors.cpf) { - setErrors((prev) => ({ ...prev, cpf: undefined })); - } + router.push(`/confirmar?rm=${rm}&nome=${encodeURIComponent(nome)}`); }; return ( <div className="flex min-h-screen flex-col items-center justify-center bg-[#f0f5fa] px-4 sm:px-6 lg:px-8"> <div className="w-full max-w-md"> - <div className="mb-6 flex items-center justify-center"> - <div className="flex flex-col items-center"> - <div className="mb-2 text-center text-2xl sm:text-3xl font-bold text-[#004a93]"> - JUSTIÇA ELEITORAL ESTUDANTIL - </div> - <div className="h-2 w-full bg-gradient-to-r from-[#009c3b] via-[#ffdf00] to-[#002776]"></div> - </div> - </div> - - <Card className="border-2 border-[#004a93] shadow-lg overflow-hidden"> - <CardHeader className="bg-[#004a93] text-center text-white"> - <CardTitle className="text-xl sm:text-2xl">ELEIÇÕES ESTUDANTIS</CardTitle> - <CardDescription className="text-gray-100"> - Identificação do Eleitor - </CardDescription> - </CardHeader> - <CardContent className="pt-6"> - <form onSubmit={handleSubmit} className="space-y-4"> - <div className="space-y-2"> - <label - htmlFor="rm" - className="text-sm font-medium text-[#004a93]" - > - Digite seu RM: - </label> - <Input - id="rm" - type="text" - value={rm} - onChange={(e) => { - setRm(e.target.value); - if (errors.rm) { - setErrors((prev) => ({ ...prev, rm: undefined })); - } - }} - placeholder="Digite os 5 dígitos do seu RM" - className="border-2 border-[#004a93]" - maxLength={5} - /> - {errors.rm && ( - <p className="text-sm text-red-500">{errors.rm}</p> - )} - </div> - - <div className="space-y-2"> - <label - htmlFor="nome" - className="text-sm font-medium text-[#004a93]" - > - Digite seu nome completo: - </label> - <Input - id="nome" - type="text" - value={nome} - onChange={(e) => { - setNome(e.target.value); - if (errors.nome) { - setErrors((prev) => ({ ...prev, nome: undefined })); - } - }} - placeholder="Digite seu nome completo" - className="border-2 border-[#004a93]" - /> - {errors.nome && ( - <p className="text-sm text-red-500">{errors.nome}</p> - )} + <div className="mb-6 flex items-center justify-center"> + <div className="flex flex-col items-center"> + <div className="mb-2 text-center text-2xl sm:text-3xl font-bold text-[#004a93]"> + JUSTIÇA ELEITORAL ESTUDANTIL + </div> + <div className="h-2 w-full bg-gradient-to-r from-[#009c3b] via-[#ffdf00] to-[#002776]"></div> </div> + </div> - <div className="space-y-2"> - <label - htmlFor="cpf" - className="text-sm font-medium text-[#004a93]" - > - Digite seu CPF: - </label> - <Input - id="cpf" - type="text" - value={cpf} - onChange={handleCPFChange} - placeholder="Digite seu CPF" - className="border-2 border-[#004a93]" - maxLength={14} - /> - {errors.cpf && ( - <p className="text-sm text-red-500">{errors.cpf}</p> - )} + <Card className="border-2 border-[#004a93] shadow-lg overflow-hidden"> + <CardHeader className="bg-[#004a93] text-center text-white"> + <CardTitle className="text-xl sm:text-2xl"> + ELEIÇÕES ESTUDANTIS + </CardTitle> + <CardDescription className="text-gray-100"> + Identificação do Eleitor + </CardDescription> + </CardHeader> + <CardContent className="pt-6"> + <form onSubmit={handleSubmit} className="space-y-4"> + <div className="space-y-2"> + <label + htmlFor="rm" + className="text-sm font-medium text-[#004a93]" + > + Digite seu RM: + </label> + <Input + id="rm" + type="text" + value={rm} + onChange={(e) => { + setRm(e.target.value); + if (errors.rm) { + setErrors((prev) => ({ ...prev, rm: undefined })); + } + }} + placeholder="Digite os 5 dígitos do seu RM" + className="border-2 border-[#004a93]" + maxLength={5} + /> + {errors.rm && ( + <p className="text-sm text-red-500">{errors.rm}</p> + )} + </div> + + <div className="space-y-2"> + <label + htmlFor="nome" + className="text-sm font-medium text-[#004a93]" + > + Digite seu nome completo: + </label> + <Input + id="nome" + type="text" + value={nome} + onChange={(e) => { + setNome(e.target.value); + if (errors.nome) { + setErrors((prev) => ({ ...prev, nome: undefined })); + } + }} + placeholder="Digite seu nome completo" + className="border-2 border-[#004a93]" + /> + {errors.nome && ( + <p className="text-sm text-red-500">{errors.nome}</p> + )} + </div> + + <Button + type="submit" + className="w-full bg-[#004a93] text-white hover:bg-[#003a73]" + > + CONFIRMAR + </Button> + </form> + </CardContent> + <CardFooter className="flex justify-center border-t border-[#004a93] bg-[#f8f8f8] py-3 text-sm text-[#004a93] rounded-b-lg"> + Seu voto é secreto e seguro. + </CardFooter> + </Card> + + <div className="mt-4 flex justify-center"> + <div className="text-center text-sm text-[#004a93]"> + © {new Date().getFullYear()} Justiça Eleitoral Estudantil </div> - - <Button - type="submit" - className="w-full bg-[#004a93] text-white hover:bg-[#003a73]" - > - CONFIRMAR - </Button> - </form> - </CardContent> - <CardFooter className="flex justify-center border-t border-[#004a93] bg-[#f8f8f8] py-3 text-sm text-[#004a93] rounded-b-lg"> - Seu voto é secreto e seguro. - </CardFooter> - </Card> - - <div className="mt-4 flex justify-center"> - <div className="text-center text-sm text-[#004a93]"> - © {new Date().getFullYear()} Justiça Eleitoral Estudantil </div> </div> - </div> </div> ); } diff --git a/app/votar/page.tsx b/app/votar/page.tsx index 5ca0cb4..6d0efdc 100644 --- a/app/votar/page.tsx +++ b/app/votar/page.tsx @@ -16,31 +16,28 @@ export default function VotarPage() { const searchParams = useSearchParams(); const rm = searchParams.get("rm") || ""; const nome = searchParams.get("nome") || ""; - const cpf = searchParams.get("cpf") || ""; const [selectedOption, setSelectedOption] = useState<string | null>(null); - const [audioElement, setAudioElement] = useState<HTMLAudioElement>() + const [audioElement, setAudioElement] = useState<HTMLAudioElement>(); useEffect(() => { - if (!rm || !nome || !cpf) { + if (!rm || !nome) { router.push("/"); return; } - const audio = new Audio('/confirma.mp3') - setAudioElement(audio) - }, [rm, nome, cpf, router]); + const audio = new Audio("/confirma.mp3"); + setAudioElement(audio); + }, [rm, nome, router]); const handleVote = (option: string) => { setSelectedOption(option); if (!audioElement) return; - audioElement.play() + audioElement.play(); setTimeout(() => { router.push( - `/obrigado?rm=${rm}&nome=${encodeURIComponent( - nome - )}&cpf=${cpf}&option=${option}` + `/obrigado?rm=${rm}&nome=${encodeURIComponent(nome)}&option=${option}` ); }, 500); }; @@ -48,53 +45,53 @@ export default function VotarPage() { return ( <div className="flex min-h-screen flex-col items-center justify-center bg-[#f0f5fa] p-4"> <div className="w-full max-w-md md:max-w-2xl"> - <div className="mb-6 flex items-center justify-center"> - <div className="flex flex-col items-center"> - <div className="mb-2 text-center text-2xl font-bold text-[#004a93] md:text-3xl"> - JUSTIÇA ELEITORAL ESTUDANTIL + <div className="mb-6 flex items-center justify-center"> + <div className="flex flex-col items-center"> + <div className="mb-2 text-center text-2xl font-bold text-[#004a93] md:text-3xl"> + JUSTIÇA ELEITORAL ESTUDANTIL + </div> + <div className="h-2 w-full bg-gradient-to-r from-[#009c3b] via-[#ffdf00] to-[#002776]"></div> + </div> </div> - <div className="h-2 w-full bg-gradient-to-r from-[#009c3b] via-[#ffdf00] to-[#002776]"></div> - </div> - </div> - <Card className="border-2 border-[#004a93] shadow-lg overflow-hidden"> - <CardHeader className="bg-[#004a93] text-center text-white"> - <CardTitle className="text-xl md:text-2xl">SEU VOTO PARA</CardTitle> - <CardDescription className="text-gray-100"> - CHAPA DO GREMIO ESTUDANTIL - </CardDescription> - </CardHeader> - <CardContent className="space-y-6 p-4 md:p-6 rounded-b-lg"> - <div className="grid grid-cols-1 gap-4 md:grid-cols-2 md:gap-6"> - <Button - onClick={() => handleVote("SIE")} - className="flex h-32 flex-col items-center justify-center border-2 border-[#004a93] bg-white p-4 text-lg font-bold text-[#004a93] hover:bg-[#e6f0fa] md:h-40 md:text-xl" - variant="outline" - > - <div className="mb-2 text-3xl md:text-4xl">1</div> - SIE - </Button> - <Button - onClick={() => handleVote("Liderança Jovem")} - className="flex h-32 flex-col items-center justify-center border-2 border-[#004a93] bg-white p-4 text-lg font-bold text-[#004a93] hover:bg-[#e6f0fa] md:h-40 md:text-xl" - variant="outline" - > - <div className="mb-2 text-3xl md:text-4xl">2</div> - Liderança Jovem - </Button> - </div> - <div className="mt-4 text-center text-sm text-[#004a93] md:text-base"> - Toque no quadro correspondente para VOTAR - </div> - </CardContent> - </Card> + <Card className="border-2 border-[#004a93] shadow-lg overflow-hidden"> + <CardHeader className="bg-[#004a93] text-center text-white"> + <CardTitle className="text-xl md:text-2xl">SEU VOTO PARA</CardTitle> + <CardDescription className="text-gray-100"> + CHAPA DO GREMIO ESTUDANTIL + </CardDescription> + </CardHeader> + <CardContent className="space-y-6 p-4 md:p-6 rounded-b-lg"> + <div className="grid grid-cols-1 gap-4 md:grid-cols-2 md:gap-6"> + <Button + onClick={() => handleVote("Liderança Jovem")} + className="flex h-32 flex-col items-center justify-center border-2 border-[#004a93] bg-white p-4 text-lg font-bold text-[#004a93] hover:bg-[#e6f0fa] md:h-40 md:text-xl" + variant="outline" + > + <div className="mb-2 text-3xl md:text-4xl">1</div> + Liderança Jovem + </Button> + <Button + onClick={() => handleVote("SIE")} + className="flex h-32 flex-col items-center justify-center border-2 border-[#004a93] bg-white p-4 text-lg font-bold text-[#004a93] hover:bg-[#e6f0fa] md:h-40 md:text-xl" + variant="outline" + > + <div className="mb-2 text-3xl md:text-4xl">2</div> + SIE + </Button> + </div> + <div className="mt-4 text-center text-sm text-[#004a93] md:text-base"> + Toque no quadro correspondente para VOTAR + </div> + </CardContent> + </Card> - <div className="mt-4 flex justify-center"> - <div className="text-center text-sm text-[#004a93] md:text-base"> - © {new Date().getFullYear()} Justiça Eleitoral Estudantil + <div className="mt-4 flex justify-center"> + <div className="text-center text-sm text-[#004a93] md:text-base"> + © {new Date().getFullYear()} Justiça Eleitoral Estudantil + </div> </div> </div> - </div> </div> ); } diff --git a/database.sql b/database.sql index 78b23cf..226fa2f 100644 --- a/database.sql +++ b/database.sql @@ -1,11 +1,9 @@ CREATE TABLE votes ( - id SERIAL PRIMARY KEY, - rm VARCHAR(5) NOT NULL, + rm VARCHAR(5) PRIMARY KEY, name VARCHAR(100) NOT NULL, - cpf VARCHAR(11) NOT NULL, - option_voted VARCHAR(50), + option VARCHAR(50), voted_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(), - UNIQUE(rm, cpf) + UNIQUE(rm, name) ); -CREATE INDEX idx_votes_rm_cpf ON votes(rm, cpf);
\ No newline at end of file +CREATE INDEX idx_votes_rm_name ON votes(rm, name);
\ No newline at end of file |