Skip to content

Commit

Permalink
feat: 💄 Ajustado responsividade para mobile
Browse files Browse the repository at this point in the history
Closes #181
  • Loading branch information
LiloMarino committed Nov 9, 2024
1 parent 601b074 commit 4787f4e
Show file tree
Hide file tree
Showing 12 changed files with 223 additions and 89 deletions.
44 changes: 23 additions & 21 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -150,27 +150,29 @@ function App() {
<ToastProvider>
<Router basename="/Quiz-RPG">
<NavbarRPG />
<Routes>
<Route path="/" element={<Home />} />
<Route path="/home" element={<Home />} />
<Route path="/caracteristicas" element={<Caracteristicas />} />
<Route path="/classes" element={<Classes />} />
<Route path="/racas" element={<Racas />} />
<Route path="/backgrounds" element={<Backgrounds />} />
<Route path="/tags" element={<Tags />} />
<Route path="/perguntas" element={<Perguntas />} />
<Route path="/questionarios" element={<Questionarios />} />
<Route path="/responder/:id" element={<Responder />} />
<Route path="/editar-tag/:id" element={<EditarTag />} />
<Route path="/editar-background/:id" element={<EditarBackground />} />
<Route path="/editar-classe/:id" element={<EditarClasse />} />
<Route path="/editar-raca/:id" element={<EditarRaca />} />
<Route path="/editar-pergunta/:id" element={<EditarPergunta />} />
<Route path="/editar-questionario/:id" element={<EditarQuestionario />} />
<Route path="/criar-questionario" element={<CriarQuestionario />} />
<Route path="/resultado" element={<Resultado />} />
<Route path="/import" element={<Import />} />
</Routes>
<div className="mb-5">
<Routes>
<Route path="/" element={<Home />} />
<Route path="/home" element={<Home />} />
<Route path="/caracteristicas" element={<Caracteristicas />} />
<Route path="/classes" element={<Classes />} />
<Route path="/racas" element={<Racas />} />
<Route path="/backgrounds" element={<Backgrounds />} />
<Route path="/tags" element={<Tags />} />
<Route path="/perguntas" element={<Perguntas />} />
<Route path="/questionarios" element={<Questionarios />} />
<Route path="/responder/:id" element={<Responder />} />
<Route path="/editar-tag/:id" element={<EditarTag />} />
<Route path="/editar-background/:id" element={<EditarBackground />} />
<Route path="/editar-classe/:id" element={<EditarClasse />} />
<Route path="/editar-raca/:id" element={<EditarRaca />} />
<Route path="/editar-pergunta/:id" element={<EditarPergunta />} />
<Route path="/editar-questionario/:id" element={<EditarQuestionario />} />
<Route path="/criar-questionario" element={<CriarQuestionario />} />
<Route path="/resultado" element={<Resultado />} />
<Route path="/import" element={<Import />} />
</Routes>
</div>
</Router>

{/* Modal de Patch Notes */}
Expand Down
8 changes: 4 additions & 4 deletions src/components/QuizCreate.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export const QuizCreate: React.FC<QuizCreateProps> = ({ perguntas }) => {
// Salvar Questionário
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();

// Validação do nome do questionário
newQuiz.nome = newQuiz.nome.trim();
if (newQuiz.nome === "") {
Expand All @@ -65,9 +65,9 @@ export const QuizCreate: React.FC<QuizCreateProps> = ({ perguntas }) => {
};

return (
<Container className="h-100 mt-3">
<Row className="align-items-center h-100">
<Col xs={6} className="mx-auto">
<Container className="mt-3">
<Row>
<Col md={{ span: 6, offset: 3 }}>
<Card>
<Card.Body>
<Form onSubmit={handleSubmit}>
Expand Down
6 changes: 3 additions & 3 deletions src/components/QuizEdit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,9 @@ export const QuizEdit: React.FC<QuizEditProps> = ({ id }) => {
}, [id]);

return (
<Container className="h-100 mt-3">
<Row className="align-items-center h-100">
<Col xs={6} className="mx-auto">
<Container className="mt-3">
<Row>
<Col md={{ span: 6, offset: 3 }}>
<Card>
<Card.Body>
<Form onSubmit={handleSubmit}>
Expand Down
6 changes: 3 additions & 3 deletions src/components/QuizMasterCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ export const QuizMasterCard: React.FC<QuizMasterCardProps> = ({ questionario, on
};

return (
<Container className="h-100 mt-3">
<Row className="align-items-center h-100">
<Col xs={6} className="mx-auto">
<Container className="mt-3">
<Row>
<Col md={{ span: 6, offset: 3 }}>
<Card>
<Card.Body>
<Card.Title>{questionario.nome}</Card.Title>
Expand Down
8 changes: 4 additions & 4 deletions src/components/ResultPodium.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ interface ResultPodiumProps {
const ResultPodium: React.FC<ResultPodiumProps> = ({ top3 }) => {
return (
<Container className="h-100">
<Row>
<Col xs={4}>
<Row className="justify-content-center">
<Col xs={12} sm={6} md={4} className="mb-3">
<ResultCard
title={top3[2]?.nome}
imageSrc={top3[2]?.url_imagem}
Expand All @@ -19,7 +19,7 @@ const ResultPodium: React.FC<ResultPodiumProps> = ({ top3 }) => {
placement={3}
/>
</Col>
<Col xs={4}>
<Col xs={12} sm={6} md={4} className="mb-3">
<ResultCard
title={top3[0]?.nome}
imageSrc={top3[0]?.url_imagem}
Expand All @@ -28,7 +28,7 @@ const ResultPodium: React.FC<ResultPodiumProps> = ({ top3 }) => {
placement={1}
/>
</Col>
<Col xs={4}>
<Col xs={12} sm={6} md={4} className="mb-3">
<ResultCard
title={top3[1]?.nome}
imageSrc={top3[1]?.url_imagem}
Expand Down
57 changes: 52 additions & 5 deletions src/components/TraitCard.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import React from "react";
import { Container, Row, Col, Card } from "react-bootstrap";
import React, { useState } from "react";
import { Container, Row, Col, Card, Accordion, useAccordionButton } from "react-bootstrap";
import { CaracteristicaWithTags, TipoCaracteristica } from "../types";
import TagList from "./TagList";
import silhueta from "../assets/img/silhueta.png";
import { useToast } from "../context/ToastContext";
import { faChevronDown, faChevronUp } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";

interface TraitCardProps {
tipo: TipoCaracteristica;
Expand All @@ -12,26 +14,71 @@ interface TraitCardProps {

const TraitCard: React.FC<TraitCardProps> = ({ tipo, caracteristicas }) => {
const { showToast } = useToast();
const [activeKey, setActiveKey] = useState<string | null>(null);

const handleCardClick = (caracteristica: CaracteristicaWithTags) => {
if (caracteristica.url_referencia) {
// Se houver um link de referência, redireciona
window.open(caracteristica.url_referencia, "_blank");
} else {
// Se não houver link de referência, mostra um toast de aviso
showToast("Esta característica não possui um link de referência.", "warning");
}
};

// Componente CustomToggle com ícones do FontAwesome
const CustomToggle = ({ eventKey }: { eventKey: string }) => {
const decoratedOnClick = useAccordionButton(eventKey, () =>
setActiveKey(activeKey === eventKey ? null : eventKey)
);

const isExpanded = activeKey === eventKey;
return (
<Card.Header
onClick={decoratedOnClick}
className="d-flex justify-content-between align-items-center p-3 border-top"
style={{ backgroundColor: "#f8f9fa", cursor: "pointer" }}
>
<span>Clique para ver a imagem</span>
<FontAwesomeIcon icon={isExpanded ? faChevronUp : faChevronDown} />
</Card.Header>
);
};

return (
<Container className="mt-5">
<Row>
{caracteristicas
.filter((caracteristica) => caracteristica.tipo === tipo)
.map((caracteristica) => (
<Col key={caracteristica.id_caracteristica} md={4} className="mb-4">
{/* Accordion para Mobile */}
<Accordion activeKey={activeKey} className="d-md-none">
<Card className="mb-3" style={{ cursor: "pointer" }}>
<Card.Body onClick={() => handleCardClick(caracteristica)}>
<Card.Title>{caracteristica.nome}</Card.Title>
<h6>Descrição</h6>
<Card.Text>{caracteristica.descricao}</Card.Text>
<TagList tags={caracteristica.tags} />
</Card.Body>
<CustomToggle eventKey={caracteristica.id_caracteristica!.toString()} />
<Accordion.Collapse eventKey={caracteristica.id_caracteristica!.toString()}>
<Card.Body className="p-0" style={{ borderTop: "1px solid #ddd" }}>
<Card.Img
src={caracteristica.url_imagem || silhueta}
alt={caracteristica.nome}
style={{
objectFit: "contain",
width: "100%",
maxHeight: "500px",
}}
/>
</Card.Body>
</Accordion.Collapse>
</Card>
</Accordion>

{/* Layout para Desktop */}
<Card
className="mb-3"
className="d-none d-md-flex mb-3"
style={{ maxWidth: "540px", height: "300px", cursor: "pointer" }}
onClick={() => handleCardClick(caracteristica)}
>
Expand Down
84 changes: 78 additions & 6 deletions src/components/TraitMasterCard.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useState } from "react";
import { Card, Row, Col, Button, Modal } from "react-bootstrap";
import { Card, Row, Col, Button, Modal, useAccordionButton, Accordion } from "react-bootstrap";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faPen, faTrash } from "@fortawesome/free-solid-svg-icons";
import { faChevronDown, faChevronUp, faPen, faTrash } from "@fortawesome/free-solid-svg-icons";
import { CaracteristicaWithTags } from "../types";
import TagList from "./TagList";
import silhueta from "../assets/img/silhueta.png";
Expand All @@ -14,6 +14,7 @@ interface TraitMasterCardProps {

const TraitMasterCard: React.FC<TraitMasterCardProps> = ({ caracteristica, handleEdit, handleDelete }) => {
const [showDeleteModal, setShowDeleteModal] = useState(false);
const [activeKey, setActiveKey] = useState<string | null>(null);

// Função para abrir o modal
const openDeleteModal = () => setShowDeleteModal(true);
Expand All @@ -24,12 +25,73 @@ const TraitMasterCard: React.FC<TraitMasterCardProps> = ({ caracteristica, handl
// Função para confirmar a exclusão
const confirmDelete = async () => {
await handleDelete(caracteristica.id_caracteristica!);
closeDeleteModal(); // Fecha o modal após exclusão
closeDeleteModal();
};

// Componente CustomToggle com ícones do FontAwesome
const CustomToggle = ({ eventKey }: { eventKey: string }) => {
const decoratedOnClick = useAccordionButton(eventKey, () => setActiveKey(activeKey === eventKey ? null : eventKey));
const isExpanded = activeKey === eventKey;

return (
<Card.Header
onClick={decoratedOnClick}
className="d-flex justify-content-between align-items-center p-3 border-top"
style={{ backgroundColor: "#f8f9fa", cursor: "pointer" }}
>
<span>Clique para ver a imagem</span>
<FontAwesomeIcon icon={isExpanded ? faChevronUp : faChevronDown} />
</Card.Header>
);
};

return (
<>
<Card key={caracteristica.id_caracteristica} className="mb-3">
{/* Accordion para Mobile */}
<Accordion activeKey={activeKey} className="d-md-none">
<Card className="mb-3" style={{ cursor: "pointer" }}>
<Card.Body>
<Card.Title>{caracteristica.nome}</Card.Title>
<h6>Descrição</h6>
<Card.Text>{caracteristica.descricao}</Card.Text>
<TagList tags={caracteristica.tags} />
</Card.Body>
<CustomToggle eventKey={caracteristica.id_caracteristica!.toString()} />
<Accordion.Collapse eventKey={caracteristica.id_caracteristica!.toString()}>
<Card.Body className="p-0" style={{ borderTop: "1px solid #ddd" }}>
<Card.Img
src={caracteristica.url_imagem || silhueta}
alt={caracteristica.nome}
style={{
objectFit: "contain",
width: "100%",
maxHeight: "500px",
}}
/>
</Card.Body>
</Accordion.Collapse>
<div className="d-flex justify-content-between p-3">
<Button
variant="warning"
className="flex-grow-1 text-white"
onClick={() => handleEdit(caracteristica.id_caracteristica!)}
style={{ marginRight: "10px" }}
>
<FontAwesomeIcon icon={faPen} />
</Button>
<Button
variant="danger"
className="flex-grow-1"
onClick={openDeleteModal}
>
<FontAwesomeIcon icon={faTrash} />
</Button>
</div>
</Card>
</Accordion>

{/* Layout para Desktop */}
<Card key={caracteristica.id_caracteristica} className="d-none d-md-flex mb-3">
<Row>
<Col md={6}>
<Card.Body>
Expand All @@ -39,7 +101,15 @@ const TraitMasterCard: React.FC<TraitMasterCardProps> = ({ caracteristica, handl
</Card.Body>
</Col>
<Col md={4}>
<Card.Img src={caracteristica.url_imagem || silhueta} alt={caracteristica.nome} />
<Card.Img
src={caracteristica.url_imagem || silhueta}
alt={caracteristica.nome}
style={{
width: "100%",
height: "auto",
objectFit: "cover",
}}
/>
</Col>
<Col md={2} className="d-flex flex-column justify-content-center align-items-center">
<Button
Expand All @@ -62,7 +132,9 @@ const TraitMasterCard: React.FC<TraitMasterCardProps> = ({ caracteristica, handl
<Modal.Title>Confirmação de Exclusão</Modal.Title>
</Modal.Header>
<Modal.Body>
Tem certeza que deseja excluir a característica "{caracteristica.nome}"?<br/><b>Esta ação não pode ser desfeita.</b>
Tem certeza que deseja excluir a característica "{caracteristica.nome}"?
<br />
<b>Esta ação não pode ser desfeita.</b>
</Modal.Body>
<Modal.Footer>
<Button variant="secondary" onClick={closeDeleteModal}>
Expand Down
Loading

0 comments on commit 4787f4e

Please sign in to comment.