imio.smartweb.core 1.2.91__py3-none-any.whl → 1.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- imio/smartweb/core/browser/controlpanel.py +42 -5
- imio/smartweb/core/browser/utils.py +4 -1
- imio/smartweb/core/configure.zcml +5 -1
- imio/smartweb/core/contents/__init__.py +2 -0
- imio/smartweb/core/contents/rest/campaign/__init__.py +0 -0
- imio/smartweb/core/contents/rest/campaign/configure.zcml +80 -0
- imio/smartweb/core/contents/rest/campaign/content.py +83 -0
- imio/smartweb/core/contents/rest/campaign/endpoint.py +211 -0
- imio/smartweb/core/contents/rest/campaign/view.pt +19 -0
- imio/smartweb/core/contents/rest/campaign/view.py +29 -0
- imio/smartweb/core/contents/rest/configure.zcml +1 -0
- imio/smartweb/core/interfaces.py +4 -0
- imio/smartweb/core/overrides.zcml +10 -0
- imio/smartweb/core/profiles/default/metadata.xml +1 -1
- imio/smartweb/core/profiles/ideabox/browserlayer.xml +7 -0
- imio/smartweb/core/profiles/ideabox/metadata.xml +5 -0
- imio/smartweb/core/profiles/ideabox/registry/iaideabox.xml +9 -0
- imio/smartweb/core/profiles/ideabox/types/imio.smartweb.CampaignView.xml +40 -0
- imio/smartweb/core/profiles/ideabox/types/imio.smartweb.Folder.xml +71 -0
- imio/smartweb/core/profiles/ideabox/types.xml +17 -0
- imio/smartweb/core/profiles/ideabox_uninstall/browserlayer.xml +7 -0
- imio/smartweb/core/profiles/ideabox_uninstall/types/imio.smartweb.Folder.xml +25 -0
- imio/smartweb/core/profiles/ideabox_uninstall/types.xml +4 -0
- imio/smartweb/core/profiles/testing/metadata.xml +1 -0
- imio/smartweb/core/profiles/testing/registry.xml +2 -2
- imio/smartweb/core/profiles.zcml +18 -0
- imio/smartweb/core/subscribers.py +27 -1
- imio/smartweb/core/subscribers.zcml +8 -0
- imio/smartweb/core/tests/resources/json_ideabox_campaign.json +222 -0
- imio/smartweb/core/tests/resources/json_ideabox_campaigns.json +425 -0
- imio/smartweb/core/tests/resources/json_ideabox_projects.json +1871 -0
- imio/smartweb/core/tests/test_iadeliberations.py +38 -40
- imio/smartweb/core/tests/test_ideabox.py +120 -0
- imio/smartweb/core/tests/test_procedure.py +7 -3
- imio/smartweb/core/tests/test_rest.py +7 -0
- imio/smartweb/core/tests/test_vocabularies.py +8 -10
- imio/smartweb/core/upgrades/configure.zcml +16 -1
- imio/smartweb/core/upgrades/upgrades.py +64 -0
- imio/smartweb/core/utils.py +33 -0
- imio/smartweb/core/viewlets/ogptags.py +9 -0
- imio/smartweb/core/vocabularies.py +35 -4
- imio/smartweb/core/vocabularies.zcml +6 -0
- imio/smartweb/core/webcomponents/build/css/373.smartweb-webcomponents-compiled.css +1 -1
- imio/smartweb/core/webcomponents/build/css/420.smartweb-webcomponents-compiled.css +1 -0
- imio/smartweb/core/webcomponents/build/css/486.smartweb-webcomponents-compiled.css +1 -1
- imio/smartweb/core/webcomponents/build/css/666.smartweb-webcomponents-compiled.css +1 -0
- imio/smartweb/core/webcomponents/build/css/884.smartweb-webcomponents-compiled.css +1 -1
- imio/smartweb/core/webcomponents/build/css/smartweb-webcomponents-compiled.css +1 -1
- imio/smartweb/core/webcomponents/build/js/141.smartweb-webcomponents-compiled.js +2 -0
- imio/smartweb/core/webcomponents/build/js/{828.smartweb-webcomponents-compiled.js.LICENSE.txt → 141.smartweb-webcomponents-compiled.js.LICENSE.txt} +3 -3
- imio/smartweb/core/webcomponents/build/js/15.smartweb-webcomponents-compiled.js +2 -0
- imio/smartweb/core/webcomponents/build/js/21.smartweb-webcomponents-compiled.js +1 -0
- imio/smartweb/core/webcomponents/build/js/218.smartweb-webcomponents-compiled.js +1 -1
- imio/smartweb/core/webcomponents/build/js/218.smartweb-webcomponents-compiled.js.LICENSE.txt +0 -5
- imio/smartweb/core/webcomponents/build/js/373.smartweb-webcomponents-compiled.js +1 -1
- imio/smartweb/core/webcomponents/build/js/486.smartweb-webcomponents-compiled.js +1 -1
- imio/smartweb/core/webcomponents/build/js/666.smartweb-webcomponents-compiled.js +1 -0
- imio/smartweb/core/webcomponents/build/js/799.smartweb-webcomponents-compiled.js +1 -1
- imio/smartweb/core/webcomponents/build/js/824.smartweb-webcomponents-compiled.js +1 -1
- imio/smartweb/core/webcomponents/build/js/884.smartweb-webcomponents-compiled.js +1 -1
- imio/smartweb/core/webcomponents/build/js/919.smartweb-webcomponents-compiled.js +1 -1
- imio/smartweb/core/webcomponents/build/js/922.smartweb-webcomponents-compiled.js +1 -0
- imio/smartweb/core/webcomponents/build/js/smartweb-webcomponents-compiled.js +1 -1
- imio/smartweb/core/webcomponents/package.json +80 -80
- imio/smartweb/core/webcomponents/src/components/Annuaire/Annuaire.scss +1 -0
- imio/smartweb/core/webcomponents/src/components/Campaign/Campaign.jsx +306 -0
- imio/smartweb/core/webcomponents/src/components/Campaign/Campaign.scss +672 -0
- imio/smartweb/core/webcomponents/src/components/Campaign/CampaignCard/CampaignCard.jsx +79 -0
- imio/smartweb/core/webcomponents/src/components/Campaign/CampaignContent/CampaignContent.jsx +193 -0
- imio/smartweb/core/webcomponents/src/components/Campaign/CampaignList/CampaignList.jsx +67 -0
- imio/smartweb/core/webcomponents/src/components/Campaign/Filters/Filter.jsx +259 -0
- imio/smartweb/core/webcomponents/src/components/Campaign/index.js +2 -0
- imio/smartweb/core/webcomponents/src/components/Filters/MainFilter.scss +1 -0
- imio/smartweb/core/webcomponents/src/components/News/NewsContent/NewsContent.jsx +0 -1
- imio/smartweb/core/webcomponents/src/hooks/useAxios.js +45 -9
- imio/smartweb/core/webcomponents/src/index.jsx +2 -0
- imio/smartweb/core/webcomponents/src/index.scss +2 -2
- imio/smartweb/core/webcomponents/src/utils/CampaignMap.jsx +177 -0
- imio/smartweb/core/webcomponents/src/utils/Map.jsx +1 -1
- imio/smartweb/core/webcomponents/src/utils/Map.scss +15 -1
- imio/smartweb/core/webcomponents/src/utils/translation.js +235 -199
- {imio.smartweb.core-1.2.91.dist-info → imio.smartweb.core-1.3.dist-info}/METADATA +8 -1
- {imio.smartweb.core-1.2.91.dist-info → imio.smartweb.core-1.3.dist-info}/RECORD +90 -57
- imio/smartweb/core/webcomponents/build/js/499.smartweb-webcomponents-compiled.js +0 -2
- imio/smartweb/core/webcomponents/build/js/828.smartweb-webcomponents-compiled.js +0 -2
- /imio/smartweb/core/webcomponents/build/js/{499.smartweb-webcomponents-compiled.js.LICENSE.txt → 15.smartweb-webcomponents-compiled.js.LICENSE.txt} +0 -0
- /imio.smartweb.core-1.2.91-py3.12-nspkg.pth → /imio.smartweb.core-1.3-py3.12-nspkg.pth +0 -0
- {imio.smartweb.core-1.2.91.dist-info → imio.smartweb.core-1.3.dist-info}/LICENSE.GPL +0 -0
- {imio.smartweb.core-1.2.91.dist-info → imio.smartweb.core-1.3.dist-info}/LICENSE.rst +0 -0
- {imio.smartweb.core-1.2.91.dist-info → imio.smartweb.core-1.3.dist-info}/WHEEL +0 -0
- {imio.smartweb.core-1.2.91.dist-info → imio.smartweb.core-1.3.dist-info}/namespace_packages.txt +0 -0
- {imio.smartweb.core-1.2.91.dist-info → imio.smartweb.core-1.3.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,79 @@
|
|
1
|
+
import React, { useEffect, useState } from "react";
|
2
|
+
import { Translate } from "react-translated";
|
3
|
+
|
4
|
+
const CampaignCard = (props) => {
|
5
|
+
const [image, setImage] = useState(new Image());
|
6
|
+
const [imageClassName, setImageClassName] = useState("");
|
7
|
+
|
8
|
+
// Set image and image className
|
9
|
+
useEffect(() => {
|
10
|
+
const loadImage = async () => {
|
11
|
+
const img = new Image();
|
12
|
+
const src = props.item.images_raw[0].image.content || "";
|
13
|
+
|
14
|
+
img.src = "data:image/jpeg;base64," + src;
|
15
|
+
|
16
|
+
try {
|
17
|
+
await img.decode(); // Wait for the image to be decoded
|
18
|
+
setImage(img);
|
19
|
+
const imgClassName = img.width < img.height ? "img-contain" : "img-cover";
|
20
|
+
setImageClassName(imgClassName);
|
21
|
+
} catch (error) {
|
22
|
+
// Handle image loading errors here
|
23
|
+
console.error("Error loading image:", error);
|
24
|
+
}
|
25
|
+
};
|
26
|
+
|
27
|
+
if (props.item.images_raw[0].image.content) {
|
28
|
+
loadImage();
|
29
|
+
}
|
30
|
+
}, [props.item]);
|
31
|
+
|
32
|
+
return (
|
33
|
+
<>
|
34
|
+
<div className="r-list-item">
|
35
|
+
{image && image.src ? (
|
36
|
+
<>
|
37
|
+
<div className="r-item-img">
|
38
|
+
<div
|
39
|
+
className="r-content-figure-blur"
|
40
|
+
style={{ backgroundImage: "url(" + image.src + ")" }}
|
41
|
+
/>
|
42
|
+
<img
|
43
|
+
className={"r-content-figure-img" + " " + imageClassName}
|
44
|
+
src={image.src}
|
45
|
+
alt=""
|
46
|
+
/>
|
47
|
+
</div>
|
48
|
+
</>
|
49
|
+
) : (
|
50
|
+
<>
|
51
|
+
<div className="r-item-img r-item-img-placeholder"></div>
|
52
|
+
</>
|
53
|
+
)}
|
54
|
+
<div className="r-item-text">
|
55
|
+
<span className="r-item-title">{props.item.nom}</span>
|
56
|
+
<div className="campaign-vote">
|
57
|
+
<div className="campaign-vote-pour">
|
58
|
+
<i className="bi bi-hand-thumbs-up-fill"></i>
|
59
|
+
<span className="campaign-vote-pour-count">
|
60
|
+
{props.item.votes_pour}
|
61
|
+
</span>
|
62
|
+
</div>
|
63
|
+
<div className="campaign-vote-contre">
|
64
|
+
<i className="bi bi-hand-thumbs-down-fill"></i>
|
65
|
+
<span className="campaign-vote-contre-count">
|
66
|
+
{props.item.votes_contre}
|
67
|
+
</span>
|
68
|
+
</div>
|
69
|
+
</div>
|
70
|
+
</div>
|
71
|
+
<div className="r-item-arrow">
|
72
|
+
<i class="bi bi-chevron-right"></i>
|
73
|
+
</div>
|
74
|
+
</div>
|
75
|
+
</>
|
76
|
+
);
|
77
|
+
};
|
78
|
+
|
79
|
+
export default CampaignCard;
|
@@ -0,0 +1,193 @@
|
|
1
|
+
import { useNavigate } from "react-router-dom";
|
2
|
+
import React, { useEffect, useState } from "react";
|
3
|
+
import useAxios from "../../../hooks/useAxios";
|
4
|
+
import useFilterQuery from "../../../hooks/useFilterQuery";
|
5
|
+
import "spotlight.js";
|
6
|
+
import "../../../../node_modules/flexbin/flexbin.css";
|
7
|
+
import { Translate } from "react-translated";
|
8
|
+
import queryString from "query-string";
|
9
|
+
|
10
|
+
export default function CampaignContent({ queryUrl, onChange }) {
|
11
|
+
const navigate = useNavigate();
|
12
|
+
const { u, ...parsed } = Object.assign({
|
13
|
+
id: queryString.parse(useFilterQuery().toString())["u"],
|
14
|
+
b_start: 0,
|
15
|
+
});
|
16
|
+
const [params, setParams] = useState(parsed);
|
17
|
+
const [item, setitem] = useState(null);
|
18
|
+
const [urlVotePour, setUrlVotePour] = useState(null);
|
19
|
+
const [urlVoteContre, setUrlVoteContre] = useState(null);
|
20
|
+
|
21
|
+
const [files, setFiles] = useState();
|
22
|
+
const { response, error, isLoading } = useAxios(
|
23
|
+
{
|
24
|
+
method: "get",
|
25
|
+
url: "",
|
26
|
+
baseURL: queryUrl,
|
27
|
+
headers: {
|
28
|
+
Accept: "application/json",
|
29
|
+
},
|
30
|
+
params: params,
|
31
|
+
},
|
32
|
+
[]
|
33
|
+
);
|
34
|
+
|
35
|
+
// set all contacts state
|
36
|
+
useEffect(() => {
|
37
|
+
if (response !== null) {
|
38
|
+
setitem(response.fields);
|
39
|
+
const parsedUrl = new URL(response.url);
|
40
|
+
const baseUrl = `${parsedUrl.protocol}//${parsedUrl.hostname}`;
|
41
|
+
const fullUrlPour = `${baseUrl}/ideabox-voter-pour-un-projet/?projet=${response.id}`;
|
42
|
+
const fullUrlContre = `${baseUrl}/ideabox-voter-contre-un-projet/?projet=${response.id}`;
|
43
|
+
|
44
|
+
setUrlVotePour(fullUrlPour);
|
45
|
+
setUrlVoteContre(fullUrlContre);
|
46
|
+
}
|
47
|
+
|
48
|
+
window.scrollTo({
|
49
|
+
top: 0,
|
50
|
+
left: 0,
|
51
|
+
behavior: "instant",
|
52
|
+
});
|
53
|
+
}, [response]);
|
54
|
+
|
55
|
+
function handleClick() {
|
56
|
+
navigate("..");
|
57
|
+
onChange(null);
|
58
|
+
}
|
59
|
+
return !isLoading ? (
|
60
|
+
<div className="campaign-content r-content">
|
61
|
+
<button type="button" onClick={handleClick}>
|
62
|
+
<Translate text="Retour" />
|
63
|
+
</button>
|
64
|
+
<ContentText item={item} urlVotePour={urlVotePour} urlVoteContre={urlVoteContre} />
|
65
|
+
</div>
|
66
|
+
) : (
|
67
|
+
<div className="lds-roller-container">
|
68
|
+
<div className="lds-roller">
|
69
|
+
<div></div>
|
70
|
+
<div></div>
|
71
|
+
<div></div>
|
72
|
+
<div></div>
|
73
|
+
<div></div>
|
74
|
+
<div></div>
|
75
|
+
<div></div>
|
76
|
+
<div></div>
|
77
|
+
</div>
|
78
|
+
</div>
|
79
|
+
);
|
80
|
+
}
|
81
|
+
|
82
|
+
function ContentText({ item, urlVotePour, urlVoteContre }) {
|
83
|
+
const [image, setImage] = useState(new Image());
|
84
|
+
const [imageClassName, setImageClassName] = useState("");
|
85
|
+
|
86
|
+
useEffect(() => {
|
87
|
+
if (item) {
|
88
|
+
// Set image and image className
|
89
|
+
const src = item.images_raw[0].image.content || "";
|
90
|
+
const img = new Image();
|
91
|
+
img.src = "data:image/jpeg;base64," + src;
|
92
|
+
|
93
|
+
img.onload = () => {
|
94
|
+
setImage(img);
|
95
|
+
const imgClassName = img.width < img.height ? "img-contain" : "img-cover";
|
96
|
+
setImageClassName(imgClassName);
|
97
|
+
};
|
98
|
+
|
99
|
+
img.onerror = (error) => {
|
100
|
+
// Handle image loading errors here
|
101
|
+
console.error("Error loading image:", error);
|
102
|
+
};
|
103
|
+
}
|
104
|
+
}, [item]);
|
105
|
+
return (
|
106
|
+
<>
|
107
|
+
<article>
|
108
|
+
<header>
|
109
|
+
<h2 className="r-content-title">{item.nom}</h2>
|
110
|
+
</header>
|
111
|
+
<figure>
|
112
|
+
<div className="campaign-vote" style={{ marginTop: "1.5rem" }}>
|
113
|
+
<a href={urlVotePour} target="_blank" className="campaign-vote-pour">
|
114
|
+
<i className="bi bi-hand-thumbs-up-fill"></i>
|
115
|
+
<span className="campaign-vote-pour-count">({item.votes_pour})</span>
|
116
|
+
<span className="campaign-vote-contre-text"> Je vote pour</span>
|
117
|
+
</a>
|
118
|
+
<a href={urlVoteContre} target="_blank" className="campaign-vote-contre">
|
119
|
+
<i className="bi bi-hand-thumbs-down-fill"></i>
|
120
|
+
<span className="campaign-vote-contre-count">
|
121
|
+
({item.votes_contre})
|
122
|
+
</span>
|
123
|
+
<span className="campaign-vote-contre-text"> Je vote contre</span>
|
124
|
+
</a>
|
125
|
+
</div>
|
126
|
+
{image ? (
|
127
|
+
<div className="r-content-img">
|
128
|
+
<div
|
129
|
+
className="r-content-figure-blur"
|
130
|
+
style={{ backgroundImage: "url(" + image.src + ")" }}
|
131
|
+
/>
|
132
|
+
<img
|
133
|
+
className={"r-content-figure-img" + " " + imageClassName}
|
134
|
+
src={image.src}
|
135
|
+
alt=""
|
136
|
+
/>
|
137
|
+
</div>
|
138
|
+
) : (
|
139
|
+
<>
|
140
|
+
<div className="r-item-img r-item-img-placeholder"></div>
|
141
|
+
</>
|
142
|
+
)}
|
143
|
+
</figure>
|
144
|
+
</article>
|
145
|
+
<div className="contactCard">
|
146
|
+
<div className="contactText">
|
147
|
+
<div className="r-content-description">
|
148
|
+
{item.description && (
|
149
|
+
<div
|
150
|
+
className="campaign-description"
|
151
|
+
dangerouslySetInnerHTML={{
|
152
|
+
__html: item.description,
|
153
|
+
}}
|
154
|
+
/>
|
155
|
+
)}
|
156
|
+
</div>
|
157
|
+
|
158
|
+
<div className="contactTextAll"></div>
|
159
|
+
</div>
|
160
|
+
{/* add files to download */}
|
161
|
+
{/* {files && (
|
162
|
+
<div className="r-content-files">
|
163
|
+
{files.map((file, i) => (
|
164
|
+
<div key={i} className="r-content-file">
|
165
|
+
<a
|
166
|
+
href={file.targetUrl}
|
167
|
+
className="r-content-file-link"
|
168
|
+
rel="nofollow"
|
169
|
+
>
|
170
|
+
<span className="r-content-file-title">{file.title}</span>
|
171
|
+
<span className="r-content-file-icon">
|
172
|
+
<svg
|
173
|
+
width="21"
|
174
|
+
height="21"
|
175
|
+
viewBox="0 0 24 24"
|
176
|
+
fill="none"
|
177
|
+
stroke="#8899a4"
|
178
|
+
stroke-width="2"
|
179
|
+
stroke-linecap="square"
|
180
|
+
stroke-linejoin="arcs"
|
181
|
+
>
|
182
|
+
<path d="M3 15v4c0 1.1.9 2 2 2h14a2 2 0 0 0 2-2v-4M17 9l-5 5-5-5M12 12.8V2.5"></path>
|
183
|
+
</svg>
|
184
|
+
</span>
|
185
|
+
</a>
|
186
|
+
</div>
|
187
|
+
))}
|
188
|
+
</div>
|
189
|
+
)} */}
|
190
|
+
</div>
|
191
|
+
</>
|
192
|
+
);
|
193
|
+
}
|
@@ -0,0 +1,67 @@
|
|
1
|
+
import React, { useEffect, useContext } from "react";
|
2
|
+
import CampaignCard from "../CampaignCard/CampaignCard";
|
3
|
+
import { Link } from "react-router-dom";
|
4
|
+
import removeAccents from "remove-accents";
|
5
|
+
import { ScrollContext } from "../../../hooks/ScrollContext";
|
6
|
+
const CampaignList = ({
|
7
|
+
itemsArray,
|
8
|
+
onChange,
|
9
|
+
onHover,
|
10
|
+
showCategoriesOrTopics,
|
11
|
+
contextAuthenticatedUser,
|
12
|
+
}) => {
|
13
|
+
const { scrollPos, updateScrollPos } = useContext(ScrollContext);
|
14
|
+
|
15
|
+
function handleClick(event) {
|
16
|
+
onChange(event);
|
17
|
+
updateScrollPos(window.scrollY);
|
18
|
+
}
|
19
|
+
|
20
|
+
function handleHover(event) {
|
21
|
+
onHover(event);
|
22
|
+
}
|
23
|
+
|
24
|
+
useEffect(() => {
|
25
|
+
window.scrollTo({ top: scrollPos, left: 0, behavior: "instant" });
|
26
|
+
}, [itemsArray]);
|
27
|
+
|
28
|
+
return (
|
29
|
+
<React.Fragment>
|
30
|
+
<ul className="r-result-list event-result-list">
|
31
|
+
{itemsArray.map((item, i) => (
|
32
|
+
<li
|
33
|
+
key={i}
|
34
|
+
className="r-list-item-group"
|
35
|
+
onMouseEnter={() => handleHover(item.id)}
|
36
|
+
onMouseLeave={() => handleHover(null)}
|
37
|
+
onClick={() => handleClick(item.id)}
|
38
|
+
>
|
39
|
+
<Link
|
40
|
+
className="r-list-item-link"
|
41
|
+
style={{ textDecoration: "none" }}
|
42
|
+
to={{
|
43
|
+
pathname:
|
44
|
+
"/" +
|
45
|
+
removeAccents(item.text)
|
46
|
+
.replace(/[^a-zA-Z ]/g, "")
|
47
|
+
.replace(/\s/g, "-")
|
48
|
+
.toLowerCase(),
|
49
|
+
search: `?u=${item.id}`,
|
50
|
+
state: {
|
51
|
+
idItem: item.id,
|
52
|
+
},
|
53
|
+
}}
|
54
|
+
></Link>
|
55
|
+
<CampaignCard
|
56
|
+
item={item.fields}
|
57
|
+
showCategoriesOrTopics={showCategoriesOrTopics}
|
58
|
+
key={item.created}
|
59
|
+
contextAuthenticatedUser={contextAuthenticatedUser}
|
60
|
+
/>
|
61
|
+
</li>
|
62
|
+
))}
|
63
|
+
</ul>
|
64
|
+
</React.Fragment>
|
65
|
+
);
|
66
|
+
};
|
67
|
+
export default CampaignList;
|
@@ -0,0 +1,259 @@
|
|
1
|
+
import React, { useEffect, useRef, useCallback, useState } from "react";
|
2
|
+
import Select from "react-select";
|
3
|
+
import { useNavigate } from "react-router-dom";
|
4
|
+
import useAxios from "../../../hooks/useAxios";
|
5
|
+
import { Translator, Translate } from "react-translated";
|
6
|
+
// import DateFilter from "../../Filters/DateFilter";
|
7
|
+
import moment from "moment";
|
8
|
+
import queryString from "query-string";
|
9
|
+
// import { taxonomy_event_public } from "./../../Filters/PublicTargetData";
|
10
|
+
// import { iam } from "./../../Filters/IamData";
|
11
|
+
import { menuStyles, moreFilterStyles } from "./../../Filters/SelectStyles";
|
12
|
+
|
13
|
+
function Filters(props) {
|
14
|
+
let navigate = useNavigate();
|
15
|
+
const [inputValues, setInputValues] = useState(props.activeFilter);
|
16
|
+
const [topicsFilter, setTopicsFilter] = useState(null);
|
17
|
+
const [zonesFilter, setZonesFilter] = useState(null);
|
18
|
+
// const [localsCategoryFilter, setLocalsCategoryFilter] = useState([]);
|
19
|
+
const [dates, setDates] = useState(null);
|
20
|
+
// Get data
|
21
|
+
const { response, error, isLoading } = useAxios({
|
22
|
+
method: "get",
|
23
|
+
url: [
|
24
|
+
{ url: props.queryZonesUrl, identifier: "zones" },
|
25
|
+
{ url: props.queryTopicsUrl, identifier: "topics" },
|
26
|
+
],
|
27
|
+
headers: {
|
28
|
+
Accept: "application/json",
|
29
|
+
},
|
30
|
+
params: inputValues,
|
31
|
+
paramsSerializer: { indexes: null },
|
32
|
+
});
|
33
|
+
|
34
|
+
// set fitlers data to state
|
35
|
+
useEffect(() => {
|
36
|
+
if (response !== null) {
|
37
|
+
const optionsTopics =
|
38
|
+
response.topics &&
|
39
|
+
response.topics.items.map((d) => ({
|
40
|
+
value: d.value,
|
41
|
+
label: d.title,
|
42
|
+
}));
|
43
|
+
const optionsCategory =
|
44
|
+
response.category &&
|
45
|
+
response.category.map((d) => ({
|
46
|
+
value: d.token,
|
47
|
+
label: d.title,
|
48
|
+
queryString: "category",
|
49
|
+
}));
|
50
|
+
const optionsZones =
|
51
|
+
response.zones &&
|
52
|
+
response.zones.items.map((d) => ({
|
53
|
+
value: d.id,
|
54
|
+
label: d.digest,
|
55
|
+
queryString: "zones",
|
56
|
+
}));
|
57
|
+
setTopicsFilter(optionsTopics);
|
58
|
+
setZonesFilter(optionsZones);
|
59
|
+
|
60
|
+
// setLocalsCategoryFilter(optionsLocalsCategory);
|
61
|
+
}
|
62
|
+
}, [response]);
|
63
|
+
|
64
|
+
// const to group category and local category
|
65
|
+
// const groupedOptions = [
|
66
|
+
// {
|
67
|
+
// label: <Translate text="Catégories spécifiques" />,
|
68
|
+
// options: localsCategoryFilter,
|
69
|
+
// },
|
70
|
+
// {
|
71
|
+
// label: <Translate text="Catégories" />,
|
72
|
+
// options: categoryFilter,
|
73
|
+
// },
|
74
|
+
// ];
|
75
|
+
|
76
|
+
const onChangeHandler = useCallback(({ target: { name, value } }) => {
|
77
|
+
if (value.length > 2) {
|
78
|
+
setInputValues((state) => ({ ...state, [name]: value }), []);
|
79
|
+
} else {
|
80
|
+
setInputValues((prevState) => {
|
81
|
+
const state = { ...prevState };
|
82
|
+
const { [name]: remove, ...rest } = state;
|
83
|
+
return rest;
|
84
|
+
});
|
85
|
+
}
|
86
|
+
});
|
87
|
+
const onChangeHandlerSelect = useCallback((value, action) => {
|
88
|
+
const inputName = action.name;
|
89
|
+
if (value) {
|
90
|
+
setInputValues((state) => ({ ...state, [inputName]: value.value }), []);
|
91
|
+
} else {
|
92
|
+
setInputValues((prevState) => {
|
93
|
+
const state = { ...prevState };
|
94
|
+
const { [inputName]: remove, ...rest } = state;
|
95
|
+
return rest;
|
96
|
+
});
|
97
|
+
}
|
98
|
+
});
|
99
|
+
// const onChangeCheckbox = useCallback((value, action) => {
|
100
|
+
// if (value.target.checked) {
|
101
|
+
// setInputValues((state) => ({ ...state, free_entry: true }), []);
|
102
|
+
// } else {
|
103
|
+
// setInputValues((state) => {
|
104
|
+
// const newState = { ...state };
|
105
|
+
// delete newState["free_entry"];
|
106
|
+
// return newState;
|
107
|
+
// }, []);
|
108
|
+
// }
|
109
|
+
// });
|
110
|
+
|
111
|
+
const onChangeGroupSelect = useCallback((value, action) => {
|
112
|
+
if (value) {
|
113
|
+
setInputValues((state) => ({ ...state, [value.queryString]: value.value }), []);
|
114
|
+
} else {
|
115
|
+
setInputValues((prevState) => {
|
116
|
+
const state = { ...prevState };
|
117
|
+
const { [action.removedValues[0].queryString]: remove, ...rest } = state;
|
118
|
+
return rest;
|
119
|
+
});
|
120
|
+
}
|
121
|
+
});
|
122
|
+
|
123
|
+
// make to no launch useEffect first time
|
124
|
+
const firstUpdate = useRef(true);
|
125
|
+
useEffect(() => {
|
126
|
+
if (firstUpdate.current) {
|
127
|
+
firstUpdate.current = false;
|
128
|
+
return;
|
129
|
+
}
|
130
|
+
navigate({
|
131
|
+
pathname: "./",
|
132
|
+
search: queryString.stringify(inputValues),
|
133
|
+
});
|
134
|
+
props.onChange(inputValues);
|
135
|
+
}, [inputValues]);
|
136
|
+
|
137
|
+
function handleSubmit(e) {
|
138
|
+
e.preventDefault();
|
139
|
+
props.onChange(inputValues);
|
140
|
+
}
|
141
|
+
// set default input value
|
142
|
+
let actTopi =
|
143
|
+
topicsFilter && topicsFilter.filter((option) => option.value === props.activeFilter.topics);
|
144
|
+
|
145
|
+
let actZones =
|
146
|
+
zonesFilter && zonesFilter.filter((option) => option.value === props.activeFilter.zones);
|
147
|
+
// let actCategory =
|
148
|
+
// categoryFilter &&
|
149
|
+
// categoryFilter.filter((option) => option.value === props.activeFilter.category);
|
150
|
+
|
151
|
+
// let actTarget =
|
152
|
+
// taxonomy_event_public &&
|
153
|
+
// taxonomy_event_public.filter((option) => option.value === props.activeFilter.topics);
|
154
|
+
|
155
|
+
// let actIam = iam && iam.filter((option) => option.value === props.activeFilter.topics);
|
156
|
+
|
157
|
+
useEffect(() => {
|
158
|
+
if (dates) {
|
159
|
+
setInputValues((prevState) => {
|
160
|
+
if (dates["event_dates.query"].length > 1) {
|
161
|
+
const { "event_dates.range": _, ...rest } = dates;
|
162
|
+
const newValue = "min:max";
|
163
|
+
return { ...prevState, ...rest, "event_dates.range": newValue };
|
164
|
+
} else if (dates["event_dates.query"].every((item) => item === null)) {
|
165
|
+
return {
|
166
|
+
...prevState,
|
167
|
+
"event_dates.query": [moment().format("YYYY-MM-DD")],
|
168
|
+
"event_dates.range": "min",
|
169
|
+
};
|
170
|
+
} else {
|
171
|
+
return { ...prevState, ...dates, "event_dates.range": "min" };
|
172
|
+
}
|
173
|
+
});
|
174
|
+
}
|
175
|
+
}, [dates]);
|
176
|
+
|
177
|
+
return (
|
178
|
+
<React.Fragment>
|
179
|
+
<div className="react-filters-menu">
|
180
|
+
<div className="react-filters-container">
|
181
|
+
<form className="r-filter r-filter-search" onSubmit={handleSubmit}>
|
182
|
+
{/* <label>Recherche</label> */}
|
183
|
+
<div className="relative">
|
184
|
+
<Translator>
|
185
|
+
{({ translate }) => (
|
186
|
+
<input
|
187
|
+
className="input-custom-class"
|
188
|
+
name="SearchableText"
|
189
|
+
type="text"
|
190
|
+
value={inputValues.SearchableText}
|
191
|
+
onChange={onChangeHandler}
|
192
|
+
placeholder={translate({
|
193
|
+
text: "Recherche",
|
194
|
+
})}
|
195
|
+
/>
|
196
|
+
)}
|
197
|
+
</Translator>
|
198
|
+
<svg
|
199
|
+
xmlns="http://www.w3.org/2000/svg"
|
200
|
+
fill="none"
|
201
|
+
stroke="#9f9f9f"
|
202
|
+
strokeWidth="4"
|
203
|
+
aria-hidden="true"
|
204
|
+
display="block"
|
205
|
+
overflow="visible"
|
206
|
+
style={{ height: 16, width: 16 }}
|
207
|
+
viewBox="0 0 32 32"
|
208
|
+
>
|
209
|
+
<path d="M13 24a11 11 0 1 0 0-22 11 11 0 0 0 0 22zm8-3 9 9" />
|
210
|
+
</svg>
|
211
|
+
</div>
|
212
|
+
</form>
|
213
|
+
<div className="react-sep-menu"></div>
|
214
|
+
{/* Filtre Thématique */}
|
215
|
+
{/* Filtre Thématique */}
|
216
|
+
<div className="r-filter top-filter topics-Filter">
|
217
|
+
<Translator>
|
218
|
+
{({ translate }) => (
|
219
|
+
<Select
|
220
|
+
styles={menuStyles}
|
221
|
+
name={"filter-themes"}
|
222
|
+
className="select-custom-no-border"
|
223
|
+
isClearable
|
224
|
+
onChange={onChangeHandlerSelect}
|
225
|
+
options={topicsFilter && topicsFilter}
|
226
|
+
placeholder={translate({
|
227
|
+
text: "Thématiques",
|
228
|
+
})}
|
229
|
+
value={actTopi && actTopi[0]}
|
230
|
+
/>
|
231
|
+
)}
|
232
|
+
</Translator>
|
233
|
+
</div>
|
234
|
+
|
235
|
+
<div className="r-filter top-filter topics-Filter">
|
236
|
+
<Translator>
|
237
|
+
{({ translate }) => (
|
238
|
+
<Select
|
239
|
+
styles={menuStyles}
|
240
|
+
name={"filter-zones"}
|
241
|
+
className="select-custom-no-border"
|
242
|
+
isClearable
|
243
|
+
onChange={onChangeHandlerSelect}
|
244
|
+
options={zonesFilter && zonesFilter}
|
245
|
+
placeholder={translate({
|
246
|
+
text: "Zones",
|
247
|
+
})}
|
248
|
+
value={actZones && actZones[0]}
|
249
|
+
/>
|
250
|
+
)}
|
251
|
+
</Translator>
|
252
|
+
</div>
|
253
|
+
</div>
|
254
|
+
</div>
|
255
|
+
</React.Fragment>
|
256
|
+
);
|
257
|
+
}
|
258
|
+
|
259
|
+
export default Filters;
|
@@ -56,7 +56,6 @@ const ContactContent = ({ queryUrl, onChange, contextAuthenticatedUser }) => {
|
|
56
56
|
|
57
57
|
// Function to generate iframe URL
|
58
58
|
const getIframeSrc = (url) => {
|
59
|
-
console.log(item.video_url);
|
60
59
|
if (url.includes("youtube.com") || url.includes("youtu.be")) {
|
61
60
|
const urlParams = new URLSearchParams(new URL(url).search);
|
62
61
|
const videoId = urlParams.get("v") || url.split("/").pop();
|