Skip to content

Commit c76e4e1

Browse files
authored
Merge pull request #61 from iranpsc/fix/logic-bugs
fix map polygan and building logic
2 parents 8ab7205 + 401d2cb commit c76e4e1

68 files changed

Lines changed: 1609 additions & 1044 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

src/App.jsx

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
1-
import { useEffect, useLayoutEffect, useState } from "react";
2-
import { BrowserRouter, useNavigate } from "react-router-dom"; // Import useNavigate
1+
import { useLayoutEffect } from "react";
2+
import { BrowserRouter } from "react-router-dom"; // Import useNavigate
33
import { Toaster } from "react-hot-toast";
4-
import { useTranslation } from "react-i18next";
54
import "./App.css";
65
import "react-quill/dist/quill.snow.css";
76
import styled from "styled-components";
@@ -21,7 +20,6 @@ import { MapProvider } from "react-map-gl";
2120
import { SelectedEnvironmentProvider } from "./services/reducers/SelectedEnvironmentContext.jsx";
2221
import { AlertProvider } from "./services/reducers/AlertContext.jsx";
2322
import Routers from "./layouts/map/Routers.jsx";
24-
import { getFieldTranslationByNames } from "./services/Utility/index.jsx";
2523
import { LanguageProvider } from "./services/reducers/LanguageContext.jsx";
2624
import { LoaderProvider } from "./services/reducers/LoaderProvider.jsx";
2725
import RotateDevice from "./components/RotateDevice";
@@ -49,7 +47,6 @@ const Container = styled.section`
4947
function App() {
5048
useAppHeight();
5149

52-
console.log(useTranslation());
5350
useLayoutEffect(() => {
5451
window.Echo = new Echo({
5552
broadcaster: "pusher",
5.63 KB
Binary file not shown.

src/assets/gif/clockdark.gif

23.3 KB
Loading

src/assets/gif/clocklight.gif

23.1 KB
Loading

src/assets/images/3ddevelop.jpg

11.8 KB
Loading

src/components/Button.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ const ButtonElement = styled.button`
5050
}
5151
5252
@media (min-width: 998px) {
53-
height: 50px;
53+
height: ${(props) => (props.large ? "40px" : "50px")};
5454
}
5555
img {
5656
width: 25px;
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import "react-quill/dist/quill.snow.css";
2+
import React, { useState, useEffect } from "react";
3+
import ReactQuill from "react-quill";
4+
import { CiEdit } from "react-icons/ci";
5+
import {
6+
convertToPersian,
7+
getFieldTranslationByNames,
8+
} from "../../services/Utility";
9+
import {
10+
EditorContainer as StyledEditorContainer,
11+
Label,
12+
Char,
13+
formats,
14+
modulesWithoutImage,
15+
} from "../editorContainerStyle";
16+
17+
/**
18+
* Reusable RichTextEditor with strict char limit
19+
*
20+
* Props:
21+
* - value: string (initial content)
22+
* - onChange: function (called when value changes)
23+
* - charLimit: number (max characters)
24+
* - label: string (optional label above editor)
25+
* - showIcon: boolean (whether to show CiEdit icon)
26+
* - placeholder: string (placeholder when empty)
27+
*/
28+
const CustomEditor = ({
29+
value = "",
30+
onChange,
31+
charLimit = 2000,
32+
label,
33+
showIcon = true,
34+
placeholder = "",
35+
}) => {
36+
const [content, setContent] = useState(value);
37+
38+
useEffect(() => {
39+
setContent(value);
40+
}, [value]);
41+
const handleChange = (val, delta, source, editor) => {
42+
// طول واقعی متن بدون html
43+
const text = editor.getText(); // این متن plain text است
44+
let newValue = val;
45+
46+
if (text.length - 1 > charLimit) {
47+
// -1 چون editor یه \n اضافه می‌کنه
48+
const allowedText = text.slice(0, charLimit);
49+
// جایگزینی متن editor با محدودیت
50+
const quill = editor;
51+
quill.deleteText(charLimit, text.length); // بقیه رو حذف می‌کنه
52+
newValue = quill.root.innerHTML;
53+
}
54+
55+
setContent(newValue);
56+
onChange?.(newValue);
57+
};
58+
59+
const handleKeyDown = (event) => {
60+
const allowedKeys = [
61+
"Backspace",
62+
"Delete",
63+
"ArrowLeft",
64+
"ArrowRight",
65+
"ArrowUp",
66+
"ArrowDown",
67+
];
68+
if (content.length >= charLimit && !allowedKeys.includes(event.key)) {
69+
event.preventDefault();
70+
}
71+
};
72+
73+
const handlePaste = (event) => {
74+
event.preventDefault();
75+
const paste = event.clipboardData.getData("text");
76+
const remaining = charLimit - content.length;
77+
if (remaining <= 0) return; // هیچ چیزی اضافه نشود
78+
const toPaste = paste.slice(0, remaining);
79+
const newValue = content + toPaste;
80+
setContent(newValue);
81+
onChange?.(newValue);
82+
};
83+
84+
const remainingChars = charLimit - content.length;
85+
const isOverLimit = remainingChars <= 0;
86+
87+
return (
88+
<div>
89+
{label && <Label>{label}</Label>}
90+
<StyledEditorContainer>
91+
<ReactQuill
92+
value={content}
93+
onChange={handleChange}
94+
onKeyDown={handleKeyDown}
95+
onPaste={handlePaste}
96+
modules={modulesWithoutImage}
97+
formats={formats}
98+
placeholder={placeholder}
99+
/>
100+
</StyledEditorContainer>
101+
<Char isOverLimit={isOverLimit}>
102+
<span>
103+
{convertToPersian(remainingChars)} {getFieldTranslationByNames("530")}
104+
</span>
105+
{showIcon && <CiEdit size={20} />}
106+
</Char>
107+
</div>
108+
);
109+
};
110+
111+
export default CustomEditor;
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import styled from "styled-components";
2+
3+
const Wrapper = styled.div`
4+
cursor: pointer;
5+
`;
6+
7+
const Menu = styled.ul`
8+
display: flex;
9+
flex-direction: column;
10+
align-items: center;
11+
padding-top: 8px;
12+
`;
13+
14+
const Item = styled.li`
15+
width: 100%;
16+
display: flex;
17+
gap: 10px;
18+
justify-content: flex-start;
19+
color: flex-start;
20+
padding: 6px 0;
21+
cursor: pointer;
22+
23+
&:hover {
24+
color: #0066ff;
25+
}
26+
`;
27+
28+
const Name = styled.p`
29+
max-width: 200px;
30+
overflow: hidden;
31+
transition: max-width 0.2s ease;
32+
33+
color: ${(p) => (p.selected ? p.theme.colors.primary : "#858585")};
34+
:hover {
35+
color: ${({ theme }) => theme.colors.primary};
36+
}
37+
`;
38+
39+
// ===============================
40+
// COMPONENT
41+
// ===============================
42+
export default function DropdownLanguageModule({
43+
langArray,
44+
currentLangObject,
45+
changeLanguage,
46+
currentLang,
47+
setIsLangOpen,
48+
isLangOpen,
49+
}) {
50+
return (
51+
<Wrapper>
52+
<Menu>
53+
{langArray?.map((item) => (
54+
<Item
55+
key={item.id}
56+
onClick={() => {
57+
changeLanguage(item.code); // ← تغییر زبان با انتخاب آیتم
58+
setIsLangOpen(!isLangOpen);
59+
}}
60+
>
61+
<img
62+
src={item.icon}
63+
alt={item.native_name}
64+
width={28}
65+
height={28}
66+
/>
67+
<Name selected={currentLang === item.code}>{item.native_name}</Name>
68+
</Item>
69+
))}
70+
</Menu>
71+
</Wrapper>
72+
);
73+
}

0 commit comments

Comments
 (0)