From b22d757bd71ee01c24a6c5d846bdd2549ae163ad Mon Sep 17 00:00:00 2001 From: Simurgan Date: Thu, 13 Feb 2025 13:54:01 +0300 Subject: [PATCH 01/16] feat: add new map tiles fix: fix redirect problem --- mappafront/public/_redirects | 1 + mappafront/src/views/pages/map/index.tsx | 22 +++++++++++++++++++--- 2 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 mappafront/public/_redirects diff --git a/mappafront/public/_redirects b/mappafront/public/_redirects new file mode 100644 index 0000000..7797f7c --- /dev/null +++ b/mappafront/public/_redirects @@ -0,0 +1 @@ +/* /index.html 200 diff --git a/mappafront/src/views/pages/map/index.tsx b/mappafront/src/views/pages/map/index.tsx index f61d3b8..89fb999 100644 --- a/mappafront/src/views/pages/map/index.tsx +++ b/mappafront/src/views/pages/map/index.tsx @@ -70,10 +70,26 @@ const MapPage = () => {
- + + {markers.map((item) => ( Date: Tue, 18 Feb 2025 14:23:06 +0300 Subject: [PATCH 02/16] feat: add map view filters --- mappafront/src/models/map-filters.ts | 5 ++ mappafront/src/views/pages/map/index.tsx | 47 ++++++++++++++++- mappafront/src/views/pages/map/style.scss | 64 ++++++++++++++++++++++- 3 files changed, 113 insertions(+), 3 deletions(-) create mode 100644 mappafront/src/models/map-filters.ts diff --git a/mappafront/src/models/map-filters.ts b/mappafront/src/models/map-filters.ts new file mode 100644 index 0000000..bac624f --- /dev/null +++ b/mappafront/src/models/map-filters.ts @@ -0,0 +1,5 @@ +export interface FilterGroup { + group: string; + key: string; + options: string[]; +} diff --git a/mappafront/src/views/pages/map/index.tsx b/mappafront/src/views/pages/map/index.tsx index 89fb999..0d42b81 100644 --- a/mappafront/src/views/pages/map/index.tsx +++ b/mappafront/src/views/pages/map/index.tsx @@ -6,9 +6,35 @@ import Text from "@/views/components/text"; import React, { useState } from "react"; import Button from "@/views/components/button"; import ReactModal from "react-modal"; +import { FilterGroup } from "@/models/map-filters"; ReactModal.setAppElement("#root"); // For blocking not working modal styles in some browsers. +const filters: FilterGroup[] = [ + { + group: "Location Types", + key: "location", + options: ["Cities", "Villages", "Castles", "Caravansarries", "Other"], + }, + { + group: "Document Types", + key: "documents", + options: [ + "All", + "Waqfiyas", + "Manakibnames", + "Tawarikhs", + "Travel Books", + "Other", + ], + }, + { + group: "Survival Status", + key: "survival", + options: ["All", "Survived", "Unsurvived"], + }, +]; + const MapPage = () => { const [modalIsOpen, setIsOpen] = React.useState(false); const [selectedMarker, setSelectedMarker] = useState(); @@ -122,7 +148,26 @@ const MapPage = () => { ))}
-
+
+ +
+ {filters.map((filterGroup) => ( +
+ + {filterGroup.group} + + {filterGroup.options.map((option) => ( +
+ + + {option} + +
+ ))} +
+ ))} +
+
); diff --git a/mappafront/src/views/pages/map/style.scss b/mappafront/src/views/pages/map/style.scss index 5b4ce66..3d43287 100644 --- a/mappafront/src/views/pages/map/style.scss +++ b/mappafront/src/views/pages/map/style.scss @@ -65,8 +65,68 @@ section.section.map-section { .map-tools-container { width: $tools-width; - height: 100%; - background-color: blue; + border: 8px solid $color-primary; + border-top: 0; + display: flex; + flex-direction: column; + + .map-search-input { + width: 100%; + border: 8px solid $color-primary; + border-left: 0; + border-right: 0; + } + + .map-search-input:focus { + outline: none; + } + + .map-filters-container { + .filter-group { + display: flex; + flex-direction: column; + gap: 9px; + padding: 0.2rem 0 0.2rem 0.3rem; + border-bottom: 8px solid $color-primary; + + .filter-item { + display: flex; + flex-direction: row; + align-items: center; + gap: 6px; + + .checkbox-input { + appearance: none; /* Tarayıcı varsayılan stilini kaldır */ + -webkit-appearance: none; + -moz-appearance: none; + + width: 16px; + height: 16px; + border: 2px solid $color-primary; + background-color: $color-secondary; + cursor: pointer; + border-radius: 3px; + display: inline-block; + position: relative; + } + + .checkbox-input:checked { + background-color: $color-primary; + border-color: $color-primary; + } + + .checkbox-input:checked::after { + content: "✓"; + font-size: 12px; + color: white; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + } + } + } + } } } } From b992599ae730127c1cef0060e3a4c2b365b86829 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20K=C4=B1z=C4=B1lay?= Date: Thu, 30 Jan 2025 17:35:27 +0300 Subject: [PATCH 03/16] feat: add ordinary page action header --- .../src/views/pages/ordinary-people/index.tsx | 33 ++++++++++++- .../views/pages/ordinary-people/style.scss | 49 +++++++++++++++++++ 2 files changed, 81 insertions(+), 1 deletion(-) create mode 100644 mappafront/src/views/pages/ordinary-people/style.scss diff --git a/mappafront/src/views/pages/ordinary-people/index.tsx b/mappafront/src/views/pages/ordinary-people/index.tsx index 7bff1bf..bb5b7a9 100644 --- a/mappafront/src/views/pages/ordinary-people/index.tsx +++ b/mappafront/src/views/pages/ordinary-people/index.tsx @@ -1,4 +1,35 @@ +import Text from "@/views/components/text"; +import "./style.scss"; +import Button from "@/views/components/button"; + const OrdinaryPeoplePage = () => { - return
OrdinaryPeoplePage
; + return ( +
+
+
+ + Unordinary People
+ + in the context of their relationship with ordinary people + +
+ +
+ + + +
+
+
+
+ ); }; export default OrdinaryPeoplePage; diff --git a/mappafront/src/views/pages/ordinary-people/style.scss b/mappafront/src/views/pages/ordinary-people/style.scss new file mode 100644 index 0000000..9c5e103 --- /dev/null +++ b/mappafront/src/views/pages/ordinary-people/style.scss @@ -0,0 +1,49 @@ +@use "@/assets/mixins.scss" as *; +@use "@/assets/variables.scss" as *; + +section.section.ordinary-section { + .container { + padding: 0; + margin: 0; + max-width: 100%; + width: 100%; + + .page-head { + width: 100%; + height: 1.92rem; + display: flex; + flex-direction: column; + justify-content: center; + padding-left: 2rem; + background-color: $color-primary; + gap: 0.16rem; + + .page-head-actions-container { + display: flex; + flex-direction: row; + gap: 0.16rem; + + .action-button { + background-color: $color-secondary; + border: none; + height: 0.4rem; + width: fit-content; + padding: 0 0.28rem; + + &:hover { + cursor: pointer; + } + } + + .action-input { + width: 3.4rem; + height: 0.4rem; + border: 2px solid white; + padding: 0 0.2rem; + color: $color-secondary; + background-color: transparent; + } + } + } + } +} From 82d2f7a8e67da581327f30c816bfa3822a256ee3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20K=C4=B1z=C4=B1lay?= Date: Thu, 30 Jan 2025 17:38:58 +0300 Subject: [PATCH 04/16] fix: some ui and stylefixs --- mappafront/src/views/pages/ordinary-people/index.tsx | 5 +---- mappafront/src/views/pages/ordinary-people/style.scss | 3 ++- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/mappafront/src/views/pages/ordinary-people/index.tsx b/mappafront/src/views/pages/ordinary-people/index.tsx index bb5b7a9..0da28a1 100644 --- a/mappafront/src/views/pages/ordinary-people/index.tsx +++ b/mappafront/src/views/pages/ordinary-people/index.tsx @@ -8,10 +8,7 @@ const OrdinaryPeoplePage = () => {
- Unordinary People
- - in the context of their relationship with ordinary people - + Ordinary People
diff --git a/mappafront/src/views/pages/ordinary-people/style.scss b/mappafront/src/views/pages/ordinary-people/style.scss index 9c5e103..1fe0421 100644 --- a/mappafront/src/views/pages/ordinary-people/style.scss +++ b/mappafront/src/views/pages/ordinary-people/style.scss @@ -2,6 +2,7 @@ @use "@/assets/variables.scss" as *; section.section.ordinary-section { + padding-top: 0; .container { padding: 0; margin: 0; @@ -16,7 +17,7 @@ section.section.ordinary-section { justify-content: center; padding-left: 2rem; background-color: $color-primary; - gap: 0.16rem; + gap: 0.4rem; .page-head-actions-container { display: flex; From 3ce60029e491bf02ca12cdb51986282ceb678d68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20K=C4=B1z=C4=B1lay?= Date: Mon, 3 Feb 2025 12:04:48 +0300 Subject: [PATCH 05/16] feat: add basic tablecomponent --- .../src/views/components/table/index.tsx | 46 ++++++++++++++++ .../src/views/components/table/style.scss | 55 +++++++++++++++++++ .../src/views/pages/ordinary-people/index.tsx | 18 ++++++ .../views/pages/ordinary-people/style.scss | 5 ++ 4 files changed, 124 insertions(+) create mode 100644 mappafront/src/views/components/table/index.tsx create mode 100644 mappafront/src/views/components/table/style.scss diff --git a/mappafront/src/views/components/table/index.tsx b/mappafront/src/views/components/table/index.tsx new file mode 100644 index 0000000..7f0d866 --- /dev/null +++ b/mappafront/src/views/components/table/index.tsx @@ -0,0 +1,46 @@ +import Text from "../text"; +import "./style.scss"; + +interface TableData { + [key: string]: any; +} + +interface TableProps { + headers: string[]; + data: TableData[]; +} + +const Table = ({ headers, data }: TableProps) => { + return ( +
+ + + + {headers.map((item: string) => ( + + ))} + + + + {data.map((item, index) => ( + + {Object.keys(item).map((itemKey, subIndex) => ( + + ))} + + ))} + +
+ + {item} + +
+ + {item[itemKey]} + +
+
+ ); +}; + +export default Table; diff --git a/mappafront/src/views/components/table/style.scss b/mappafront/src/views/components/table/style.scss new file mode 100644 index 0000000..95c1848 --- /dev/null +++ b/mappafront/src/views/components/table/style.scss @@ -0,0 +1,55 @@ +@use "@/assets/mixins.scss" as *; +@use "@/assets/variables.scss" as *; + +.table-container { + width: 100%; + height: 100%; + overflow-x: auto; + + table.table { + width: 100%; + border-collapse: collapse; + border-style: hidden; + + thead { + overflow: hidden; + + tr.table-header { + height: 0.3rem; + + th.header-item { + text-align: start; + padding: 0.2rem; + } + + th.header-item:first-child { + border-top-left-radius: 15px; + } + + th.header-item:last-child { + border-top-right-radius: 15px; + } + } + } + + tbody { + tr.table-row { + td.row-item { + padding: 0.2rem; + text-align: start; + border-bottom: 1px solid #ddd; + } + &:nth-child(odd) { + background-color: white; + } + &:nth-child(even) { + background-color: whitesmoke; + } + + &:last-child td { + border-bottom: none; + } + } + } + } +} diff --git a/mappafront/src/views/pages/ordinary-people/index.tsx b/mappafront/src/views/pages/ordinary-people/index.tsx index 0da28a1..9a50bbc 100644 --- a/mappafront/src/views/pages/ordinary-people/index.tsx +++ b/mappafront/src/views/pages/ordinary-people/index.tsx @@ -1,6 +1,7 @@ import Text from "@/views/components/text"; import "./style.scss"; import Button from "@/views/components/button"; +import Table from "@/views/components/table"; const OrdinaryPeoplePage = () => { return ( @@ -26,6 +27,23 @@ const OrdinaryPeoplePage = () => {
+
+
+ + + ); }; diff --git a/mappafront/src/views/pages/ordinary-people/style.scss b/mappafront/src/views/pages/ordinary-people/style.scss index 1fe0421..da0200c 100644 --- a/mappafront/src/views/pages/ordinary-people/style.scss +++ b/mappafront/src/views/pages/ordinary-people/style.scss @@ -46,5 +46,10 @@ section.section.ordinary-section { } } } + + .contect { + width: 100%; + height: 100%; + } } } From c5d23ae6699d12c0a99207474576cb769895a5da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20=C5=9E=C3=BCkr=C3=BC?= Date: Thu, 6 Feb 2025 12:43:11 +0300 Subject: [PATCH 06/16] Update README.md --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5fbd7e8..1406eff 100644 --- a/README.md +++ b/README.md @@ -1 +1,5 @@ -# mappaturcorum \ No newline at end of file +# Mappa Anatolicorum (Mappa Turcorum) + +An ongoing open-source digital humanities project about visualization of historical data of ordinary people in Anatolia, with collaboration of a history research team. Currently, our focus is on visualization of geo-historical data on a map and a graph visualization interface for social relations of ordinary people. + +You can check [frontend](https://github.com/Simurgan/mappaturcorum/tree/frontend) and [backend](https://github.com/Simurgan/mappaturcorum/tree/backend) branches for the lates updates in them. Also, you can view the project at [mappa-anatolicorum.netlify.app](https://mappa-anatolicorum.netlify.app). From 428dd88d629ea246b4758697a23d938094645ce0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=96mer=20=C5=9E=C3=BCkr=C3=BC?= Date: Thu, 6 Feb 2025 12:48:00 +0300 Subject: [PATCH 07/16] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1406eff..acfad4b 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ # Mappa Anatolicorum (Mappa Turcorum) -An ongoing open-source digital humanities project about visualization of historical data of ordinary people in Anatolia, with collaboration of a history research team. Currently, our focus is on visualization of geo-historical data on a map and a graph visualization interface for social relations of ordinary people. +Mappa Anatolicorum is an ongoing open-source digital humanities project about visualization of historical data of ordinary people in Anatolia, with collaboration of a history research team. Currently, our focus is on visualization of geo-historical data on a map and a graph visualization interface for social relations of ordinary people. You can check [frontend](https://github.com/Simurgan/mappaturcorum/tree/frontend) and [backend](https://github.com/Simurgan/mappaturcorum/tree/backend) branches for the lates updates in them. Also, you can view the project at [mappa-anatolicorum.netlify.app](https://mappa-anatolicorum.netlify.app). From 86cb51e1ad365bc044e1d255940c6129c39678b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20K=C4=B1z=C4=B1lay?= Date: Mon, 17 Feb 2025 21:06:04 +0300 Subject: [PATCH 08/16] feat: add table layout,table & table pagination --- .../src/helpers/data/ordinary-people.ts | 117 ++++++++++++++++++ mappafront/src/helpers/hooks/usePagination.ts | 59 +++++++++ mappafront/src/models/ordinary-people.ts | 21 ++++ .../src/views/components/table/data/index.tsx | 53 ++++++++ .../views/components/table/data/style.scss | 46 +++++++ .../src/views/components/table/index.tsx | 60 ++++----- .../components/table/pagination/index.tsx | 86 +++++++++++++ .../components/table/pagination/style.scss | 88 +++++++++++++ .../src/views/components/table/style.scss | 54 +------- .../src/views/pages/ordinary-people/index.tsx | 23 ++-- 10 files changed, 508 insertions(+), 99 deletions(-) create mode 100644 mappafront/src/helpers/data/ordinary-people.ts create mode 100644 mappafront/src/helpers/hooks/usePagination.ts create mode 100644 mappafront/src/models/ordinary-people.ts create mode 100644 mappafront/src/views/components/table/data/index.tsx create mode 100644 mappafront/src/views/components/table/data/style.scss create mode 100644 mappafront/src/views/components/table/pagination/index.tsx create mode 100644 mappafront/src/views/components/table/pagination/style.scss diff --git a/mappafront/src/helpers/data/ordinary-people.ts b/mappafront/src/helpers/data/ordinary-people.ts new file mode 100644 index 0000000..a88bd0b --- /dev/null +++ b/mappafront/src/helpers/data/ordinary-people.ts @@ -0,0 +1,117 @@ +export const ordinaryTableHeaders = [ + "Name", + "Alternate Name", + "Ethnonym", + "Religion", + "Former Religion", + "Profession", + "Gender", + "Interesting Feature", + "Interaction with Others (ordinary)", + "Interaction with Others (ordinary): Explanation", + "Interaction with Others (unordinary)", + "Interaction with Others (unordinary): Explanation", + "Source(s)", + "Biography", + "Description in the Source", + "Explanation of Ethnicity", + "Version", +]; + +export const ordinaryTableData = [ + { + name: "Sophia Lee", + alternateName: "MJ", + ethnonym: "German", + religion: null, + formerReligion: null, + profession: "Doctor", + gender: "Male", + interestingFeature: "Philanthropist", + interactionOrdinary: "Charismatic", + interactionOrdinaryExplanation: "Challenging", + interactionUnordinary: null, + interactionUnordinaryExplanation: "Controversial", + sources: [], + biography: "Left a significant impact.", + descriptionInSource: "A mysterious figure.", + explanationOfEthnicity: "Spanish", + version: "4.5", + }, + { + name: "Ali Veli", + alternateName: null, + ethnonym: "Spanish", + religion: "Islam", + formerReligion: null, + profession: "Scientist", + gender: "Female", + interestingFeature: "Great public speaker", + interactionOrdinary: null, + interactionOrdinaryExplanation: null, + interactionUnordinary: "Introverted", + interactionUnordinaryExplanation: "Leader", + sources: [], + biography: null, + descriptionInSource: null, + explanationOfEthnicity: null, + version: null, + }, + { + name: "Jane Smith", + alternateName: "M. Yılmaz", + ethnonym: "American", + religion: "Spiritual", + formerReligion: null, + profession: "Author", + gender: "Male", + interestingFeature: null, + interactionOrdinary: null, + interactionOrdinaryExplanation: null, + interactionUnordinary: null, + interactionUnordinaryExplanation: "Challenging", + sources: [], + biography: null, + descriptionInSource: null, + explanationOfEthnicity: null, + version: "4.5", + }, + { + name: "Elif Kaya", + alternateName: null, + ethnonym: "Russian", + religion: "Buddhism", + formerReligion: null, + profession: "Politician", + gender: "Other", + interestingFeature: null, + interactionOrdinary: "Leader", + interactionOrdinaryExplanation: "Supportive", + interactionUnordinary: null, + interactionUnordinaryExplanation: null, + sources: ["News Article"], + biography: "Famous in their field.", + descriptionInSource: null, + explanationOfEthnicity: null, + version: "2.1", + }, + { + name: "Ayşe Demir", + alternateName: null, + ethnonym: "Indian", + religion: "Christianity", + formerReligion: null, + profession: "Author", + gender: "Male", + interestingFeature: "Can speak 5 languages", + interactionOrdinary: "Introverted", + interactionOrdinaryExplanation: null, + interactionUnordinary: null, + interactionUnordinaryExplanation: null, + sources: ["Autobiography", "News Article"], + biography: null, + descriptionInSource: null, + explanationOfEthnicity: "American", + version: "4.5", + }, +]; diff --git a/mappafront/src/helpers/hooks/usePagination.ts b/mappafront/src/helpers/hooks/usePagination.ts new file mode 100644 index 0000000..ec4cb42 --- /dev/null +++ b/mappafront/src/helpers/hooks/usePagination.ts @@ -0,0 +1,59 @@ +import { useState, useMemo } from "react"; + +interface UsePaginationProps { + _data: Object[]; + itemsPerPage?: number; + initialPage?: number; +} + +interface UsePaginationReturn { + currentPage: number; + totalPages: number; + paginatedData: Object[]; + nextPage: () => void; + prevPage: () => void; + goToPage: (page: number) => void; +} + +const usePagination = ({ + _data, + itemsPerPage = 4, // Varsayılan olarak 4 öğe gösterilecek + initialPage = 1, +}: UsePaginationProps): UsePaginationReturn => { + const totalItems = _data.length; + const totalPages = totalItems > 0 ? Math.ceil(totalItems / itemsPerPage) : 1; + const [currentPage, setCurrentPage] = useState( + Math.min(initialPage, totalPages) + ); + + // Sayfalara göre veriyi hesapla (useMemo ile optimize edildi) + const paginatedData = useMemo(() => { + const startIndex = (currentPage - 1) * itemsPerPage; + return _data.slice(startIndex, startIndex + itemsPerPage); + }, [_data, currentPage, itemsPerPage]); + + const nextPage = () => { + setCurrentPage((prev) => (prev < totalPages ? prev + 1 : prev)); + }; + + const prevPage = () => { + setCurrentPage((prev) => (prev > 1 ? prev - 1 : prev)); + }; + + const goToPage = (page: number) => { + if (page >= 1 && page <= totalPages) { + setCurrentPage(page); + } + }; + + return { + currentPage, + totalPages, + paginatedData, // Burada her sayfa için uygun verileri döndürür + nextPage, + prevPage, + goToPage, + }; +}; + +export default usePagination; diff --git a/mappafront/src/models/ordinary-people.ts b/mappafront/src/models/ordinary-people.ts new file mode 100644 index 0000000..1f77c07 --- /dev/null +++ b/mappafront/src/models/ordinary-people.ts @@ -0,0 +1,21 @@ +type OrdinaryPeopleTableDataType = { + name: string; + alternateName?: string; + ethnonym?: string; + religion?: string; + formerReligion?: string; + profession?: string; + gender?: "Male" | "Female" | "Other"; + interestingFeature?: string; + interactionOrdinary?: string; + interactionOrdinaryExplanation?: string; + interactionUnordinary?: string; + interactionUnordinaryExplanation?: string; + sources?: string[]; + biography?: string; + descriptionInSource?: string; + explanationOfEthnicity?: string; + version?: string; +}; + +export type { OrdinaryPeopleTableDataType }; diff --git a/mappafront/src/views/components/table/data/index.tsx b/mappafront/src/views/components/table/data/index.tsx new file mode 100644 index 0000000..c7bac25 --- /dev/null +++ b/mappafront/src/views/components/table/data/index.tsx @@ -0,0 +1,53 @@ +import Text from "../../text"; +import "./style.scss"; + +interface TableDataProps { + headers: string[]; + data: { [key: string]: any }[]; +} + +const TableData = ({ headers, data }: TableDataProps) => { + return ( +
+ + + {headers.map((header, index) => ( + + ))} + + + + + {data.length > 0 ? ( + data.map((row, rowIndex) => ( + + {Object.keys(row).map((key) => ( + + ))} + + )) + ) : ( + + + + )} + +
+ + {header} + +
+ + {typeof row[key] === "object" && row[key] !== null + ? JSON.stringify(row[key]) + : row[key]?.toString() || "-"}{" "} + +
+ + No data available + +
+ ); +}; + +export default TableData; diff --git a/mappafront/src/views/components/table/data/style.scss b/mappafront/src/views/components/table/data/style.scss new file mode 100644 index 0000000..daf00e2 --- /dev/null +++ b/mappafront/src/views/components/table/data/style.scss @@ -0,0 +1,46 @@ +@use "@/assets/mixins.scss" as *; +@use "@/assets/variables.scss" as *; + +table.table { + width: 100%; + border: 3px solid $color-primary; + margin-bottom: 0.28rem; + border-collapse: collapse; + + .table-header { + width: 100%; + + .table-columns { + display: flex; + flex-direction: row; + align-items: center; + padding: 0.14rem 0.32rem; + gap: 0.32rem; + border-bottom: 1px solid $color-primary; + + .table-column { + width: 0.62rem; + display: table-cell; + text-align: center; + } + } + } + + .table-body { + .data-row { + display: flex; + flex-direction: row; + border-bottom: 1px solid $color-primary; + padding: 0.32rem; + gap: 0.32rem; + + .data-row-item { + width: 0.62rem; + white-space: nowrap; + text-align: center; + text-overflow: ellipsis; + overflow: hidden; + } + } + } +} diff --git a/mappafront/src/views/components/table/index.tsx b/mappafront/src/views/components/table/index.tsx index 7f0d866..1f25fde 100644 --- a/mappafront/src/views/components/table/index.tsx +++ b/mappafront/src/views/components/table/index.tsx @@ -1,44 +1,36 @@ -import Text from "../text"; +import usePagination from "@/helpers/hooks/usePagination"; +import TableData from "./data"; +import TablePagination from "./pagination"; import "./style.scss"; -interface TableData { - [key: string]: any; -} - interface TableProps { - headers: string[]; - data: TableData[]; + tableHeaders: string[]; + tableData: Object[]; } -const Table = ({ headers, data }: TableProps) => { +const Table = ({ tableHeaders, tableData }: TableProps) => { + const { + currentPage, + totalPages, + nextPage, + prevPage, + goToPage, + paginatedData, + } = usePagination({ + _data: tableData, + itemsPerPage: 100, + }); + return (
- - - - {headers.map((item: string) => ( - - ))} - - - - {data.map((item, index) => ( - - {Object.keys(item).map((itemKey, subIndex) => ( - - ))} - - ))} - -
- - {item} - -
- - {item[itemKey]} - -
+ +
); }; diff --git a/mappafront/src/views/components/table/pagination/index.tsx b/mappafront/src/views/components/table/pagination/index.tsx new file mode 100644 index 0000000..745e632 --- /dev/null +++ b/mappafront/src/views/components/table/pagination/index.tsx @@ -0,0 +1,86 @@ +import arrowForward from "@/assets/icons/arrow-forward.svg"; +import "./style.scss"; + +interface TablePaginationProps { + currentPage: number; + totalPage: number; + nextStep?: (page: number) => void; + prevStep?: (page: number) => void; + goStep?: (page: number) => void; +} + +const TablePagination = ({ + currentPage, + totalPage, + nextStep, + prevStep, + goStep, +}: TablePaginationProps) => { + const generatePageNumbers = (): (number | string)[] => { + const maxVisiblePages = 5; + let pages: (number | string)[] = []; + + if (totalPage <= maxVisiblePages) { + // Sayfa sayısı 5 veya daha azsa hepsini göster + return Array.from({ length: totalPage }, (_, i) => i + 1); + } + + if (currentPage <= 3) { + // Kullanıcı ilk sayfalardaysa + pages = [1, 2, 3, "...", totalPage]; + } else if (currentPage >= totalPage - 2) { + // Kullanıcı son sayfalardaysa + pages = [1, "...", totalPage - 2, totalPage - 1, totalPage]; + } else { + // Kullanıcı ortadaysa + pages = [ + 1, + "...", + currentPage - 1, + currentPage, + currentPage + 1, + "...", + totalPage, + ]; + } + + return pages; + }; + + const pageNumbers: (number | string)[] = generatePageNumbers(); + + return ( + + ); +}; + +export default TablePagination; diff --git a/mappafront/src/views/components/table/pagination/style.scss b/mappafront/src/views/components/table/pagination/style.scss new file mode 100644 index 0000000..ad24394 --- /dev/null +++ b/mappafront/src/views/components/table/pagination/style.scss @@ -0,0 +1,88 @@ +@use "@/assets/mixins.scss" as *; +@use "@/assets/variables.scss" as *; + +.pagination { + display: flex; + align-items: center; + justify-content: center; + gap: 10px; + background: #fdf9f2; + padding: 10px; + + button { + display: flex; + align-items: center; + justify-content: center; + width: 50px; + height: 50px; + border: 2px solid #a33d30; + background: #fff8f0; + color: #a33d30; + font-size: 18px; + font-weight: bold; + cursor: pointer; + transition: all 0.3s; + + &:hover { + background: #f5e5d8; + } + + &.active { + background: #a33d30; + color: white; + } + + &.prev, + &.next { + background: #a33d30; + color: white; + border: none; + font-size: 22px; + } + + &.disabled { + opacity: 0.5; + cursor: not-allowed; + } + } +} +.pagination { + button { + display: flex; + align-items: center; + justify-content: center; + min-width: 40px; + height: 40px; + border: 1px solid $color-primary; + background: #fff8f0; + + &:hover { + background: #f5e5d8; + } + + &.active { + background: $color-primary; + color: white; + } + + &.prev { + background: $color-primary; + transform: rotate(180deg); + } + + &.next { + background: $color-primary; + border: none; + } + + &.disabled { + opacity: 0.5; + cursor: not-allowed; + } + } + + .dots { + border: none; + pointer-events: none; + } +} diff --git a/mappafront/src/views/components/table/style.scss b/mappafront/src/views/components/table/style.scss index 95c1848..862dcbd 100644 --- a/mappafront/src/views/components/table/style.scss +++ b/mappafront/src/views/components/table/style.scss @@ -2,54 +2,8 @@ @use "@/assets/variables.scss" as *; .table-container { - width: 100%; - height: 100%; - overflow-x: auto; - - table.table { - width: 100%; - border-collapse: collapse; - border-style: hidden; - - thead { - overflow: hidden; - - tr.table-header { - height: 0.3rem; - - th.header-item { - text-align: start; - padding: 0.2rem; - } - - th.header-item:first-child { - border-top-left-radius: 15px; - } - - th.header-item:last-child { - border-top-right-radius: 15px; - } - } - } - - tbody { - tr.table-row { - td.row-item { - padding: 0.2rem; - text-align: start; - border-bottom: 1px solid #ddd; - } - &:nth-child(odd) { - background-color: white; - } - &:nth-child(even) { - background-color: whitesmoke; - } - - &:last-child td { - border-bottom: none; - } - } - } - } + padding: 0.84rem 1.92rem; + display: flex; + flex-direction: column; + align-items: center; } diff --git a/mappafront/src/views/pages/ordinary-people/index.tsx b/mappafront/src/views/pages/ordinary-people/index.tsx index 9a50bbc..9fefdbc 100644 --- a/mappafront/src/views/pages/ordinary-people/index.tsx +++ b/mappafront/src/views/pages/ordinary-people/index.tsx @@ -2,6 +2,10 @@ import Text from "@/views/components/text"; import "./style.scss"; import Button from "@/views/components/button"; import Table from "@/views/components/table"; +import { + ordinaryTableData, + ordinaryTableHeaders, +} from "@/helpers/data/ordinary-people"; const OrdinaryPeoplePage = () => { return ( @@ -28,21 +32,10 @@ const OrdinaryPeoplePage = () => {
-
- - +
); From d60c76bb57168cf0d76d52eb8cdde58917d14705 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Burak=20K=C4=B1z=C4=B1lay?= Date: Tue, 18 Feb 2025 09:32:45 +0300 Subject: [PATCH 09/16] feat: add data table modal --- .../src/views/components/modal/index.tsx | 66 +++++++++++++++++++ .../src/views/components/modal/style.scss | 57 ++++++++++++++++ .../src/views/components/table/data/index.tsx | 9 ++- .../src/views/components/table/index.tsx | 9 ++- .../src/views/pages/ordinary-people/index.tsx | 19 ++++++ 5 files changed, 156 insertions(+), 4 deletions(-) create mode 100644 mappafront/src/views/components/modal/index.tsx create mode 100644 mappafront/src/views/components/modal/style.scss diff --git a/mappafront/src/views/components/modal/index.tsx b/mappafront/src/views/components/modal/index.tsx new file mode 100644 index 0000000..ca11406 --- /dev/null +++ b/mappafront/src/views/components/modal/index.tsx @@ -0,0 +1,66 @@ +import ReactModal from "react-modal"; + +import "./style.scss"; +import Text from "../text"; +import Button from "../button"; + +interface MappaModalProps { + isOpen: boolean; + closeModal: () => void; + data?: { [key: string]: any }; +} + +const MappaModal = ({ isOpen, closeModal, data }: MappaModalProps) => { + return ( + +
+ {/* Kapatma Butonu */} + + + {/* Başlık */} + + Overview + + +
+ + {data?.name || "No Name Provided"} + + +
+ {data && Object.keys(data).length > 0 ? ( + Object.keys(data).map((key, index) => ( +
+ + {key} + + + {typeof data[key] === "object" + ? JSON.stringify(data[key]) + : data[key]?.toString() || "-"}{" "} + +
+ )) + ) : ( + + No data available + + )} +
+
+
+
+ ); +}; + +export default MappaModal; diff --git a/mappafront/src/views/components/modal/style.scss b/mappafront/src/views/components/modal/style.scss new file mode 100644 index 0000000..e43362a --- /dev/null +++ b/mappafront/src/views/components/modal/style.scss @@ -0,0 +1,57 @@ +@use "@/assets/mixins.scss" as *; +@use "@/assets/variables.scss" as *; + +.custom-mappa-modal { + position: fixed; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + background-color: white; + width: 9.5rem; + max-width: 100%; + height: 75%; + max-height: 90vh; + overflow-y: auto; + border-radius: 0px !important; + box-shadow: 0px 4px 10px rgba(0, 0, 0, 0.2); + border: 8px solid $color-primary; + z-index: 10001 !important; + background-color: $color-secondary; +} +div.modal-content { + display: flex; + flex-direction: column; + + .modal-close-button { + position: fixed; + right: 0.2rem; + top: 0.2rem; + background-color: transparent; + border: none; + } + + div.content { + padding: 0.6rem 1rem; + + .content-info { + .info-row { + padding-top: 0.32rem; + gap: 0.64rem; + + .data-field { + width: 50%; + text-transform: capitalize; + } + .data { + width: 50%; + } + + width: 100%; + display: flex; + flex-direction: row; + + align-items: center; + } + } + } +} diff --git a/mappafront/src/views/components/table/data/index.tsx b/mappafront/src/views/components/table/data/index.tsx index c7bac25..38c71c8 100644 --- a/mappafront/src/views/components/table/data/index.tsx +++ b/mappafront/src/views/components/table/data/index.tsx @@ -4,9 +4,10 @@ import "./style.scss"; interface TableDataProps { headers: string[]; data: { [key: string]: any }[]; + openModal: (data: any) => void; } -const TableData = ({ headers, data }: TableDataProps) => { +const TableData = ({ headers, data, openModal }: TableDataProps) => { return (
@@ -24,7 +25,11 @@ const TableData = ({ headers, data }: TableDataProps) => { {data.length > 0 ? ( data.map((row, rowIndex) => ( - + openModal(row)} + > {Object.keys(row).map((key) => (
diff --git a/mappafront/src/views/components/table/index.tsx b/mappafront/src/views/components/table/index.tsx index 1f25fde..6365955 100644 --- a/mappafront/src/views/components/table/index.tsx +++ b/mappafront/src/views/components/table/index.tsx @@ -6,9 +6,10 @@ import "./style.scss"; interface TableProps { tableHeaders: string[]; tableData: Object[]; + openModal: (data: any) => void; } -const Table = ({ tableHeaders, tableData }: TableProps) => { +const Table = ({ tableHeaders, tableData, openModal }: TableProps) => { const { currentPage, totalPages, @@ -23,7 +24,11 @@ const Table = ({ tableHeaders, tableData }: TableProps) => { return (
- + openModal(data)} + /> { + const [modalIsOpen, setIsOpen] = useState(false); + const [selectedData, setSelectedData] = useState(); + + function openModal(data: any) { + setIsOpen(true); + setSelectedData(data); + } + function closeModal() { + setIsOpen(false); + } return (
@@ -33,10 +46,16 @@ const OrdinaryPeoplePage = () => {
openModal(data)} tableHeaders={ordinaryTableHeaders} tableData={ordinaryTableData} /> + ); }; From 7bb978337f1afc721d5b1a896d92261fca883a8d Mon Sep 17 00:00:00 2001 From: Simurgan Date: Sat, 22 Feb 2025 16:02:05 +0300 Subject: [PATCH 10/16] feat: start to implement axios and backend connection --- .gitignore | 2 + mappafront/.gitignore | 2 + mappafront/package-lock.json | 279 +++++++++++++++++++++++++++++ mappafront/package.json | 2 + mappafront/src/actions/api.ts | 8 + mappafront/src/actions/ordinary.ts | 13 ++ 6 files changed, 306 insertions(+) create mode 100644 .gitignore create mode 100644 mappafront/src/actions/api.ts create mode 100644 mappafront/src/actions/ordinary.ts diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e1c66f9 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.env +mappa_data/ diff --git a/mappafront/.gitignore b/mappafront/.gitignore index e7ff2bb..e3e25c7 100644 --- a/mappafront/.gitignore +++ b/mappafront/.gitignore @@ -27,3 +27,5 @@ src/assets/images src/assets/icons .netlify +.env.local +.env.prod.local diff --git a/mappafront/package-lock.json b/mappafront/package-lock.json index a6f58b2..c94fdcd 100644 --- a/mappafront/package-lock.json +++ b/mappafront/package-lock.json @@ -10,6 +10,7 @@ "dependencies": { "@types/node": "^22.10.7", "@types/react-modal": "^3.16.3", + "axios": "^1.7.9", "leaflet": "^1.9.4", "react": "19.0.0", "react-dom": "19.0.0", @@ -2077,6 +2078,23 @@ "dev": true, "license": "Python-2.0" }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/axios": { + "version": "1.7.9", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz", + "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==", + "license": "MIT", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -2151,6 +2169,19 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, + "node_modules/call-bind-apply-helpers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", + "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -2247,6 +2278,18 @@ "dev": true, "license": "MIT" }, + "node_modules/combined-stream": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", + "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -2532,6 +2575,15 @@ "dev": true, "license": "MIT" }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, "node_modules/detect-libc": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", @@ -2546,6 +2598,20 @@ "node": ">=0.10" } }, + "node_modules/dunder-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", + "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-errors": "^1.3.0", + "gopd": "^1.2.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/electron-to-chromium": { "version": "1.5.84", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.84.tgz", @@ -2553,6 +2619,24 @@ "dev": true, "license": "ISC" }, + "node_modules/es-define-property": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", + "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-module-lexer": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.6.0.tgz", @@ -2560,6 +2644,33 @@ "dev": true, "license": "MIT" }, + "node_modules/es-object-atoms": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", + "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", + "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.6", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/esbuild": { "version": "0.24.2", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.24.2.tgz", @@ -2947,6 +3058,26 @@ "node": ">=12" } }, + "node_modules/follow-redirects": { + "version": "1.15.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", + "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "license": "MIT", + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/force-graph": { "version": "1.49.0", "resolved": "https://registry.npmjs.org/force-graph/-/force-graph-1.49.0.tgz", @@ -2973,6 +3104,21 @@ "node": ">=12" } }, + "node_modules/form-data": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz", + "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==", + "license": "MIT", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "es-set-tostringtag": "^2.1.0", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -2988,6 +3134,15 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -2998,6 +3153,43 @@ "node": ">=6.9.0" } }, + "node_modules/get-intrinsic": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.7.tgz", + "integrity": "sha512-VW6Pxhsrk0KAOqs3WEd0klDiF/+V7gQOpAvY1jVU/LHmaD/kQO4523aiJuikX/QAKYiW6x8Jh+RJej1almdtCA==", + "license": "MIT", + "dependencies": { + "call-bind-apply-helpers": "^1.0.1", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "function-bind": "^1.1.2", + "get-proto": "^1.0.0", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "hasown": "^2.0.2", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", + "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", + "license": "MIT", + "dependencies": { + "dunder-proto": "^1.0.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -3024,6 +3216,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/gopd": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", + "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", @@ -3041,6 +3245,45 @@ "node": ">=8" } }, + "node_modules/has-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", + "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/ignore": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", @@ -3321,6 +3564,15 @@ "@jridgewell/sourcemap-codec": "^1.5.0" } }, + "node_modules/math-intrinsics": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", + "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -3345,6 +3597,27 @@ "node": ">=8.6" } }, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, "node_modules/minimatch": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", @@ -3578,6 +3851,12 @@ "react-is": "^16.13.1" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", + "license": "MIT" + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", diff --git a/mappafront/package.json b/mappafront/package.json index f1d7284..ceaafb2 100644 --- a/mappafront/package.json +++ b/mappafront/package.json @@ -6,12 +6,14 @@ "scripts": { "dev": "vite", "build": "tsc -b && vite build", + "buildprod": "tsc -b && vite build --mode prod", "lint": "eslint .", "preview": "vite preview" }, "dependencies": { "@types/node": "^22.10.7", "@types/react-modal": "^3.16.3", + "axios": "^1.7.9", "leaflet": "^1.9.4", "react": "19.0.0", "react-dom": "19.0.0", diff --git a/mappafront/src/actions/api.ts b/mappafront/src/actions/api.ts new file mode 100644 index 0000000..0c10120 --- /dev/null +++ b/mappafront/src/actions/api.ts @@ -0,0 +1,8 @@ +import axios from "axios"; + +// Dynamically set backend URL +const backendUrl = import.meta.env.VITE_BACKEND_URL ?? "__VITE_BACKEND_URL__"; + +axios.defaults.baseURL = `${backendUrl}/`; + +export const api = axios; diff --git a/mappafront/src/actions/ordinary.ts b/mappafront/src/actions/ordinary.ts new file mode 100644 index 0000000..1ac2df1 --- /dev/null +++ b/mappafront/src/actions/ordinary.ts @@ -0,0 +1,13 @@ +import api from "./api"; + +const ordinaryApi = api.create({ + baseURL: api.defaults.baseURL + "ordinaryperson/", +}); + +export const getOrdinaryPage = async () => { + const response = await ordinaryApi({ + url: "page/", + method: "get", + data: + }) +} From 70efccc036042725df93ca48f221e73c9ff810b0 Mon Sep 17 00:00:00 2001 From: Simurgan Date: Sat, 22 Feb 2025 18:13:39 +0300 Subject: [PATCH 11/16] feat: continue to implement api connection --- mappafront/src/actions/api.ts | 5 ++++- mappafront/src/actions/ordinary.ts | 11 ++++++---- mappafront/src/models/ordinary-people.ts | 17 ++++++++++++++-- .../src/views/pages/ordinary-people/index.tsx | 20 ++++++++++++++++++- 4 files changed, 45 insertions(+), 8 deletions(-) diff --git a/mappafront/src/actions/api.ts b/mappafront/src/actions/api.ts index 0c10120..ab7a336 100644 --- a/mappafront/src/actions/api.ts +++ b/mappafront/src/actions/api.ts @@ -2,7 +2,10 @@ import axios from "axios"; // Dynamically set backend URL const backendUrl = import.meta.env.VITE_BACKEND_URL ?? "__VITE_BACKEND_URL__"; +console.log(backendUrl); +console.log("backend url"); axios.defaults.baseURL = `${backendUrl}/`; -export const api = axios; +const api = axios; +export default api; diff --git a/mappafront/src/actions/ordinary.ts b/mappafront/src/actions/ordinary.ts index 1ac2df1..6edf5b1 100644 --- a/mappafront/src/actions/ordinary.ts +++ b/mappafront/src/actions/ordinary.ts @@ -1,13 +1,16 @@ +import { OrdinaryPageRequestBody } from "@/models/ordinary-people"; import api from "./api"; const ordinaryApi = api.create({ baseURL: api.defaults.baseURL + "ordinaryperson/", }); -export const getOrdinaryPage = async () => { +export const getOrdinaryPage = async (data: OrdinaryPageRequestBody) => { const response = await ordinaryApi({ url: "page/", method: "get", - data: - }) -} + data: data, + }); + + return response; +}; diff --git a/mappafront/src/models/ordinary-people.ts b/mappafront/src/models/ordinary-people.ts index 1f77c07..5ef0df6 100644 --- a/mappafront/src/models/ordinary-people.ts +++ b/mappafront/src/models/ordinary-people.ts @@ -1,4 +1,4 @@ -type OrdinaryPeopleTableDataType = { +export type OrdinaryPeopleTableDataType = { name: string; alternateName?: string; ethnonym?: string; @@ -18,4 +18,17 @@ type OrdinaryPeopleTableDataType = { version?: string; }; -export type { OrdinaryPeopleTableDataType }; +export type OrdinaryPageRequestBody = { + pageSize: number; + pageNumber: number; + filter: { + name?: string; + religion?: number; + ethnicity?: number; + profession?: number; + location?: number; + sources?: number[]; + gender?: number; + interactionsWithUnordinary?: number[]; + }; +}; diff --git a/mappafront/src/views/pages/ordinary-people/index.tsx b/mappafront/src/views/pages/ordinary-people/index.tsx index f5b162c..a49f64e 100644 --- a/mappafront/src/views/pages/ordinary-people/index.tsx +++ b/mappafront/src/views/pages/ordinary-people/index.tsx @@ -7,8 +7,9 @@ import { ordinaryTableHeaders, } from "@/helpers/data/ordinary-people"; -import { useState } from "react"; +import { useEffect, useState } from "react"; import MappaModal from "@/views/components/modal"; +import { getOrdinaryPage } from "@/actions/ordinary"; const OrdinaryPeoplePage = () => { const [modalIsOpen, setIsOpen] = useState(false); @@ -18,9 +19,26 @@ const OrdinaryPeoplePage = () => { setIsOpen(true); setSelectedData(data); } + function closeModal() { setIsOpen(false); } + + const setInitialData = async () => { + const response = await getOrdinaryPage({ + pageSize: 10, + pageNumber: 1, + filter: {}, + }); + + console.log(response); + console.log("response"); + }; + + useEffect(() => { + setInitialData(); + }, []); + return (
From f40a9d74fb1e24fda6a00339fed27c59171f9e52 Mon Sep 17 00:00:00 2001 From: Simurgan Date: Sun, 23 Feb 2025 19:08:19 +0300 Subject: [PATCH 12/16] feat: improve table view and connect ordinary person page api --- mappafront/src/actions/ordinary.ts | 10 ++- mappafront/src/models/ordinary-people.ts | 38 ++++++++++-- .../src/views/components/table/index.tsx | 38 +++--------- .../table/{data => table-data}/index.tsx | 38 ++++++------ .../table/{data => table-data}/style.scss | 0 .../index.tsx | 45 ++++++++------ .../style.scss | 0 mappafront/src/views/layout/header/index.tsx | 3 +- .../src/views/pages/ordinary-people/index.tsx | 62 ++++++++++++++++--- 9 files changed, 146 insertions(+), 88 deletions(-) rename mappafront/src/views/components/table/{data => table-data}/index.tsx (54%) rename mappafront/src/views/components/table/{data => table-data}/style.scss (100%) rename mappafront/src/views/components/table/{pagination => table-pagination}/index.tsx (65%) rename mappafront/src/views/components/table/{pagination => table-pagination}/style.scss (100%) diff --git a/mappafront/src/actions/ordinary.ts b/mappafront/src/actions/ordinary.ts index 6edf5b1..4499706 100644 --- a/mappafront/src/actions/ordinary.ts +++ b/mappafront/src/actions/ordinary.ts @@ -1,5 +1,9 @@ -import { OrdinaryPageRequestBody } from "@/models/ordinary-people"; +import { + OrdinaryPageRequestBody, + OrdinaryPageResponseData, +} from "@/models/ordinary-people"; import api from "./api"; +import { AxiosResponse } from "axios"; const ordinaryApi = api.create({ baseURL: api.defaults.baseURL + "ordinaryperson/", @@ -8,9 +12,9 @@ const ordinaryApi = api.create({ export const getOrdinaryPage = async (data: OrdinaryPageRequestBody) => { const response = await ordinaryApi({ url: "page/", - method: "get", + method: "post", data: data, }); - return response; + return response as AxiosResponse; }; diff --git a/mappafront/src/models/ordinary-people.ts b/mappafront/src/models/ordinary-people.ts index 5ef0df6..fe060e1 100644 --- a/mappafront/src/models/ordinary-people.ts +++ b/mappafront/src/models/ordinary-people.ts @@ -21,14 +21,40 @@ export type OrdinaryPeopleTableDataType = { export type OrdinaryPageRequestBody = { pageSize: number; pageNumber: number; - filter: { + filter?: { name?: string; - religion?: number; - ethnicity?: number; - profession?: number; - location?: number; + religion?: number[]; + ethnicity?: number[]; + profession?: number[]; + location?: number[]; sources?: number[]; - gender?: number; + gender?: number[]; interactionsWithUnordinary?: number[]; }; }; + +export type SubObjectPair = { + id: number; + name: string; +}; + +export type OrdinaryPageResponseDataItem = { + id: number; + name: string; + alternateName?: string; + ethnicity?: SubObjectPair; + gender?: SubObjectPair; + location?: SubObjectPair; + profession?: SubObjectPair; + religion?: SubObjectPair; + sources: SubObjectPair[]; + interactionsWithUnordinary: SubObjectPair[]; +}; + +export type OrdinaryPageResponseData = { + pageSize: number; + pageNumber: number; + totalCount: number; + totalPages: number; + data: OrdinaryPageResponseDataItem[]; +}; diff --git a/mappafront/src/views/components/table/index.tsx b/mappafront/src/views/components/table/index.tsx index 6365955..491f403 100644 --- a/mappafront/src/views/components/table/index.tsx +++ b/mappafront/src/views/components/table/index.tsx @@ -1,41 +1,17 @@ -import usePagination from "@/helpers/hooks/usePagination"; -import TableData from "./data"; -import TablePagination from "./pagination"; +import TableData, { TableDataProps } from "./table-data"; +import TablePagination, { TablePaginationProps } from "./table-pagination"; import "./style.scss"; interface TableProps { - tableHeaders: string[]; - tableData: Object[]; - openModal: (data: any) => void; + tableData: TableDataProps; + paginationData?: TablePaginationProps; } -const Table = ({ tableHeaders, tableData, openModal }: TableProps) => { - const { - currentPage, - totalPages, - nextPage, - prevPage, - goToPage, - paginatedData, - } = usePagination({ - _data: tableData, - itemsPerPage: 100, - }); - +const Table = ({ tableData, paginationData }: TableProps) => { return (
- openModal(data)} - /> - + + {paginationData && }
); }; diff --git a/mappafront/src/views/components/table/data/index.tsx b/mappafront/src/views/components/table/table-data/index.tsx similarity index 54% rename from mappafront/src/views/components/table/data/index.tsx rename to mappafront/src/views/components/table/table-data/index.tsx index 38c71c8..2bab84a 100644 --- a/mappafront/src/views/components/table/data/index.tsx +++ b/mappafront/src/views/components/table/table-data/index.tsx @@ -1,42 +1,44 @@ +import { ReactNode } from "react"; import Text from "../../text"; import "./style.scss"; -interface TableDataProps { - headers: string[]; - data: { [key: string]: any }[]; - openModal: (data: any) => void; -} +export type TableDataProps = { + headers: ReactNode[]; + rows?: { cells: ReactNode[]; onClick?: () => void }[]; + hasRowHover?: boolean; +}; -const TableData = ({ headers, data, openModal }: TableDataProps) => { +const TableData = ({ headers, rows, hasRowHover }: TableDataProps) => { return (
{headers.map((header, index) => ( ))} - {data.length > 0 ? ( - data.map((row, rowIndex) => ( + {rows && rows.length > 0 ? ( + rows.map((row, rowIndex) => ( openModal(row)} + className={`data-row${hasRowHover ? " hasHoverEffect" : ""}`} + onClick={row.onClick} > - {Object.keys(row).map((key) => ( - ))} @@ -45,7 +47,7 @@ const TableData = ({ headers, data, openModal }: TableDataProps) => { diff --git a/mappafront/src/views/components/table/data/style.scss b/mappafront/src/views/components/table/table-data/style.scss similarity index 100% rename from mappafront/src/views/components/table/data/style.scss rename to mappafront/src/views/components/table/table-data/style.scss diff --git a/mappafront/src/views/components/table/pagination/index.tsx b/mappafront/src/views/components/table/table-pagination/index.tsx similarity index 65% rename from mappafront/src/views/components/table/pagination/index.tsx rename to mappafront/src/views/components/table/table-pagination/index.tsx index 745e632..35d37bc 100644 --- a/mappafront/src/views/components/table/pagination/index.tsx +++ b/mappafront/src/views/components/table/table-pagination/index.tsx @@ -1,20 +1,16 @@ import arrowForward from "@/assets/icons/arrow-forward.svg"; import "./style.scss"; -interface TablePaginationProps { +export type TablePaginationProps = { currentPage: number; totalPage: number; - nextStep?: (page: number) => void; - prevStep?: (page: number) => void; - goStep?: (page: number) => void; -} + setPage: (page: number) => void; +}; const TablePagination = ({ currentPage, totalPage, - nextStep, - prevStep, - goStep, + setPage, }: TablePaginationProps) => { const generatePageNumbers = (): (number | string)[] => { const maxVisiblePages = 5; @@ -25,12 +21,19 @@ const TablePagination = ({ return Array.from({ length: totalPage }, (_, i) => i + 1); } - if (currentPage <= 3) { + if (currentPage < 4) { // Kullanıcı ilk sayfalardaysa - pages = [1, 2, 3, "...", totalPage]; - } else if (currentPage >= totalPage - 2) { + pages = [1, 2, 3, 4, "...", totalPage]; + } else if (currentPage > totalPage - 3) { // Kullanıcı son sayfalardaysa - pages = [1, "...", totalPage - 2, totalPage - 1, totalPage]; + pages = [ + 1, + "...", + totalPage - 3, + totalPage - 2, + totalPage - 1, + totalPage, + ]; } else { // Kullanıcı ortadaysa pages = [ @@ -53,7 +56,9 @@ const TablePagination = ({
- - {header} - + {/* */} + {header} + {/* */}
- + {row.cells.map((cell, index) => ( + + {cell} + {/* {typeof row[key] === "object" && row[key] !== null ? JSON.stringify(row[key]) : row[key]?.toString() || "-"}{" "} - + */}
- No data available + There is no such data
openModal(data)} - tableHeaders={ordinaryTableHeaders} - tableData={ordinaryTableData} + paginationData={ + totalPage + ? { + currentPage: tablePage, + setPage: setTablePage, + totalPage: totalPage, + } + : undefined + } + tableData={{ + hasRowHover: true, + headers: headerData.map((cell) => ( + + {cell} + + )), + rows: tableData?.map((ordinary) => { + const cellTexts = [ + ordinary.name, + ordinary.alternateName, + ordinary.ethnicity?.name, + ordinary.religion?.name, + ordinary.profession?.name, + ordinary.gender?.name, + ]; + return { + cells: cellTexts.map((cellText) => ( + + {cellText} + + )), + onClick: () => openModal({}), + }; + }), + }} /> Date: Sun, 23 Feb 2025 20:00:53 +0300 Subject: [PATCH 13/16] remove unnnecessary files --- .../{ordinary.ts => ordinary-people.ts} | 0 .../src/helpers/data/ordinary-people.ts | 117 ------------------ mappafront/src/helpers/hooks/usePagination.ts | 59 --------- mappafront/src/models/ordinary-people.ts | 20 --- .../src/views/pages/ordinary-people/index.tsx | 2 +- 5 files changed, 1 insertion(+), 197 deletions(-) rename mappafront/src/actions/{ordinary.ts => ordinary-people.ts} (100%) delete mode 100644 mappafront/src/helpers/data/ordinary-people.ts delete mode 100644 mappafront/src/helpers/hooks/usePagination.ts diff --git a/mappafront/src/actions/ordinary.ts b/mappafront/src/actions/ordinary-people.ts similarity index 100% rename from mappafront/src/actions/ordinary.ts rename to mappafront/src/actions/ordinary-people.ts diff --git a/mappafront/src/helpers/data/ordinary-people.ts b/mappafront/src/helpers/data/ordinary-people.ts deleted file mode 100644 index a88bd0b..0000000 --- a/mappafront/src/helpers/data/ordinary-people.ts +++ /dev/null @@ -1,117 +0,0 @@ -export const ordinaryTableHeaders = [ - "Name", - "Alternate Name", - "Ethnonym", - "Religion", - "Former Religion", - "Profession", - "Gender", - "Interesting Feature", - "Interaction with Others (ordinary)", - "Interaction with Others (ordinary): Explanation", - "Interaction with Others (unordinary)", - "Interaction with Others (unordinary): Explanation", - "Source(s)", - "Biography", - "Description in the Source", - "Explanation of Ethnicity", - "Version", -]; - -export const ordinaryTableData = [ - { - name: "Sophia Lee", - alternateName: "MJ", - ethnonym: "German", - religion: null, - formerReligion: null, - profession: "Doctor", - gender: "Male", - interestingFeature: "Philanthropist", - interactionOrdinary: "Charismatic", - interactionOrdinaryExplanation: "Challenging", - interactionUnordinary: null, - interactionUnordinaryExplanation: "Controversial", - sources: [], - biography: "Left a significant impact.", - descriptionInSource: "A mysterious figure.", - explanationOfEthnicity: "Spanish", - version: "4.5", - }, - { - name: "Ali Veli", - alternateName: null, - ethnonym: "Spanish", - religion: "Islam", - formerReligion: null, - profession: "Scientist", - gender: "Female", - interestingFeature: "Great public speaker", - interactionOrdinary: null, - interactionOrdinaryExplanation: null, - interactionUnordinary: "Introverted", - interactionUnordinaryExplanation: "Leader", - sources: [], - biography: null, - descriptionInSource: null, - explanationOfEthnicity: null, - version: null, - }, - { - name: "Jane Smith", - alternateName: "M. Yılmaz", - ethnonym: "American", - religion: "Spiritual", - formerReligion: null, - profession: "Author", - gender: "Male", - interestingFeature: null, - interactionOrdinary: null, - interactionOrdinaryExplanation: null, - interactionUnordinary: null, - interactionUnordinaryExplanation: "Challenging", - sources: [], - biography: null, - descriptionInSource: null, - explanationOfEthnicity: null, - version: "4.5", - }, - { - name: "Elif Kaya", - alternateName: null, - ethnonym: "Russian", - religion: "Buddhism", - formerReligion: null, - profession: "Politician", - gender: "Other", - interestingFeature: null, - interactionOrdinary: "Leader", - interactionOrdinaryExplanation: "Supportive", - interactionUnordinary: null, - interactionUnordinaryExplanation: null, - sources: ["News Article"], - biography: "Famous in their field.", - descriptionInSource: null, - explanationOfEthnicity: null, - version: "2.1", - }, - { - name: "Ayşe Demir", - alternateName: null, - ethnonym: "Indian", - religion: "Christianity", - formerReligion: null, - profession: "Author", - gender: "Male", - interestingFeature: "Can speak 5 languages", - interactionOrdinary: "Introverted", - interactionOrdinaryExplanation: null, - interactionUnordinary: null, - interactionUnordinaryExplanation: null, - sources: ["Autobiography", "News Article"], - biography: null, - descriptionInSource: null, - explanationOfEthnicity: "American", - version: "4.5", - }, -]; diff --git a/mappafront/src/helpers/hooks/usePagination.ts b/mappafront/src/helpers/hooks/usePagination.ts deleted file mode 100644 index ec4cb42..0000000 --- a/mappafront/src/helpers/hooks/usePagination.ts +++ /dev/null @@ -1,59 +0,0 @@ -import { useState, useMemo } from "react"; - -interface UsePaginationProps { - _data: Object[]; - itemsPerPage?: number; - initialPage?: number; -} - -interface UsePaginationReturn { - currentPage: number; - totalPages: number; - paginatedData: Object[]; - nextPage: () => void; - prevPage: () => void; - goToPage: (page: number) => void; -} - -const usePagination = ({ - _data, - itemsPerPage = 4, // Varsayılan olarak 4 öğe gösterilecek - initialPage = 1, -}: UsePaginationProps): UsePaginationReturn => { - const totalItems = _data.length; - const totalPages = totalItems > 0 ? Math.ceil(totalItems / itemsPerPage) : 1; - const [currentPage, setCurrentPage] = useState( - Math.min(initialPage, totalPages) - ); - - // Sayfalara göre veriyi hesapla (useMemo ile optimize edildi) - const paginatedData = useMemo(() => { - const startIndex = (currentPage - 1) * itemsPerPage; - return _data.slice(startIndex, startIndex + itemsPerPage); - }, [_data, currentPage, itemsPerPage]); - - const nextPage = () => { - setCurrentPage((prev) => (prev < totalPages ? prev + 1 : prev)); - }; - - const prevPage = () => { - setCurrentPage((prev) => (prev > 1 ? prev - 1 : prev)); - }; - - const goToPage = (page: number) => { - if (page >= 1 && page <= totalPages) { - setCurrentPage(page); - } - }; - - return { - currentPage, - totalPages, - paginatedData, // Burada her sayfa için uygun verileri döndürür - nextPage, - prevPage, - goToPage, - }; -}; - -export default usePagination; diff --git a/mappafront/src/models/ordinary-people.ts b/mappafront/src/models/ordinary-people.ts index fe060e1..b26a550 100644 --- a/mappafront/src/models/ordinary-people.ts +++ b/mappafront/src/models/ordinary-people.ts @@ -1,23 +1,3 @@ -export type OrdinaryPeopleTableDataType = { - name: string; - alternateName?: string; - ethnonym?: string; - religion?: string; - formerReligion?: string; - profession?: string; - gender?: "Male" | "Female" | "Other"; - interestingFeature?: string; - interactionOrdinary?: string; - interactionOrdinaryExplanation?: string; - interactionUnordinary?: string; - interactionUnordinaryExplanation?: string; - sources?: string[]; - biography?: string; - descriptionInSource?: string; - explanationOfEthnicity?: string; - version?: string; -}; - export type OrdinaryPageRequestBody = { pageSize: number; pageNumber: number; diff --git a/mappafront/src/views/pages/ordinary-people/index.tsx b/mappafront/src/views/pages/ordinary-people/index.tsx index 1755325..23293fc 100644 --- a/mappafront/src/views/pages/ordinary-people/index.tsx +++ b/mappafront/src/views/pages/ordinary-people/index.tsx @@ -5,7 +5,7 @@ import Table from "@/views/components/table"; import { useEffect, useState } from "react"; import MappaModal from "@/views/components/modal"; -import { getOrdinaryPage } from "@/actions/ordinary"; +import { getOrdinaryPage } from "@/actions/ordinary-people"; import { OrdinaryPageResponseDataItem } from "@/models/ordinary-people"; const OrdinaryPeoplePage = () => { From 1cbf563762fbb9bb09bdd5af243d8cd8d92fd680 Mon Sep 17 00:00:00 2001 From: Simurgan Date: Sun, 23 Feb 2025 20:07:06 +0300 Subject: [PATCH 14/16] feat: update table content when page changes --- .../src/views/pages/ordinary-people/index.tsx | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/mappafront/src/views/pages/ordinary-people/index.tsx b/mappafront/src/views/pages/ordinary-people/index.tsx index 23293fc..b47c609 100644 --- a/mappafront/src/views/pages/ordinary-people/index.tsx +++ b/mappafront/src/views/pages/ordinary-people/index.tsx @@ -36,6 +36,18 @@ const OrdinaryPeoplePage = () => { } }; + const updateData = async () => { + const response = await getOrdinaryPage({ + pageNumber: tablePage, + pageSize: 10, + }); + + if (response.status === 200) { + setTableData(response.data.data); + setTotalPage(response.data.totalPages); + } + }; + const headerData = [ "Name", "Alternate Name", @@ -49,6 +61,10 @@ const OrdinaryPeoplePage = () => { setInitialData(); }, []); + useEffect(() => { + updateData(); + }, [tablePage]); + return (
From 7ee425a95a1cb443f74ba393b8972bf71efbc09a Mon Sep 17 00:00:00 2001 From: Simurgan Date: Sun, 23 Feb 2025 20:21:21 +0300 Subject: [PATCH 15/16] rebase commit with data-table branch --- mappafront/src/views/pages/map/index.tsx | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/mappafront/src/views/pages/map/index.tsx b/mappafront/src/views/pages/map/index.tsx index 0d42b81..ebdf90f 100644 --- a/mappafront/src/views/pages/map/index.tsx +++ b/mappafront/src/views/pages/map/index.tsx @@ -106,16 +106,8 @@ const MapPage = () => { // ]} > - {markers.map((item) => ( Date: Mon, 24 Feb 2025 00:16:03 +0300 Subject: [PATCH 16/16] feat: connect map to backend (only ordinary) --- mappafront/src/actions/map.ts | 16 ++ mappafront/src/models/map.ts | 13 ++ mappafront/src/views/pages/map/index.tsx | 174 ++++++++++++++++------ mappafront/src/views/pages/map/style.scss | 16 +- 4 files changed, 168 insertions(+), 51 deletions(-) create mode 100644 mappafront/src/actions/map.ts create mode 100644 mappafront/src/models/map.ts diff --git a/mappafront/src/actions/map.ts b/mappafront/src/actions/map.ts new file mode 100644 index 0000000..80e00ef --- /dev/null +++ b/mappafront/src/actions/map.ts @@ -0,0 +1,16 @@ +import { AxiosResponse } from "axios"; +import api from "./api"; +import { CityMapResponseDataItem } from "@/models/map"; + +const mapApi = api.create({ + baseURL: api.defaults.baseURL + "city/", +}); + +export const getCityMap = async () => { + const response = await mapApi({ + url: "map/", + method: "get", + }); + + return response as AxiosResponse; +}; diff --git a/mappafront/src/models/map.ts b/mappafront/src/models/map.ts new file mode 100644 index 0000000..f13add1 --- /dev/null +++ b/mappafront/src/models/map.ts @@ -0,0 +1,13 @@ +export type CityMapResponseDataItem = { + id: number; + name: string; + asciiName?: string; + latitude: number; + longitude: number; + numberOfLocationOf: number; + numberOfSourcesWrittenInTheCity: number; + numberOfSourcesMentioningTheCity: number; + numberOfBackgroundCityOf: number; + numberOfBirthPlaceOf: number; + numberOfDeathPlaceOf: number; +}; diff --git a/mappafront/src/views/pages/map/index.tsx b/mappafront/src/views/pages/map/index.tsx index ebdf90f..89aa3dd 100644 --- a/mappafront/src/views/pages/map/index.tsx +++ b/mappafront/src/views/pages/map/index.tsx @@ -3,10 +3,15 @@ import "leaflet/dist/leaflet.css"; import "./style.scss"; import L from "leaflet"; import Text from "@/views/components/text"; -import React, { useState } from "react"; +import React, { useEffect, useState } from "react"; import Button from "@/views/components/button"; import ReactModal from "react-modal"; import { FilterGroup } from "@/models/map-filters"; +import { getCityMap } from "@/actions/map"; +import { CityMapResponseDataItem } from "@/models/map"; +import Table from "@/views/components/table"; +import { OrdinaryPageResponseDataItem } from "@/models/ordinary-people"; +import { getOrdinaryPage } from "@/actions/ordinary-people"; ReactModal.setAppElement("#root"); // For blocking not working modal styles in some browsers. @@ -37,33 +42,16 @@ const filters: FilterGroup[] = [ const MapPage = () => { const [modalIsOpen, setIsOpen] = React.useState(false); - const [selectedMarker, setSelectedMarker] = useState(); - - const markers = [ - { id: 1, name: "İstanbul", latitude: 41.0082, longitude: 28.9784 }, - { id: 2, name: "Ankara", latitude: 39.9208, longitude: 32.8541 }, - { id: 3, name: "İzmir", latitude: 38.4192, longitude: 27.1287 }, - { id: 4, name: "Bursa", latitude: 40.1826, longitude: 29.0669 }, - { id: 5, name: "Antalya", latitude: 36.8841, longitude: 30.7056 }, - { id: 6, name: "Adana", latitude: 37.0, longitude: 35.3213 }, - { id: 7, name: "Gaziantep", latitude: 37.0662, longitude: 37.3833 }, - { id: 8, name: "Konya", latitude: 37.8713, longitude: 32.4846 }, - { id: 9, name: "Eskişehir", latitude: 39.7767, longitude: 30.5206 }, - { id: 10, name: "Trabzon", latitude: 41.0053, longitude: 39.726 }, - { id: 11, name: "Kayseri", latitude: 38.7312, longitude: 35.4787 }, - { id: 12, name: "Mersin", latitude: 36.8121, longitude: 34.6415 }, - { id: 13, name: "Samsun", latitude: 41.2867, longitude: 36.33 }, - { id: 14, name: "Erzurum", latitude: 39.9055, longitude: 41.2658 }, - { id: 15, name: "Van", latitude: 38.5012, longitude: 43.3727 }, - { id: 16, name: "Diyarbakır", latitude: 37.9158, longitude: 40.2189 }, - { id: 17, name: "Balıkesir", latitude: 39.6484, longitude: 27.8826 }, - { id: 18, name: "Malatya", latitude: 38.3555, longitude: 38.3096 }, - { id: 19, name: "Aydın", latitude: 37.8444, longitude: 27.8458 }, - { id: 20, name: "Şanlıurfa", latitude: 37.1674, longitude: 38.7955 }, - ]; + const [selectedMarker, setSelectedMarker] = + useState(); + const [cityData, setCityData] = useState([]); + const [markers, setMarkers] = useState([]); + const [tableData, setTableData] = useState(); + const [tablePage, setTablePage] = useState(); + const [totalPage, setTotalPage] = useState(); - function openModal(markerValue: string) { - setSelectedMarker(markerValue); + function openModal(marker: CityMapResponseDataItem) { + setSelectedMarker(marker); setIsOpen(true); } @@ -73,6 +61,73 @@ const MapPage = () => { setIsOpen(false); } + const getInitialData = async () => { + const response = await getCityMap(); + + if (response.status === 200) { + setCityData(response.data); + } + }; + + useEffect(() => { + getInitialData(); + }, []); + + useEffect(() => { + setMarkers( + cityData + .filter((city) => city.numberOfLocationOf > 0) + .map((city) => { + return { + ...city, + latitude: city.longitude, + longitude: city.latitude, + }; + }) + ); + }, [cityData]); + + useEffect(() => { + console.log(markers); + console.log("markers"); + }, [markers]); + + const getTableContent = async (cityId: number, page: number) => { + const response = await getOrdinaryPage({ + pageSize: 10, + pageNumber: page, + filter: { + location: [cityId], + }, + }); + + if (response.status === 200) { + setTableData(response.data.data); + setTotalPage(response.data.totalPages); + } + }; + + useEffect(() => { + if (selectedMarker) { + setTablePage(1); + } + }, [selectedMarker]); + + const headerData = [ + "Name", + "Alternate Name", + "Ethnonym", + "Religion", + "Profession", + "Gender", + ]; + + useEffect(() => { + if (selectedMarker && tablePage) { + getTableContent(selectedMarker?.id, tablePage); + } + }, [tablePage, selectedMarker]); + return (
@@ -85,26 +140,57 @@ const MapPage = () => { className="custom-modal" >
- - {selectedMarker} - - + +
+
( + + {cell} + + )), + rows: tableData?.map((ordinary) => { + const cellTexts = [ + ordinary.name, + ordinary.alternateName, + ordinary.ethnicity?.name, + ordinary.religion?.name, + ordinary.profession?.name, + ordinary.gender?.name, + ]; + return { + cells: cellTexts.map((cellText) => ( + + {cellText} + + )), + // onClick: () => openModal({}), + }; + }), + }} + />
- + { }) } eventHandlers={{ - click: () => openModal(item.name), + click: () => openModal(item), mouseover: (event) => { event.target.openPopup(); }, diff --git a/mappafront/src/views/pages/map/style.scss b/mappafront/src/views/pages/map/style.scss index 3d43287..9f03e2e 100644 --- a/mappafront/src/views/pages/map/style.scss +++ b/mappafront/src/views/pages/map/style.scss @@ -161,16 +161,18 @@ section.section.map-section { } .modal-content { - .modal-close-button { - position: fixed; - right: 0.2rem; - top: 0.2rem; - background-color: transparent; - border: none; - } padding: 20px; width: 100%; height: 100%; max-height: 100%; overflow-y: auto; + + .modal-header { + width: 100%; + display: flex; + justify-content: space-between; + } + + .modal-body { + } }