aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzwlucas <lucas.oliveira1676@etec.sp.gov.br>2025-04-01 17:30:52 +0000
committerzwlucas <lucas.oliveira1676@etec.sp.gov.br>2025-04-01 17:30:52 +0000
commita7a6e965979f7c46c2511a33cb601172573f3c84 (patch)
treefafef5889ca77346cdcbd1c4a3db9cc34268c82f
parente99de28b064275cdd0b04b98c6c3f50e85c01d7c (diff)
downloadeleicoes-a7a6e965979f7c46c2511a33cb601172573f3c84.tar.gz
eleicoes-a7a6e965979f7c46c2511a33cb601172573f3c84.zip
removed cpf
-rw-r--r--app/confirmar/page.tsx41
-rw-r--r--app/listagem/page.tsx18
-rw-r--r--app/obrigado/page.tsx8
-rw-r--r--app/page.tsx262
-rw-r--r--app/votar/page.tsx101
-rw-r--r--database.sql10
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