Added trade unions
This commit is contained in:
parent
8e88a5a895
commit
73ece83c60
|
@ -0,0 +1,279 @@
|
|||
module TradeUnionsController
|
||||
|
||||
using Genie, Genie.Renderer, Genie.Renderer.Html, Genie.Requests, GenieAuthentication, DataFrames
|
||||
using JSON3
|
||||
using SearchLight,SearchLightPostgreSQL, LibPQ, JSON3
|
||||
using Server.DatabaseSupport, Server.TemplateEditor, Server.Users
|
||||
import Server.DatabaseSupport: select_from_table, insert_into_table, delete_from_table, exist_in_table
|
||||
|
||||
controller = "trade_unions"
|
||||
dict_layouts = Dict(
|
||||
:trade_unions => generate_layout_html("main",controller,"trade_unions",libraries=["Leaflet"]),
|
||||
:trade_unions_add => generate_layout_html("main",controller,"trade_unions_add",libraries=["Leaflet"]),
|
||||
)
|
||||
|
||||
#---Page info-----------------------------------------------------
|
||||
|
||||
const trade_unions_info = Dict(
|
||||
"en" => Dict(
|
||||
:title => "LibSoc - Trade Unions",
|
||||
:description => ""
|
||||
),
|
||||
"ru" => Dict(
|
||||
:title => "LibSoc - Профсоюзы",
|
||||
:description => ""
|
||||
)
|
||||
)
|
||||
|
||||
function get_locale()
|
||||
data = payload()
|
||||
if :locale in keys(data)
|
||||
return data[:locale]
|
||||
else
|
||||
return "en"
|
||||
end
|
||||
end
|
||||
|
||||
#---Helpers-----------------------------------------------------------
|
||||
|
||||
|
||||
function table_to_json(name,df)
|
||||
ar = []
|
||||
for df_row in eachrow(df)
|
||||
dict = Dict()
|
||||
for id in names(df_row)
|
||||
dict[id] = df_row[id]
|
||||
end
|
||||
push!(ar,dict)
|
||||
end
|
||||
open("public/assets/"*name*".json", "w") do io
|
||||
JSON3.write(io, ar)
|
||||
end
|
||||
end
|
||||
|
||||
function compile(name)
|
||||
df = select_from_table([name => ["*"]])
|
||||
table_to_json(name,df)
|
||||
end
|
||||
|
||||
function move_requests(name)
|
||||
df_requests = select_from_table(["$(name)_requests" => ["*"]], where_data=["verified" => true, "added" => false])
|
||||
df = select_from_table([name => ["*"]])
|
||||
latitudes = df.latitude
|
||||
longitudes = df.longitude
|
||||
for df_row in eachrow(df_requests)
|
||||
ind_id_given = ismissing(df_row.id_given) ? nothing : findfirst(df_row.id_given.==df.id)
|
||||
if (!isnothing(ind_id_given))
|
||||
id = df[ind_id_given,:id]
|
||||
row_found = df[ind_id_given,Not(:id)]
|
||||
dict = Dict(zip(names(row_found),values(row_found)))
|
||||
dict["members"] += 1
|
||||
update_table(name,dict, where_data=["id" => id])
|
||||
else
|
||||
id = df_row.id
|
||||
dict_update = Dict("added" => true)
|
||||
update_table("$(name)_requests",dict_update, where_data=["id" => id])
|
||||
|
||||
df_row_to_add = df_row[Not(:id_given)]
|
||||
df_row_to_add = df_row_to_add[Not(:verified)]
|
||||
df_row_to_add = df_row_to_add[Not(:added)]
|
||||
df_row_to_add = df_row_to_add[Not(:id)]
|
||||
dict = Dict(zip(names(df_row_to_add),values(df_row_to_add)))
|
||||
dict["members"] = 1
|
||||
insert_into_table(name,dict)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
#---Functions---------------------------------------------------------
|
||||
|
||||
current_user() = findone(Users.User, id = get_authentication())
|
||||
|
||||
function trade_unions()
|
||||
locale = get_locale()
|
||||
html(:trade_unions,:trade_unions, layout = dict_layouts[:trade_unions], context = @__MODULE__,
|
||||
title = trade_unions_info[locale][:title],
|
||||
description = trade_unions_info[locale][:description]
|
||||
)
|
||||
end
|
||||
|
||||
function trade_unions_add()
|
||||
locale = get_locale()
|
||||
html(:trade_unions,:trade_unions_add, layout = dict_layouts[:trade_unions_add], context = @__MODULE__,
|
||||
title = trade_unions_info[locale][:title],
|
||||
description = trade_unions_info[locale][:description]
|
||||
)
|
||||
end
|
||||
|
||||
function trade_unions_add_post()
|
||||
data = copy(jsonpayload())
|
||||
mode = data["mode"]
|
||||
delete!(data,"mode")
|
||||
user = current_user()
|
||||
user_id = user.id
|
||||
if mode==0 # Create
|
||||
if user.verified
|
||||
existing_user_group_data = select_from_table(["users_trade_unions" => ["*"]], where_data=["user_id" => user_id])
|
||||
has_group = !isempty(existing_user_group_data)
|
||||
delete!(data,"group_id")
|
||||
group_id = insert_into_table("trade_unions",data, "RETURNING id")[1,1]
|
||||
if has_group
|
||||
user_trade_unions_id = existing_user_group_data[1,"id"]
|
||||
prev_group_id = existing_user_group_data[1,"group_id"]
|
||||
update_table("users_trade_unions",Dict("group_id" => group_id), where_data=["id" => user_trade_unions_id])
|
||||
members = select_from_table(["trade_unions" => ["members"]], where_data=["id" => prev_group_id])[1,1]
|
||||
if (members==1)
|
||||
delete_from_table("trade_unions",["id" => prev_group_id])
|
||||
else
|
||||
update_table("trade_unions",Dict("members" => members - 1), where_data=["id" => id])
|
||||
end
|
||||
else
|
||||
dict_users_trade_unions = Dict("user_id" => user.id, "group_id" => group_id)
|
||||
insert_into_table("users_trade_unions",dict_users_trade_unions)
|
||||
end
|
||||
compile("trade_unions")
|
||||
else
|
||||
data["status"] = 0
|
||||
data["user_id"] = user_id
|
||||
insert_into_table("trade_unions_requests",data)
|
||||
end
|
||||
elseif mode==1 # Join
|
||||
data["user_id"] = user_id
|
||||
if exist_in_table("users_trade_unions",["group_id" => data["group_id"]])
|
||||
if exist_in_table("trade_unions_requests",["user_id" => user_id])
|
||||
delete_from_table("trade_unions_requests",["user_id" => user_id])
|
||||
end
|
||||
data["status"] = 0
|
||||
insert_into_table("trade_unions_requests",data)
|
||||
else
|
||||
group_id = data["group_id"]
|
||||
members = select_from_table("trade_unions" => ["members"], where_data = ["id" => group_id])[1,1]
|
||||
dict = Dict("members" => members + 1)
|
||||
update_table("trade_unions",dict, where_data=["id" => group_id])
|
||||
dict_users_trade_unions = Dict("user_id" => user_id, "group_id" => group_id)
|
||||
insert_into_table("users_trade_unions",dict_users_trade_unions)
|
||||
end
|
||||
|
||||
elseif mode==2 # Move
|
||||
existing_user_group_data = select_from_table(["users_trade_unions" => ["*"]], where_data=["user_id" => user_id])
|
||||
group_id = existing_user_group_data[1,"group_id"]
|
||||
delete!(data,"group_id")
|
||||
delete!(data,"members")
|
||||
delete!(data,"contact")
|
||||
update_table("trade_unions",data, where_data=["id" => group_id])
|
||||
compile("trade_unions")
|
||||
elseif mode==3 # Leave
|
||||
existing_user_group_data = select_from_table(["users_trade_unions" => ["*"]], where_data=["user_id" => user_id])
|
||||
if size(existing_user_group_data,1)==0
|
||||
if exist_in_table("trade_unions_requests",["user_id" => user_id])
|
||||
delete_from_table("trade_unions_requests",["user_id" => user_id])
|
||||
end
|
||||
else
|
||||
delete_from_table("users_trade_unions",["user_id" => user_id])
|
||||
end
|
||||
end
|
||||
return nothing
|
||||
end
|
||||
|
||||
function get_user_trade_unions()
|
||||
local data_dicts
|
||||
user_id = get_authentication()
|
||||
trade_unions_ids = select_from_table("users_trade_unions" => ["group_id"], where_data = ["user_id" => user_id])[:,1]
|
||||
group_id = isempty(trade_unions_ids) ? nothing : trade_unions_ids[1]
|
||||
data_dicts = []
|
||||
if isnothing(group_id)
|
||||
local data
|
||||
data = select_from_table("trade_unions_requests" => ["*"], where_data = ["user_id" => user_id,"status" => 0])
|
||||
if size(data,1)==0
|
||||
data = select_from_table("trade_unions_requests" => ["*"], where_data = ["user_id" => user_id,"status" => 2])
|
||||
if size(data,1)!=0
|
||||
data = data[[end],:]
|
||||
end
|
||||
end
|
||||
for row in eachrow(data)
|
||||
dict = Dict(zip(names(row),values(row)))
|
||||
if (!ismissing(row["group_id"]))
|
||||
extra_data = select_from_table("trade_unions" => ["*"], where_data = ["id" => row["group_id"]])
|
||||
merge!(dict, Dict(zip(names(extra_data[1,:]),values(extra_data[1,:]))))
|
||||
end
|
||||
push!(data_dicts, dict)
|
||||
end
|
||||
else
|
||||
group_data = select_from_table("trade_unions" => ["*"], where_data = ["id" => group_id])
|
||||
ns = names(group_data)
|
||||
data_dicts = map(x -> Dict(zip(ns,values(x))),eachrow(group_data))
|
||||
end
|
||||
return JSON3.write(data_dicts)
|
||||
end
|
||||
|
||||
function get_group_requests()
|
||||
user_id = get_authentication()
|
||||
trade_unions_ids = select_from_table("users_trade_unions" => ["group_id"], where_data = ["user_id" => user_id])[:,1]
|
||||
group_id = isempty(trade_unions_ids) ? nothing : trade_unions_ids[1]
|
||||
data_dicts = []
|
||||
if !isnothing(group_id)
|
||||
user_ids = select_from_table("trade_unions_requests" => ["user_id"], where_data = ["group_id" => group_id, "status" => 0])[:,1]
|
||||
for user2_id in user_ids
|
||||
email = select_from_table("users" => ["email"], where_data = ["id" => user2_id])[1,1]
|
||||
push!(data_dicts,Dict("email" => email, "user_id" => user2_id))
|
||||
end
|
||||
end
|
||||
return JSON3.write(data_dicts)
|
||||
end
|
||||
|
||||
function approve_request()
|
||||
data = copy(jsonpayload())
|
||||
user_id = get_authentication()
|
||||
trade_unions_ids = select_from_table("users_trade_unions" => ["group_id"], where_data = ["user_id" => user_id])[:,1]
|
||||
group_id = isempty(trade_unions_ids) ? nothing : trade_unions_ids[1]
|
||||
members = select_from_table("trade_unions" => ["members"], where_data = ["id" => group_id])[1,1]
|
||||
dict = Dict("members" => members + 1)
|
||||
update_table("trade_unions",dict, where_data=["id" => group_id])
|
||||
update_table("trade_unions_requests",Dict("status" => 1), where_data=["group_id" => group_id, "user_id" => data["user_id"]])
|
||||
dict_users_trade_unions = Dict("user_id" => data["user_id"], "group_id" => group_id)
|
||||
insert_into_table("users_trade_unions",dict_users_trade_unions)
|
||||
compile("trade_unions")
|
||||
return nothing
|
||||
end
|
||||
|
||||
function reject_request()
|
||||
data = copy(jsonpayload())
|
||||
user_id = get_authentication()
|
||||
trade_unions_ids = select_from_table("users_trade_unions" => ["group_id"], where_data = ["user_id" => user_id])[:,1]
|
||||
group_id = isempty(trade_unions_ids) ? nothing : trade_unions_ids[1]
|
||||
update_table("trade_unions_requests",Dict("status" => 2), where_data=["group_id" => group_id, "user_id" => data["user_id"]])
|
||||
return nothing
|
||||
end
|
||||
|
||||
function changeMemberCount()
|
||||
user_id = get_authentication()
|
||||
trade_unions_ids = select_from_table("users_trade_unions" => ["group_id"], where_data = ["user_id" => user_id])[:,1]
|
||||
group_id = isempty(trade_unions_ids) ? nothing : trade_unions_ids[1]
|
||||
data = copy(jsonpayload())
|
||||
update_table("trade_unions",data, where_data=["id" => group_id])
|
||||
compile("trade_unions")
|
||||
end
|
||||
|
||||
function change_group()
|
||||
user_id = get_authentication()
|
||||
trade_unions_ids = select_from_table("users_trade_unions" => ["group_id"], where_data = ["user_id" => user_id])[:,1]
|
||||
group_id = isempty(trade_unions_ids) ? nothing : trade_unions_ids[1]
|
||||
if !isnothing(group_id)
|
||||
data = copy(jsonpayload())
|
||||
data_new = Dict()
|
||||
ks = keys(data)
|
||||
for x in ["members","contact"]
|
||||
if x in ks
|
||||
data_new[x] = data[x]
|
||||
end
|
||||
end
|
||||
if !isempty(data_new)
|
||||
update_table("trade_unions",data_new, where_data=["id" => group_id])
|
||||
compile("trade_unions")
|
||||
end
|
||||
end
|
||||
return nothing
|
||||
end
|
||||
|
||||
|
||||
end
|
|
@ -0,0 +1 @@
|
|||
<trade-unions-component></trade-unions-component>
|
|
@ -0,0 +1 @@
|
|||
<trade-unions-add-component></trade-unions-add-component>
|
|
@ -13,9 +13,9 @@ export function debounce(func, timeout){
|
|||
}
|
||||
|
||||
export function svgFromObject(object) {
|
||||
var objectDoc = object.contentDocument;
|
||||
var svgItem = objectDoc.querySelector("path");
|
||||
return svgItem
|
||||
var objectDoc = object.contentDocument
|
||||
var svgItems = objectDoc.querySelectorAll("path")
|
||||
return svgItems
|
||||
}
|
||||
|
||||
export function rem2px(rem) {
|
||||
|
|
|
@ -6,7 +6,15 @@ export function addGroupPinContent(g,content,locale) {
|
|||
for (let field of ["location","members","contact"]) {
|
||||
let fieldText = content[field] + ": "
|
||||
if (field=="contact") {
|
||||
text += fieldText + "<a href='" + g.contact + "' target='_blank' rel=noreferrer>" + g.contact + "</a>"
|
||||
if (g.contact.includes("@") && g.contact.trim().split(" ").length==1) {
|
||||
text += fieldText + "<a href='mailto:" + g.contact + "' target='_blank' rel=noreferrer>" + g.contact + "</a>"
|
||||
}
|
||||
else if (g.contact.includes("http")) {
|
||||
text += fieldText + "<a href='" + g.contact + "' target='_blank' rel=noreferrer>" + g.contact + "</a>"
|
||||
}
|
||||
else {
|
||||
text += fieldText + g.contact + "<br>"
|
||||
}
|
||||
}
|
||||
else if (field=="location") {
|
||||
let location = [g.country,g.state,g.town].filter(x => x!=null && x!=undefined)
|
||||
|
@ -176,3 +184,30 @@ export function addPartnersPinContent(g,content,locale) {
|
|||
}
|
||||
return {text,coordinates}
|
||||
}
|
||||
|
||||
export function addTradeUnionPinContent(g,content,locale) {
|
||||
let coordinates
|
||||
let text = "<b>"+content["TradeUnion"]+"</b><br>"
|
||||
for (let field of ["name","location","members","contact"]) {
|
||||
let fieldText = content[field] + ": "
|
||||
if (field=="contact") {
|
||||
text += fieldText + "<a href='" + g.contact + "' target='_blank' rel=noreferrer>" + g.contact + "</a>"
|
||||
}
|
||||
else if (field=="location") {
|
||||
let location = [g.country,g.state,g.town].filter(x => x!=null && x!=undefined)
|
||||
let locationString
|
||||
if (locale=="en") {
|
||||
locationString = location.map(x => x).join(", ")
|
||||
}
|
||||
else {
|
||||
locationString = location.map(x => translate(content, x)).join(", ")
|
||||
}
|
||||
text += fieldText + locationString + "<br>"
|
||||
coordinates = [g.latitude,g.longitude]
|
||||
}
|
||||
else {
|
||||
text += fieldText + g[field] + "<br>"
|
||||
}
|
||||
}
|
||||
return {text,coordinates}
|
||||
}
|
|
@ -1,13 +1,15 @@
|
|||
{
|
||||
"top": "Our organization is a decentralized federation build upon the principle of free association. It consists of many groups of people united around a cause of bringing down exploitative politico-economic systems. We aim to replace them with libertarian socialist systems based on decentralization, direct democracy and worker-ownership of the means of production with the goal of creating an equitable, democratic and sustainable world by stopping exploitation of humans and nature.",
|
||||
"groupsTitle": "GROUPS",
|
||||
"groupsText": "We organize groups for the purposes of education, advocacy, anti-fascist action and mutual aid. Our objective is to demonstrate how the current politico-economic systems detrimentally impact our well-being, present alternative approaches, and engage in mutual aid to alleviate the challenges of living under capitalism.",
|
||||
"groupsText": "We organize groups for the purposes of education, advocacy, anti-fascist action and mutual aid. Our objective is to demonstrate how the current politico-economic systems detrimentally impact our well-being, present alternative approaches, and engage in mutual aid.",
|
||||
"communesTitle": "COMMUNES",
|
||||
"communesText": "We establish communes based on libertarian socialist principles, where commune members have ownership over land, houses, and the means of production as well as make decisions using direct democracy. We are gradually expanding our socialist world, one commune at a time.",
|
||||
"cooperativesTitle": "COOPERATIVES",
|
||||
"cooperativesText": "We form worker cooperatives to finance the operations of our groups and communes. Recognizing that economic power influences political power, we consider the establishment of cooperatives to be one of the initial steps towards achieving socialism.",
|
||||
"cooperativesText": "We form worker cooperatives to finance the operations of our groups and communes. Recognizing that economic power influences political power, we consider the establishment of cooperatives to be a vital activity.",
|
||||
"partiesTitle": "PARTIES",
|
||||
"partiesText": "We create political parties in order to push for reforms allowing us to easier further our goals, to move the Overton window as well as to gain popularity. However, we recognize that we cannot achieve libertarian socialism through institutions which act contrary to our goals.",
|
||||
"tradeUnionsTitle": "TRADE UNIONS",
|
||||
"tradeUnionsText": "We promote trade unions, which empower laborers to collectively advocate for fair treatment, just wages, and improved working conditions. Struggle at a place of work is an integral part of our strategy to achieve libertarian socialism.",
|
||||
"findUs": "Find Us",
|
||||
"whatNow": "What Now?",
|
||||
"joinUs": "Join Us",
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
"communes": "Communes",
|
||||
"cooperatives": "Cooperatives",
|
||||
"parties": "Parties",
|
||||
"tradeUnions": "Trade Unions",
|
||||
"partners": "Partners",
|
||||
"login": "Login",
|
||||
"profile": "Profile"
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"tradeUnions": "Trade Unions",
|
||||
"p1": "Trade unions play a pivotal role in safeguarding the rights and welfare of workers. Trade unions constitute an integral part of our organization, allowing workers to unite and collectively negotiate for fair wages, better working conditions, and improved labour rights. By fostering solidarity and mobilizing for collective action, trade unions contribute to our overarching mission of dismantling exploitative systems and ushering in a world centered on decentralized decision-making, direct democracy, and worker self-management.",
|
||||
"subheading1": "Our Trade Unions",
|
||||
"location": "Location",
|
||||
"members": "Members",
|
||||
"contact": "Contact",
|
||||
"TradeUnion": "Trade union",
|
||||
"tradeUnion": "trade union",
|
||||
"map-prompt": "Want to appear on our map? Contact us!"
|
||||
}
|
|
@ -8,6 +8,8 @@
|
|||
"cooperativesText": "Мы формируем рабочие кооперативы для финансирования операций наших групп и коммун, а также формирования основы новой социалистической экономики. Признавая, что экономическая власть влияет на политическую власть, мы считаем создание кооперативов одним из первых шагов на пути к социализму.",
|
||||
"partiesTitle": "ПАРТИИ",
|
||||
"partiesText": "Мы создаем политические партии, чтобы продвигать реформы, которые позволят легче достичь наших целей, сдвигать окно Овертона и увеличивать нашу популярность. Однако мы признаем, что мы не можем достичь либертарианского социализма с помощью институтов, действующих против наших целей.",
|
||||
"tradeUnionsTitle": "ПРОФСОЮЗЫ",
|
||||
"tradeUnionsText": "Мы поддерживаем профсоюзы, которые дают возможность работникам коллективно выступать за справедливое обращение, справедливую заработную плату и улучшение условий труда. Борьба на месте работы — неотъемлемая часть нашей стратегии по достижению либертарного социализма.",
|
||||
"findUs": "Найди нас",
|
||||
"whatNow": "Что теперь?",
|
||||
"joinUs": "Присоединяйся",
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
"cooperatives": "Кооперативы",
|
||||
"parties": "Партии",
|
||||
"partners": "Партнеры",
|
||||
"tradeUnions": "Профсоюзы",
|
||||
"login": "Войти",
|
||||
"profile": "Профиль"
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"tradeUnions": "Профсоюзы",
|
||||
"p1": "Профсоюзы играют ключевую роль в защите прав и благосостояния трудящихся. Профсоюзы составляют неотъемлемую часть нашей организации, позволяя работникам объединяться и вести коллективные переговоры о справедливой заработной плате, лучших условиях труда и улучшенных трудовых правах. Укрепляя солидарность и мобилизуя для коллективных действий, профсоюзы вносят свой вклад в нашу всеобъемлющую миссию по устранению эксплуататорских систем и установлению мира, основанного на децентрализованном принятии решений, прямой демократии и самоуправлении рабочих.",
|
||||
"subheading1": "Наши профсоюзы",
|
||||
"location": "Локация",
|
||||
"members": "Участники",
|
||||
"contact": "Контакт",
|
||||
"TradeUnion": "Профсоюз",
|
||||
"tradeUnion": "профсоюз",
|
||||
"map-prompt": "Хочешь оказаться на нашей карте? Напиши нам!"
|
||||
}
|
|
@ -21,6 +21,7 @@
|
|||
loadLocaleContent(content,"communes-component",loaded)
|
||||
loadLocaleContent(content,"cooperatives-component",loaded)
|
||||
loadLocaleContent(content,"parties-component",loaded)
|
||||
loadLocaleContent(content,"trade-unions-component",loaded)
|
||||
loadLocaleContent(content,"countries",loaded)
|
||||
let locale = loadLocaleContent(content,"join-us-component",loaded)
|
||||
|
||||
|
@ -48,6 +49,7 @@
|
|||
getData("/assets/communes.json",(response) => callback(response,"communes"))
|
||||
getData("/assets/cooperatives.json",(response) => callback(response,"cooperatives"))
|
||||
getData("/assets/parties.json",(response) => callback(response,"parties"))
|
||||
getData("/assets/trade-unions.json",(response) => callback(response,"tradeUnions"))
|
||||
|
||||
function mapCallback(createMap,content,locale) {
|
||||
let map = createMap([22, 0],2)
|
||||
|
@ -55,15 +57,19 @@
|
|||
enableCountryGrouping: true,
|
||||
}
|
||||
let groupsMarkersLayer = addMarkersEntries(entries["groups"],entriesByCountry["groups"],map,content,locale,addGroupPinContent,"green",options)
|
||||
let communesMarkersLayer = addMarkersEntries(entries["communes"],entriesByCountry["communes"],map,content,locale,addCommunePinContent,"red",options)
|
||||
let coopsMarkersLayer = addMarkersEntries(entries["cooperatives"],entriesByCountry["cooperatives"],map,content,locale,addCoopPinContent,"blue",options)
|
||||
let partiesMarkersLayer = addMarkersEntries(entries["parties"],entriesByCountry["parties"],map,content,locale,addPartyPinContent,"gold",options)
|
||||
let tradeUnionsMarkersLayer = addMarkersEntries(entries["tradeUnions"],entriesByCountry["tradeUnions"],map,content,locale,addPartyPinContent,"violet",options)
|
||||
let coopsMarkersLayer = addMarkersEntries(entries["cooperatives"],entriesByCountry["cooperatives"],map,content,locale,addCoopPinContent,"blue",options)
|
||||
let communesMarkersLayer = addMarkersEntries(entries["communes"],entriesByCountry["communes"],map,content,locale,addCommunePinContent,"red",options)
|
||||
|
||||
|
||||
let overlayMaps = {}
|
||||
overlayMaps[content.groups] = groupsMarkersLayer
|
||||
overlayMaps[content.communes] = communesMarkersLayer
|
||||
overlayMaps[content.cooperatives] = coopsMarkersLayer
|
||||
overlayMaps[content.parties] = partiesMarkersLayer
|
||||
overlayMaps[content.tradeUnions] = tradeUnionsMarkersLayer
|
||||
overlayMaps[content.cooperatives] = coopsMarkersLayer
|
||||
overlayMaps[content.communes] = communesMarkersLayer
|
||||
|
||||
L.control.layers(null, overlayMaps).addTo(map)
|
||||
}
|
||||
|
||||
|
@ -73,7 +79,7 @@
|
|||
</script>
|
||||
|
||||
{#key $loaded}
|
||||
{#if $loaded==10}
|
||||
{#if $loaded==12}
|
||||
<div id="container">
|
||||
<div id="text-container">
|
||||
<h1>{$content.heading}</h1>
|
||||
|
@ -97,13 +103,14 @@
|
|||
<p>{$content.findOur}</p>
|
||||
<ol id="entities-list">
|
||||
<li><a href={"/" + locale + "/groups"}>{$content.group}</a>,</li>
|
||||
<li><a href={"/" + locale + "/communes"}>{$content.commune}</a></li>
|
||||
<li><a href={"/" + locale + "/cooperatives"}>{$content.cooperative}</a> {$content.or}</li>
|
||||
<li><a href={"/" + locale + "/parties"}>{$content.party}</a></li>
|
||||
<li><a href={"/" + locale + "/trade-unions"}>{$content.tradeUnion}</a></li>
|
||||
<li><a href={"/" + locale + "/cooperatives"}>{$content.cooperative}</a> {$content.or}</li>
|
||||
<li><a href={"/" + locale + "/communes"}>{$content.commune}</a></li>
|
||||
</ol>
|
||||
<p>{$content.nearYou}</p>
|
||||
</div>
|
||||
<p>{$content.noneNear} <a href="https://chat.whatsapp.com/BhnmUNljUxJ2AjeHUwyTKh" target="_blank" rel=noreferrer>{$content.WhatsAppGroup}</a> {$content.or} <a href="https://discord.gg/Qk8KUk787z" target="_blank" rel=noreferrer>{$content.DiscordServer}</a>{$content.helpStart}</p>
|
||||
<p>{$content.noneNear} <a href="https://discord.gg/Qk8KUk787z" target="_blank" rel=noreferrer>{$content.DiscordServer}</a> {$content.or} <a href="https://chat.whatsapp.com/BhnmUNljUxJ2AjeHUwyTKh" target="_blank" rel=noreferrer>{$content.WhatsAppGroup}</a>{$content.helpStart}</p>
|
||||
<map-component id="map" callback={(createMap) => mapCallback(createMap,$content,locale)} colors={["#23AC20","#CA2437","#217BC9","#FFD326"]}></map-component>
|
||||
<p id="add-prompt">{$content["map-prompt"]}</p>
|
||||
</div>
|
||||
|
@ -138,13 +145,16 @@
|
|||
background-image: url(https://www.libsoc.org/img/common/markers/marker-green.png);
|
||||
}
|
||||
#entities-list li:nth-of-type(2):before {
|
||||
background-image: url(https://www.libsoc.org/img/common/markers/marker-red.png);
|
||||
background-image: url(https://www.libsoc.org/img/common/markers/marker-gold.png);
|
||||
}
|
||||
#entities-list li:nth-of-type(3):before {
|
||||
background-image: url(https://www.libsoc.org/img/common/markers/marker-blue.png);
|
||||
background-image: url(https://www.libsoc.org/img/common/markers/marker-violet.png);
|
||||
}
|
||||
#entities-list li:nth-of-type(4):before {
|
||||
background-image: url(https://www.libsoc.org/img/common/markers/marker-gold.png);
|
||||
background-image: url(https://www.libsoc.org/img/common/markers/marker-blue.png);
|
||||
}
|
||||
#entities-list li:nth-of-type(5):before {
|
||||
background-image: url(https://www.libsoc.org/img/common/markers/marker-red.png);
|
||||
}
|
||||
|
||||
#entities-list li::marker {
|
||||
|
|
|
@ -51,11 +51,14 @@
|
|||
getData("/assets/communes.json",(response) => callback(response,"communes"))
|
||||
getData("/assets/cooperatives.json",(response) => callback(response,"cooperatives"))
|
||||
getData("/assets/parties.json",(response) => callback(response,"parties"))
|
||||
getData("/assets/trade-unions.json",(response) => callback(response,"tradeUnions"))
|
||||
|
||||
loadLocaleContent(content,"groups-component",loaded)
|
||||
loadLocaleContent(content,"communes-component",loaded)
|
||||
loadLocaleContent(content,"cooperatives-component",loaded)
|
||||
loadLocaleContent(content,"parties-component",loaded)
|
||||
loadLocaleContent(content,"trade-unions-component",loaded)
|
||||
|
||||
loadLocaleContent(content,"countries",loaded)
|
||||
let locale = loadLocaleContent(content,"landing-component",loaded,changeWidth)
|
||||
changeWidth(locale)
|
||||
|
@ -66,15 +69,18 @@
|
|||
enableCountryGrouping: true,
|
||||
}
|
||||
let groupsMarkersLayer = addMarkersEntries(entries["groups"],entriesByCountry["groups"],map,content,locale,addGroupPinContent,"green",options)
|
||||
let communesMarkersLayer = addMarkersEntries(entries["communes"],entriesByCountry["communes"],map,content,locale,addCommunePinContent,"red",options)
|
||||
let coopsMarkersLayer = addMarkersEntries(entries["cooperatives"],entriesByCountry["cooperatives"],map,content,locale,addCoopPinContent,"blue",options)
|
||||
let partiesMarkersLayer = addMarkersEntries(entries["parties"],entriesByCountry["parties"],map,content,locale,addPartyPinContent,"gold",options)
|
||||
let tradeUnionsMarkersLayer = addMarkersEntries(entries["tradeUnions"],entriesByCountry["tradeUnions"],map,content,locale,addPartyPinContent,"violet",options)
|
||||
let coopsMarkersLayer = addMarkersEntries(entries["cooperatives"],entriesByCountry["cooperatives"],map,content,locale,addCoopPinContent,"blue",options)
|
||||
let communesMarkersLayer = addMarkersEntries(entries["communes"],entriesByCountry["communes"],map,content,locale,addCommunePinContent,"red",options)
|
||||
|
||||
|
||||
let overlayMaps = {}
|
||||
overlayMaps[content.groups] = groupsMarkersLayer
|
||||
overlayMaps[content.communes] = communesMarkersLayer
|
||||
overlayMaps[content.cooperatives] = coopsMarkersLayer
|
||||
overlayMaps[content.parties] = partiesMarkersLayer
|
||||
overlayMaps[content.tradeUnions] = tradeUnionsMarkersLayer
|
||||
overlayMaps[content.cooperatives] = coopsMarkersLayer
|
||||
overlayMaps[content.communes] = communesMarkersLayer
|
||||
|
||||
L.control.layers(null, overlayMaps).addTo(map)
|
||||
}
|
||||
|
@ -85,7 +91,7 @@
|
|||
</script>
|
||||
|
||||
{#key $loaded}
|
||||
{#if $loaded==10}
|
||||
{#if $loaded==12}
|
||||
<div id="container">
|
||||
<picture>
|
||||
<source srcset="/img/crowd.webp">
|
||||
|
@ -105,6 +111,11 @@
|
|||
<img id="parties-img" src="/img/common/parties.svg" alt="coops">
|
||||
<p>{$content.partiesText}</p>
|
||||
</div>
|
||||
<div>
|
||||
<a href={"/" + locale + "/trade-unions"}><h2>{$content.tradeUnionsTitle}</h2></a>
|
||||
<img id="trade-unions-img" src="/img/common/trade-unions.svg" alt="trade unions">
|
||||
<p>{$content.tradeUnionsText}</p>
|
||||
</div>
|
||||
<div>
|
||||
<a href={"/" + locale + "/coops"}><h2>{$content.cooperativesTitle}</h2></a>
|
||||
<img id="coops-img" src="/img/common/coops.svg" alt="coops">
|
||||
|
@ -134,7 +145,7 @@
|
|||
</div>
|
||||
-->
|
||||
<h1 id="find-us">{$content.findUs}</h1>
|
||||
<map-component id="map" callback={(createMap) => mapCallback(createMap,$content,locale)} colors={["#23AC20","#CA2437","#217BC9","#FFD326"]}></map-component>
|
||||
<map-component id="map" callback={(createMap) => mapCallback(createMap,$content,locale)} colors={["#23AC20","#FFD326","#9D35CD","#217BC9","#CA2437"]}></map-component>
|
||||
<h1>{$content.whatNow}</h1>
|
||||
<div id="action-container">
|
||||
<a class="link-button" href={"/" + locale + "/join-us"}>{$content.joinUs}</a>
|
||||
|
@ -188,7 +199,7 @@
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
#groups-img, #communes-img, #coops-img, #parties-img {
|
||||
#groups-img, #communes-img, #coops-img, #parties-img, #trade-unions-img {
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
transform: translate(-50%);
|
||||
|
@ -202,6 +213,11 @@
|
|||
height: 7.5rem;
|
||||
}
|
||||
|
||||
#trade-unions-img {
|
||||
margin-top: 0.5rem;
|
||||
height: 7.5rem;
|
||||
}
|
||||
|
||||
#text-container {
|
||||
max-width: calc(100vw - 4rem);
|
||||
margin: auto;
|
||||
|
@ -230,13 +246,18 @@
|
|||
#container-grid {
|
||||
display: grid;
|
||||
grid-template-columns: var(--grid-width);
|
||||
grid-template-rows: var(--grid-width);
|
||||
grid-template-rows: 100% 100%;
|
||||
grid-gap: 4rem;
|
||||
row-gap: 2.5rem;
|
||||
margin-top: 2rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
#container-grid>:last-child {
|
||||
grid-column: 1/span 2;
|
||||
|
||||
}
|
||||
|
||||
#container-grid > div {
|
||||
position: relative;
|
||||
}
|
||||
|
|
|
@ -115,9 +115,10 @@
|
|||
<button on:click={() => showDropdown(initiativesDropdown)} on:focusout={() => hide(initiativesDropdown)} class="options-button">{$content.initiatives}</button>
|
||||
<div bind:this={initiativesDropdown} class="options-dropdown">
|
||||
<a href={"/"+locale+"/groups"}>{$content.groups}</a>
|
||||
<a href={"/"+locale+"/communes"}>{$content.communes}</a>
|
||||
<a href={"/"+locale+"/cooperatives"}>{$content.cooperatives}</a>
|
||||
<a href={"/"+locale+"/parties"}>{$content.parties}</a>
|
||||
<a href={"/"+locale+"/trade-unions"}>{$content.tradeUnions}</a>
|
||||
<a href={"/"+locale+"/cooperatives"}>{$content.cooperatives}</a>
|
||||
<a href={"/"+locale+"/communes"}>{$content.communes}</a>
|
||||
<a href={"/"+locale+"/partners"}>{$content.partners}</a>
|
||||
</div>
|
||||
</li>
|
||||
|
|
|
@ -115,9 +115,10 @@
|
|||
<button on:click={() => showDropdown(initiativesDropdown)} on:focusout={() => hide(initiativesDropdown)} class="options-button">{$content.initiatives}</button>
|
||||
<div bind:this={initiativesDropdown} class="options-dropdown">
|
||||
<a href={"/"+locale+"/groups"}>{$content.groups}</a>
|
||||
<a href={"/"+locale+"/communes"}>{$content.communes}</a>
|
||||
<a href={"/"+locale+"/cooperatives"}>{$content.cooperatives}</a>
|
||||
<a href={"/"+locale+"/parties"}>{$content.parties}</a>
|
||||
<a href={"/"+locale+"/trade-unions"}>{$content.tradeUnions}</a>
|
||||
<a href={"/"+locale+"/cooperatives"}>{$content.cooperatives}</a>
|
||||
<a href={"/"+locale+"/communes"}>{$content.communes}</a>
|
||||
<a href={"/"+locale+"/partners"}>{$content.partners}</a>
|
||||
</div>
|
||||
</li>
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
import "/js/components/profile-communes.js"
|
||||
import "/js/components/profile-coops.js"
|
||||
import "/js/components/profile-parties.js"
|
||||
import "/js/components/profile-trade-unions.js"
|
||||
import "/js/components/groups-add-component.js"
|
||||
|
||||
// Main code
|
||||
|
@ -26,6 +27,7 @@
|
|||
let communes
|
||||
let coops
|
||||
let parties
|
||||
let tradeUnions
|
||||
let panes
|
||||
let groupsAdd
|
||||
|
||||
|
@ -34,6 +36,7 @@
|
|||
let communesButton
|
||||
let coopsButton
|
||||
let partiesButton
|
||||
let tradeUnionsButton
|
||||
let buttons
|
||||
|
||||
let currentPaneIndex = 0
|
||||
|
@ -66,18 +69,21 @@
|
|||
setTimeout(f,100)
|
||||
}
|
||||
else {
|
||||
let svgItem = svgFromObject(svgObject)
|
||||
if (svgItem==null) {
|
||||
let svgItems = svgFromObject(svgObject)
|
||||
if (svgItems.length==0) {
|
||||
let f = () => styleField(div,weight,color)
|
||||
setTimeout(f,100)
|
||||
}
|
||||
else {
|
||||
div.style.fontWeight = weight
|
||||
svgItem.setAttribute("fill", color)
|
||||
for (let item of svgItems) {
|
||||
let fill = item.getAttribute("fill")
|
||||
if (fill!="#fff" && fill!=null) {
|
||||
item.setAttribute("fill", color)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
function fillFields() {
|
||||
|
@ -98,10 +104,10 @@
|
|||
|
||||
function init() {
|
||||
panes = [general,groups,communes,coops,parties]
|
||||
buttons = [generalButton,groupsButton,communesButton,coopsButton,partiesButton]
|
||||
buttons = [generalButton,groupsButton,communesButton,coopsButton,partiesButton,tradeUnionsButton]
|
||||
if ($loaded==1 && panes.every(x => valid(x)) && buttons.every(x => valid(x))) {
|
||||
panes = [general,groups,communes,coops,parties]
|
||||
buttons = [generalButton,groupsButton,communesButton,coopsButton,partiesButton]
|
||||
panes = [general,groups,communes,coops,parties,tradeUnions]
|
||||
buttons = [generalButton,groupsButton,communesButton,coopsButton,partiesButton,tradeUnionsButton]
|
||||
|
||||
fillFields()
|
||||
general.style.display = "initial"
|
||||
|
@ -155,6 +161,10 @@
|
|||
<object id="parties-img" class="icons" type="image/svg+xml" data="/img/common/parties.svg" title="parties"></object>
|
||||
<span>parties</span>
|
||||
</button>
|
||||
<button bind:this={tradeUnionsButton} on:click={() => changePane(tradeUnions,tradeUnionsButton)}>
|
||||
<object id="trade-unions-img" class="icons" type="image/svg+xml" data="/img/common/trade-unions.svg" title="trade unions"></object>
|
||||
<span>trade unions</span>
|
||||
</button>
|
||||
<button on:click={AuthTools.logout} id="logout-button">
|
||||
<object id="logout-img" class="icons" type="image/svg+xml" data="/img/profile/icons/logout.svg" title=""></object>
|
||||
<span>logout</span>
|
||||
|
@ -165,9 +175,10 @@
|
|||
{#if $loaded==1}
|
||||
<profile-general bind:this={general} style="display: none;"></profile-general>
|
||||
<profile-groups bind:this={groups} style="display: none;"></profile-groups>
|
||||
<profile-communes bind:this={communes} style="display: none;"></profile-communes>
|
||||
<profile-coops bind:this={coops} style="display: none;"></profile-coops>
|
||||
<profile-parties bind:this={parties} style="display: none;"></profile-parties>
|
||||
<profile-trade-unions bind:this={tradeUnions} style="display: none;"></profile-trade-unions>
|
||||
<profile-coops bind:this={coops} style="display: none;"></profile-coops>
|
||||
<profile-communes bind:this={communes} style="display: none;"></profile-communes>
|
||||
{/if}
|
||||
{/key}
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
<svelte:options tag="profile-trade-unions" />
|
||||
|
||||
<script>
|
||||
|
||||
// Import statements
|
||||
import { onMount } from 'svelte'
|
||||
import * as AuthTools from "/js/libraries/authTools.js"
|
||||
|
||||
// Main code
|
||||
|
||||
onMount(() => {
|
||||
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<h3>Under development</h3>
|
||||
|
||||
<p style=" position: relative; margin-top: 2rem;">Visit <a href="https://discord.gg/Qk8KUk787z" style="color: #c52a28;">https://discord.gg/Qk8KUk787z</a> and ask for your trade union to be added.</p>
|
||||
|
||||
<style>
|
||||
|
||||
@import '/css/common.css';
|
||||
|
||||
h3 {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
</style>
|
|
@ -0,0 +1,577 @@
|
|||
<svelte:options tag="trade-unions-add-component" />
|
||||
|
||||
<script>
|
||||
// Import statements
|
||||
import { onMount, getContext } from 'svelte'
|
||||
import { writable } from 'svelte/store';
|
||||
import { loadLocaleContent, getData, sendData } from "/js/libraries/serverTools.js"
|
||||
import { addMarkersEntries, translate } from "/js/libraries/mapTools.js"
|
||||
import { validatePosNumber } from "/js/libraries/miscTools.js"
|
||||
|
||||
// Import components
|
||||
import "/js/components/map-component.js"
|
||||
|
||||
// Export statements
|
||||
export let map = null
|
||||
|
||||
// Main code
|
||||
let loaded = writable(0)
|
||||
let content = writable({})
|
||||
let entries
|
||||
let entriesByCountry
|
||||
let userData
|
||||
|
||||
let buttonsGroupMember
|
||||
let buttonsNotGroupMember
|
||||
|
||||
let callback = (response) => {
|
||||
entries = JSON.parse(response)
|
||||
entriesByCountry = {}
|
||||
for (let g of entries) {
|
||||
let country = g.country
|
||||
if (g.contact==null) {
|
||||
g.contact = "https://discord.gg/Qk8KUk787z"
|
||||
}
|
||||
if (country in entriesByCountry) {
|
||||
entriesByCountry[country].push(g)
|
||||
}
|
||||
else {
|
||||
entriesByCountry[country] = [g]
|
||||
}
|
||||
}
|
||||
loaded.update((val) => {
|
||||
return val + 1
|
||||
})
|
||||
}
|
||||
getData("/assets/trade-unions.json",callback)
|
||||
|
||||
|
||||
let confirmationMsg
|
||||
let addressInput
|
||||
let contactInput
|
||||
let membersInput
|
||||
let addressVec = ["","",""]
|
||||
let userPinData = {
|
||||
|
||||
}
|
||||
let userPinLng = 0
|
||||
let userPin = createPin(0,0)
|
||||
userPin.setOpacity(0)
|
||||
let modeButtons = []
|
||||
|
||||
let context = getContext("profile-component")
|
||||
let closeGroupsAdd = context.closeGroupsAdd
|
||||
let maps = context.maps
|
||||
let onLoadedGroups = context.onLoadedGroups
|
||||
let userGroups = context.userGroups
|
||||
let user = context.user
|
||||
|
||||
let has_group = userGroups.length!=0
|
||||
let mode = has_group ? 2 : 0
|
||||
let pendingGroup
|
||||
if (has_group) {
|
||||
pendingGroup= userGroups[0].status!=undefined
|
||||
if (pendingGroup) {
|
||||
mode = 3
|
||||
}
|
||||
}
|
||||
|
||||
let locale = loadLocaleContent(content,"trade-unions-component",loaded)
|
||||
loadLocaleContent(content,"countries",loaded)
|
||||
|
||||
function createPin(lat,lng) {
|
||||
let markerIcon = new L.Icon({
|
||||
iconUrl: '/img/common/markers/marker-black.png',
|
||||
shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png',
|
||||
iconSize: [25, 41],
|
||||
iconAnchor: [12, 41],
|
||||
popupAnchor: [1, -34],
|
||||
shadowSize: [41, 41]
|
||||
})
|
||||
return L.marker([lat,lng], {icon: markerIcon})
|
||||
}
|
||||
|
||||
function updatePin(marker,lat,lng) {
|
||||
let newLatLng = L.latLng(lat, lng); // Replace with the desired coordinates
|
||||
marker.setLatLng(newLatLng)
|
||||
}
|
||||
|
||||
function reverseGeocodeLocal(latitude, longitude) {
|
||||
let url = `https://nominatim.openstreetmap.org/reverse?lat=${latitude}&lon=${longitude}&format=jsonv2`;
|
||||
|
||||
let callback = (response) => {
|
||||
// Parse the response JSON
|
||||
response = JSON.parse(response)
|
||||
// Extract the address information from the response
|
||||
let address = response.address
|
||||
let city = address.city || address.town || address.village || address.hamlet
|
||||
let state = address.state
|
||||
let country = address.country
|
||||
let fullAddress = country
|
||||
if (state!=undefined) {
|
||||
fullAddress += ", " + state
|
||||
}
|
||||
else {
|
||||
state = ""
|
||||
}
|
||||
if (city!=undefined) {
|
||||
fullAddress += ", " + city
|
||||
}
|
||||
else {
|
||||
city = ""
|
||||
}
|
||||
addressInput.value = fullAddress
|
||||
resizeInput(addressInput)
|
||||
}
|
||||
getData(url,callback)
|
||||
}
|
||||
|
||||
function reverseGeocode(latitude, longitude) {
|
||||
let url = `https://nominatim.openstreetmap.org/reverse?lat=${latitude}&lon=${longitude}&format=jsonv2&accept-language=en`;
|
||||
|
||||
let callback = (response) => {
|
||||
// Parse the response JSON
|
||||
response = JSON.parse(response)
|
||||
// Extract the address information from the response
|
||||
let address = response.address
|
||||
if (address!=undefined) {
|
||||
let city = address.city || address.town || address.village || address.hamlet
|
||||
let state = address.state
|
||||
let country = address.country
|
||||
let fullAddress = country
|
||||
if (state!=undefined) {
|
||||
fullAddress += ", " + state
|
||||
}
|
||||
else {
|
||||
state = ""
|
||||
}
|
||||
if (city!=undefined) {
|
||||
fullAddress += ", " + city
|
||||
}
|
||||
else {
|
||||
city = ""
|
||||
}
|
||||
addressVec = [country,state,city]
|
||||
}
|
||||
}
|
||||
getData(url,callback)
|
||||
}
|
||||
|
||||
function addGroupPinContent(g,content,locale) {
|
||||
let coordinates
|
||||
let text = "<b>"+content["TradeUnion"]+"</b><br>"
|
||||
for (let field of ["location","members","contact"]) {
|
||||
let fieldText = content[field] + ": "
|
||||
if (field=="contact") {
|
||||
text += fieldText + "<a href='" + g.contact + "' target='_blank' rel=noreferrer>" + g.contact + "</a>"
|
||||
}
|
||||
else if (field=="location") {
|
||||
let location = [g.country,g.state,g.town].filter(x => x!=null && x!=undefined)
|
||||
let locationString
|
||||
if (locale=="en") {
|
||||
locationString = location.map(x => x).join(", ")
|
||||
}
|
||||
else {
|
||||
locationString = location.map(x => translate(content, x)).join(", ")
|
||||
}
|
||||
text += fieldText + locationString + "<br>"
|
||||
coordinates = [g.latitude,g.longitude]
|
||||
}
|
||||
else {
|
||||
text += fieldText + g[field] + "<br>"
|
||||
}
|
||||
}
|
||||
return {text,coordinates}
|
||||
}
|
||||
|
||||
function mapCallback(createMap,content,locale) {
|
||||
map = createMap([22, 0],2)
|
||||
maps["groupsAdd"] = map
|
||||
let options = {
|
||||
enableCountryGrouping: false,
|
||||
pinCallback: pinCallback
|
||||
}
|
||||
addMarkersEntries(entries,entriesByCountry,map,content,locale,addGroupPinContent,"green",options)
|
||||
|
||||
userPin.addTo(map)
|
||||
map.on('click', function(event) {
|
||||
if (mode==0) {
|
||||
let lat = event.latlng.lat;
|
||||
let lng = event.latlng.lng;
|
||||
userPinData["latitude"] = lat
|
||||
userPinData["longitude"] = lng
|
||||
userPinData["id"] = null
|
||||
updatePin(userPin,lat,lng)
|
||||
userPin.setOpacity(1)
|
||||
reverseGeocodeLocal(lat, lng)
|
||||
reverseGeocode(lat, lng)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function updateConfirmationMsg(response) {
|
||||
if (response!==false) {
|
||||
if (mode==0 && !user.verified) {
|
||||
confirmationMsg.innerHTML = "You have been added to our database! Now go to our Discord to verify yourself."
|
||||
}
|
||||
else {
|
||||
confirmationMsg.innerHTML = "Success!"
|
||||
}
|
||||
confirmationMsg.style.color = "green"
|
||||
if (mode==0 || mode==1) {
|
||||
userGroups[0] = {}
|
||||
}
|
||||
userGroups[0].country = addressVec[0]=="" ? null : addressVec[0]
|
||||
userGroups[0].state = addressVec[1]=="" ? null : addressVec[1]
|
||||
userGroups[0].town = addressVec[2]=="" ? null : addressVec[2]
|
||||
userGroups[0].members = userPinData["members"]
|
||||
onLoadedGroups()
|
||||
}
|
||||
else {
|
||||
confirmationMsg.innerHTML = "Something went wrong."
|
||||
confirmationMsg.style.color = "red"
|
||||
}
|
||||
}
|
||||
|
||||
function submitLocation() {
|
||||
if (addressVec[0]!="" || mode==3) {
|
||||
let membersVal, contactVal
|
||||
if (mode==0) { // Create
|
||||
membersVal = membersInput.value
|
||||
contactVal = contactInput.value
|
||||
}
|
||||
else if (mode==1) { // Join
|
||||
contactVal = contactInput.value
|
||||
}
|
||||
else if (mode==2 || mode==3) { // Move
|
||||
membersVal = ""
|
||||
contactVal = ""
|
||||
}
|
||||
else if (mode==3) { // Leave
|
||||
membersVal = ""
|
||||
contactVal = ""
|
||||
addressVec = [null,null,null]
|
||||
userPinData["latitude"] = null
|
||||
userPinData["longitude"] = null
|
||||
}
|
||||
|
||||
userData = {
|
||||
country: addressVec[0],
|
||||
state: addressVec[1],
|
||||
town: addressVec[2],
|
||||
latitude: userPinData["latitude"],
|
||||
longitude: userPinData["longitude"],
|
||||
contact: contactVal=="" ? null : contactVal,
|
||||
members: membersVal=="" ? null : parseInt(membersVal),
|
||||
group_id: userPinData["id"],
|
||||
mode: mode
|
||||
}
|
||||
|
||||
if (userData.state=="") {
|
||||
userData.state = null
|
||||
}
|
||||
if (userData.town=="") {
|
||||
userData.town = null
|
||||
}
|
||||
let url = "/" + locale + "/trade-unions-add-post/"
|
||||
sendData(url,userData,updateConfirmationMsg)
|
||||
}
|
||||
}
|
||||
|
||||
function resizeInput(el) {
|
||||
el.nextElementSibling.innerHTML = el.value
|
||||
}
|
||||
|
||||
function pinCallback(marker,event) {
|
||||
if (mode==1) {
|
||||
let lat = event.latlng.lat;
|
||||
let lng = event.latlng.lng;
|
||||
userPinData["latitude"] = lat
|
||||
userPinData["longitude"] = lng
|
||||
userPinData["id"] = marker.id
|
||||
userPinData["members"] = marker.members
|
||||
updatePin(userPin,lat,lng)
|
||||
userPin.setOpacity(1)
|
||||
reverseGeocodeLocal(lat, lng)
|
||||
reverseGeocode(lat, lng)
|
||||
}
|
||||
}
|
||||
|
||||
function chooseButton(index) {
|
||||
for (let b of modeButtons) {
|
||||
if (b!=undefined) {
|
||||
b.style.background = "rgba(197, 43, 40, 0.319)"
|
||||
b.style.color = "black"
|
||||
}
|
||||
}
|
||||
modeButtons[index].style.background = "rgb(197, 43, 40)"
|
||||
modeButtons[index].style.color = "white"
|
||||
mode = index
|
||||
}
|
||||
|
||||
function getAddress(g) {
|
||||
if (g!=undefined) {
|
||||
let location = [g.country,g.state,g.town].filter(x => x!=null)
|
||||
return location.map(x => locale=="en" ? x : translate($content,x)).join(", ")
|
||||
}
|
||||
else {
|
||||
return "Create or join trade-union"
|
||||
}
|
||||
}
|
||||
|
||||
function onLoaded() {
|
||||
if ($loaded==3) {
|
||||
chooseButton(mode)
|
||||
if (mode==2 || mode==3) {
|
||||
addressInput.value = getAddress(userGroups[0])
|
||||
}
|
||||
}
|
||||
else {
|
||||
let f = () => onLoaded()
|
||||
setTimeout(f, 100)
|
||||
}
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
onLoaded()
|
||||
})
|
||||
</script>
|
||||
|
||||
{#key $loaded}
|
||||
{#if $loaded==3}
|
||||
<div id="container">
|
||||
<button class="close-button" on:click={closeGroupsAdd}></button>
|
||||
<!--<img src="img/crowd.png" id="crowd" alt="crowd">-->
|
||||
<div id="text-container">
|
||||
{#if !has_group}
|
||||
<div bind:this={buttonsNotGroupMember} id="button-line">
|
||||
<button bind:this={modeButtons[0]} on:click={() => chooseButton(0)}>Create</button>
|
||||
<button bind:this={modeButtons[1]} on:click={() => chooseButton(1)}>Join</button>
|
||||
</div>
|
||||
{:else if has_group && !pendingGroup}
|
||||
<div bind:this={buttonsGroupMember} id="button-line">
|
||||
<button bind:this={modeButtons[2]} on:click={() => chooseButton(2)} style={"display: " + (pendingGroup ? "none" : "initial")}>Move</button>
|
||||
<button bind:this={modeButtons[3]} on:click={() => chooseButton(3)}>Leave</button>
|
||||
</div>
|
||||
{:else}
|
||||
<div bind:this={buttonsGroupMember} id="button-line">
|
||||
<button bind:this={modeButtons[3]} on:click={() => chooseButton(3)}>Leave</button>
|
||||
</div>
|
||||
{/if}
|
||||
<div id="address-input-wrapper" class="input-label-wrapper">
|
||||
<label for="address-input">Location: </label>
|
||||
<div class="input-wrapper">
|
||||
<input bind:this={addressInput} on:input={() => resizeInput(addressInput)} id="address-input" type="text" readonly>
|
||||
<div class="ghost-input"></div>
|
||||
</div>
|
||||
</div>
|
||||
{#key mode}
|
||||
{#if mode==0}
|
||||
<div id="members-input-wrapper" class="input-label-wrapper">
|
||||
<label for="members-input">Members: </label>
|
||||
<div class="input-wrapper">
|
||||
<input bind:this={membersInput} id="members-input" type="number" value={1} on:input={(event) => validatePosNumber(event,membersInput,10000)}>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{#if mode==0 || mode==1}
|
||||
<div class="input-label-wrapper">
|
||||
<label for="contact-input">Contact: </label>
|
||||
<div class="input-wrapper">
|
||||
<input bind:this={contactInput} on:input={() => resizeInput(contactInput)} id="contact-input" type="text">
|
||||
<div class="ghost-input"></div>
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{/key}
|
||||
<button id="submit-button" on:click={submitLocation}>Submit</button>
|
||||
<p id="confirmation-msg" bind:this={confirmationMsg}></p>
|
||||
{#if !(has_group && pendingGroup)}
|
||||
<map-component id="map" callback={(createMap) => mapCallback(createMap,$content,locale)}></map-component>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{/key}
|
||||
|
||||
<style>
|
||||
@import '/css/common.css';
|
||||
|
||||
#button-line {
|
||||
position: relative;
|
||||
width: fit-content;
|
||||
margin: auto;
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
|
||||
#button-line button{
|
||||
font-family: var(--sans-serif,sans-serif);
|
||||
font-size: 1.15rem;
|
||||
padding: 1rem 0;
|
||||
width: 7rem;
|
||||
}
|
||||
|
||||
#button-line :first-child {
|
||||
border-top-left-radius: 1rem;
|
||||
border-bottom-left-radius: 1rem;
|
||||
margin-right: 0.1rem;
|
||||
}
|
||||
|
||||
#button-line :last-child {
|
||||
margin-left: 0.1rem;
|
||||
border-top-right-radius: 1rem;
|
||||
border-bottom-right-radius: 1rem;
|
||||
}
|
||||
|
||||
.close-button {
|
||||
position: absolute;
|
||||
top: 2rem;
|
||||
right: 0rem;
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.close-button:hover {
|
||||
opacity: 0.7;
|
||||
}
|
||||
|
||||
.close-button::before,
|
||||
.close-button::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
left: 50%;
|
||||
width: 0.2rem;
|
||||
height: 2rem;
|
||||
background-color: #000;
|
||||
border-radius: 1rem;
|
||||
}
|
||||
|
||||
.close-button::before {
|
||||
transform: translate(-50%, -50%) rotate(45deg);
|
||||
}
|
||||
|
||||
.close-button::after {
|
||||
transform: translate(-50%, -50%) rotate(-45deg);
|
||||
}
|
||||
|
||||
|
||||
#confirmation-msg {
|
||||
margin-top: 0.5rem;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
ol li {
|
||||
margin-left: 1rem;
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
label {
|
||||
display: inline-block;
|
||||
font-family: var(--serif,serif);
|
||||
font-size: 1.15rem;
|
||||
line-height: 160%;
|
||||
color: #222222;
|
||||
width: 6rem;
|
||||
}
|
||||
|
||||
input, .ghost-input {
|
||||
font-size: 1.15rem;
|
||||
font-family: var(--serif,serif);
|
||||
}
|
||||
|
||||
input {
|
||||
height: 2.5rem;
|
||||
display: inline-block;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#address-input, #contact-input {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#address-input-wrapper {
|
||||
margin-top: 2rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
#members-input-wrapper {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
#members-input {
|
||||
width: 5rem;
|
||||
}
|
||||
|
||||
.ghost-input {
|
||||
display: block;
|
||||
visibility: hidden;
|
||||
height: 0;
|
||||
|
||||
padding-left: 0.5rem;
|
||||
padding-right: 0.5rem;
|
||||
}
|
||||
|
||||
.input-wrapper {
|
||||
display: inline-block;
|
||||
max-width: calc(100% - 5.5rem);
|
||||
min-width: min(20rem, calc(100% - 5.5rem));
|
||||
height: 2.5rem;
|
||||
}
|
||||
|
||||
.input-label-wrapper {
|
||||
display: flex;
|
||||
justify-content: start;
|
||||
}
|
||||
|
||||
.input-label-wrapper label {
|
||||
position: relative;
|
||||
top: 0.3rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
#submit-button {
|
||||
display: block;
|
||||
margin: auto;
|
||||
margin-top: 2rem;
|
||||
padding: 1rem 2rem;
|
||||
font-size: 1.4rem;
|
||||
font-family: var(--sans-serif,sans-serif);
|
||||
border: 0rem solid black;
|
||||
border-radius: 0.5rem;
|
||||
background: #cb1816;
|
||||
color: white;
|
||||
}
|
||||
|
||||
|
||||
#map {
|
||||
--height: 30rem;
|
||||
--width: 100%;
|
||||
--margin-top: 2rem;
|
||||
--margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
#text-container {
|
||||
position: relative;
|
||||
max-width: calc(100vw - 4rem);
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
#container {
|
||||
margin: auto;
|
||||
max-width: 800px;
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 4rem;
|
||||
}
|
||||
|
||||
#container p {
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
</style>
|
|
@ -0,0 +1,178 @@
|
|||
<svelte:options tag="trade-unions-component" />
|
||||
|
||||
<script>
|
||||
// Import statements
|
||||
import { onMount } from 'svelte'
|
||||
import { writable } from 'svelte/store';
|
||||
import { loadLocaleContent, getData} from "/js/libraries/serverTools.js"
|
||||
import { addMarkersEntries, translate } from "/js/libraries/mapTools.js"
|
||||
import { addTradeUnionPinContent } from "/js/mapFuncs.js"
|
||||
|
||||
// Import components
|
||||
import "/js/components/map-component.js"
|
||||
|
||||
// Main code
|
||||
let loaded = writable(0)
|
||||
let content = writable({})
|
||||
let entries
|
||||
let entriesByCountry
|
||||
|
||||
let locale = loadLocaleContent(content,"trade-unions-component",loaded)
|
||||
loadLocaleContent(content,"countries",loaded)
|
||||
|
||||
let callback = (response) => {
|
||||
entries = JSON.parse(response)
|
||||
entriesByCountry = {}
|
||||
for (let g of entries) {
|
||||
let country = g.country
|
||||
if (g.contact==null) {
|
||||
g.contact = "https://discord.gg/Qk8KUk787z"
|
||||
}
|
||||
if (country in entriesByCountry) {
|
||||
entriesByCountry[country].push(g)
|
||||
}
|
||||
else {
|
||||
entriesByCountry[country] = [g]
|
||||
}
|
||||
}
|
||||
loaded.update((val) => {
|
||||
return val + 1
|
||||
})
|
||||
}
|
||||
getData("/assets/trade-unions.json",callback)
|
||||
|
||||
function mapCallback(createMap,content,locale) {
|
||||
let map = createMap([22, 0],2)
|
||||
let options = {
|
||||
enableCountryGrouping: true,
|
||||
}
|
||||
addMarkersEntries(entries,entriesByCountry,map,content,locale,addTradeUnionPinContent,"violet",options)
|
||||
}
|
||||
|
||||
function getCountry(x) {
|
||||
return locale=="en" ? x : translate($content,x)
|
||||
}
|
||||
|
||||
function getAddress(g) {
|
||||
let location = [g.country,g.state,g.town].filter(x => x!=null)
|
||||
return location.map(x => locale=="en" ? x : translate($content,x)).join(", ")
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
|
||||
})
|
||||
</script>
|
||||
|
||||
{#key $loaded}
|
||||
{#if $loaded==3}
|
||||
<div id="container">
|
||||
<!--<img src="img/crowd.png" id="crowd" alt="crowd">-->
|
||||
<div id="text-container">
|
||||
<h1>{$content.tradeUnions}</h1>
|
||||
<img id="trade-unions-img" src="/img/common/trade-unions.svg" alt="trade unions">
|
||||
<p class="description">{$content.p1}</p>
|
||||
<h3>{$content.subheading1}</h3>
|
||||
<map-component id="map" callback={(createMap) => mapCallback(createMap,$content,locale)}></map-component>
|
||||
<p id="add-prompt">{$content["map-prompt"]}</p>
|
||||
{#each Object.entries(entriesByCountry) as [name,entries]}
|
||||
<h4 class="country-name">{getCountry(name)}</h4>
|
||||
<div class="country-block">
|
||||
{#each entries as entry}
|
||||
<div class="location-info">
|
||||
<p><b>{$content.name}: </b>{entry.name}</p>
|
||||
<p><b>{$content.location}: </b>{getAddress(entry)}</p>
|
||||
<p><b>{$content.members}: </b>{entry.members}</p>
|
||||
{#if entry.contact.includes("@") && entry.contact.trim().split(" ").length==1}
|
||||
<p><b>{$content.contact}: </b><a href={"mailto:" + entry.contact} target=;_blank; rel=noreferrer>{entry.contact}</a></p>
|
||||
{:else if entry.contact.includes("http")}
|
||||
<p><b>{$content.contact}: </b><a href={entry.contact} target=;_blank; rel=noreferrer>{entry.contact}</a></p>
|
||||
{:else}
|
||||
<p><b>{$content.contact}: </b>{entry.contact}</p>
|
||||
{/if}
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
{/each}
|
||||
</div>
|
||||
</div>
|
||||
{/if}
|
||||
{/key}
|
||||
|
||||
<style>
|
||||
@import '/css/common.css';
|
||||
|
||||
.description {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
#add-prompt {
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
#trade-unions-img {
|
||||
position: absolute;
|
||||
width: 14rem;
|
||||
left: 50%;
|
||||
transform: translate(-50%);
|
||||
z-index: 0;
|
||||
opacity: 0.2;
|
||||
}
|
||||
|
||||
#text-container>:nth-child(3) {
|
||||
margin-top: 8rem;
|
||||
}
|
||||
|
||||
.country-name {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
.country-block {
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.location-info {
|
||||
margin-bottom: 0.75rem;
|
||||
}
|
||||
|
||||
.location-info p {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
a {
|
||||
color: #DD1C1A;
|
||||
}
|
||||
|
||||
#map {
|
||||
--height: 30rem;
|
||||
--width: 100%;
|
||||
--margin-bottom: 0.5rem;
|
||||
}
|
||||
|
||||
#text-container {
|
||||
position: relative;
|
||||
max-width: calc(100vw - 4rem);
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
h1 {
|
||||
margin-bottom: 1rem;
|
||||
font-size: 2.2rem;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
#container {
|
||||
margin: auto;
|
||||
max-width: 800px;
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 4rem;
|
||||
}
|
||||
|
||||
#container p {
|
||||
text-align: justify;
|
||||
}
|
||||
|
||||
</style>
|
|
@ -0,0 +1,32 @@
|
|||
module CreateTableTradeUnions
|
||||
|
||||
import SearchLight.Migrations: create_table, column, primary_key, add_index, drop_table
|
||||
|
||||
include("../../lib/DatabaseSupport.jl")
|
||||
import .DatabaseSupport: add_foreign_key
|
||||
|
||||
function up()
|
||||
create_table(:trade_unions) do
|
||||
[
|
||||
primary_key()
|
||||
column(:country, :string)
|
||||
column(:state, :string)
|
||||
column(:town, :string)
|
||||
column(:contact, :string)
|
||||
column(:latitude, :float)
|
||||
column(:longitude, :float)
|
||||
column(:name, :string)
|
||||
column(:members, :int)
|
||||
column(:user_id, :int)
|
||||
]
|
||||
end
|
||||
|
||||
add_foreign_key(:trade_unions,:user_id,:users,:id)
|
||||
add_index(:trade_unions, :user_id)
|
||||
end
|
||||
|
||||
function down()
|
||||
drop_table(:trade_unions)
|
||||
end
|
||||
|
||||
end
|
|
@ -28,8 +28,6 @@ function up()
|
|||
|
||||
add_index(:groups_requests, :user_id)
|
||||
|
||||
set_default("groups_requests","added",false)
|
||||
|
||||
end
|
||||
|
||||
function down()
|
|
@ -0,0 +1,38 @@
|
|||
module CreateTableTradeUnionsRequests
|
||||
|
||||
import SearchLight.Migrations: create_table, column, primary_key, add_index, drop_table
|
||||
|
||||
include("../../lib/DatabaseSupport.jl")
|
||||
using .DatabaseSupport
|
||||
import .DatabaseSupport: add_foreign_key, set_default
|
||||
|
||||
function up()
|
||||
create_table(:trade_unions_requests) do
|
||||
[
|
||||
primary_key()
|
||||
column(:group_id, :integer)
|
||||
column(:user_id, :integer)
|
||||
column(:country, :string)
|
||||
column(:state, :string)
|
||||
column(:town, :string)
|
||||
column(:contact, :string)
|
||||
column(:latitude, :float)
|
||||
column(:longitude, :float)
|
||||
column(:members,:integer)
|
||||
column(:name,:string)
|
||||
column(:status,:integer)
|
||||
]
|
||||
end
|
||||
|
||||
add_foreign_key(:trade_unions_requests,:user_id,:users,:id)
|
||||
add_foreign_key(:trade_unions_requests,:group_id,:trade_unions,:id)
|
||||
|
||||
add_index(:trade_unions_requests, :user_id)
|
||||
|
||||
end
|
||||
|
||||
function down()
|
||||
drop_table(:trade_unions_requests)
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1,24 @@
|
|||
module CreateTableTradeUnionsUsers
|
||||
|
||||
import SearchLight.Migrations: create_table, column, primary_key, add_index, drop_table
|
||||
|
||||
function up()
|
||||
create_table(:trade_unions_users) do
|
||||
[
|
||||
primary_key()
|
||||
column(:user_id, :int)
|
||||
column(:trade_union_id, :int)
|
||||
]
|
||||
end
|
||||
|
||||
add_foreign_key(:trade_unions_users,:user_id,:users,:id)
|
||||
add_foreign_key(:trade_unions_users,:trade_union_id,:trade_unions,:id)
|
||||
add_index(:trade_unions_users, :user_id)
|
||||
add_index(:trade_unions_users, :trade_union_id)
|
||||
end
|
||||
|
||||
function down()
|
||||
drop_table(:trade_unions_users)
|
||||
end
|
||||
|
||||
end
|
|
@ -0,0 +1 @@
|
|||
[]
|
|
@ -1,3 +1,3 @@
|
|||
<svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-gear-fill" fill="#5B6970" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" d="M9.405 1.05c-.413-1.4-2.397-1.4-2.81 0l-.1.34a1.464 1.464 0 0 1-2.105.872l-.31-.17c-1.283-.698-2.686.705-1.987 1.987l.169.311c.446.82.023 1.841-.872 2.105l-.34.1c-1.4.413-1.4 2.397 0 2.81l.34.1a1.464 1.464 0 0 1 .872 2.105l-.17.31c-.698 1.283.705 2.686 1.987 1.987l.311-.169a1.464 1.464 0 0 1 2.105.872l.1.34c.413 1.4 2.397 1.4 2.81 0l.1-.34a1.464 1.464 0 0 1 2.105-.872l.31.17c1.283.698 2.686-.705 1.987-1.987l-.169-.311a1.464 1.464 0 0 1 .872-2.105l.34-.1c1.4-.413 1.4-2.397 0-2.81l-.34-.1a1.464 1.464 0 0 1-.872-2.105l.17-.31c.698-1.283-.705-2.686-1.987-1.987l-.311.169a1.464 1.464 0 0 1-2.105-.872l-.1-.34zM8 10.93a2.929 2.929 0 1 0 0-5.86 2.929 2.929 0 0 0 0 5.858z"/>
|
||||
<svg width="1em" height="1em" viewBox="0 0 16 16" class="bi bi-gear-fill" xmlns="http://www.w3.org/2000/svg">
|
||||
<path fill-rule="evenodd" fill="#5B6970" d="M9.405 1.05c-.413-1.4-2.397-1.4-2.81 0l-.1.34a1.464 1.464 0 0 1-2.105.872l-.31-.17c-1.283-.698-2.686.705-1.987 1.987l.169.311c.446.82.023 1.841-.872 2.105l-.34.1c-1.4.413-1.4 2.397 0 2.81l.34.1a1.464 1.464 0 0 1 .872 2.105l-.17.31c-.698 1.283.705 2.686 1.987 1.987l.311-.169a1.464 1.464 0 0 1 2.105.872l.1.34c.413 1.4 2.397 1.4 2.81 0l.1-.34a1.464 1.464 0 0 1 2.105-.872l.31.17c1.283.698 2.686-.705 1.987-1.987l-.169-.311a1.464 1.464 0 0 1 .872-2.105l.34-.1c1.4-.413 1.4-2.397 0-2.81l-.34-.1a1.464 1.464 0 0 1-.872-2.105l.17-.31c.698-1.283-.705-2.686-1.987-1.987l-.311.169a1.464 1.464 0 0 1-2.105-.872l-.1-.34zM8 10.93a2.929 2.929 0 1 0 0-5.86 2.929 2.929 0 0 0 0 5.858z"/>
|
||||
</svg>
|
Before Width: | Height: | Size: 837 B After Width: | Height: | Size: 837 B |
|
@ -1 +1 @@
|
|||
<svg viewBox="0 0 640 512" xmlns="http://www.w3.org/2000/svg" fill="#5B6970"><path d="m96 224c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm448 0c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm32 32h-64c-17.6 0-33.5 7.1-45.1 18.6 40.3 22.1 68.9 62 75.1 109.4h66c17.7 0 32-14.3 32-32v-32c0-35.3-28.7-64-64-64zm-256 0c61.9 0 112-50.1 112-112s-50.1-112-112-112-112 50.1-112 112 50.1 112 112 112zm76.8 32h-8.3c-20.8 10-43.9 16-68.5 16s-47.6-6-68.5-16h-8.3c-63.6 0-115.2 51.6-115.2 115.2v28.8c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48v-28.8c0-63.6-51.6-115.2-115.2-115.2zm-223.7-13.4c-11.6-11.5-27.5-18.6-45.1-18.6h-64c-35.3 0-64 28.7-64 64v32c0 17.7 14.3 32 32 32h65.9c6.3-47.4 34.9-87.3 75.2-109.4z"/></svg>
|
||||
<svg viewBox="0 0 640 512" xmlns="http://www.w3.org/2000/svg"><path fill="#5B6970" d="m96 224c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm448 0c35.3 0 64-28.7 64-64s-28.7-64-64-64-64 28.7-64 64 28.7 64 64 64zm32 32h-64c-17.6 0-33.5 7.1-45.1 18.6 40.3 22.1 68.9 62 75.1 109.4h66c17.7 0 32-14.3 32-32v-32c0-35.3-28.7-64-64-64zm-256 0c61.9 0 112-50.1 112-112s-50.1-112-112-112-112 50.1-112 112 50.1 112 112 112zm76.8 32h-8.3c-20.8 10-43.9 16-68.5 16s-47.6-6-68.5-16h-8.3c-63.6 0-115.2 51.6-115.2 115.2v28.8c0 26.5 21.5 48 48 48h288c26.5 0 48-21.5 48-48v-28.8c0-63.6-51.6-115.2-115.2-115.2zm-223.7-13.4c-11.6-11.5-27.5-18.6-45.1-18.6h-64c-35.3 0-64 28.7-64 64v32c0 17.7 14.3 32 32 32h65.9c6.3-47.4 34.9-87.3 75.2-109.4z"/></svg>
|
Before Width: | Height: | Size: 745 B After Width: | Height: | Size: 745 B |
Binary file not shown.
After Width: | Height: | Size: 4.1 KiB |
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 655.51 492.22">
|
||||
<g>
|
||||
<path id="path4" style="fill-rule: evenodd;" fill="#5B6970" d="m89.92,237.33c-8.97,2.22-18.14-3.38-20.26-12.35-2.22-8.97,3.38-18.14,12.35-20.26l240.37-58.67c8.97-2.22,18.14,3.38,20.26,12.35,2.22,8.97-3.38,18.14-12.35,20.26l-240.37,58.67Zm484.89,27.21c8.97,2.22,14.57,11.29,12.35,20.26s-11.29,14.57-20.26,12.35l-93.31-22.77c-8.97-2.22-14.57-11.29-12.35-20.26s11.29-14.57,20.26-12.35l93.31,22.77Zm9.75-83.57c9.07,2.12,14.67,11.19,12.54,20.17-2.12,9.07-11.19,14.67-20.17,12.54l-58.38-13.7c-9.07-2.12-14.67-11.19-12.54-20.17,2.12-9.07,11.19-14.67,20.17-12.54l58.38,13.7Zm-504.67-27.02c-9.07,2.12-18.14-3.57-20.17-12.54-2.12-9.07,3.57-18.14,12.54-20.17l169.25-39.66c9.07-2.12,18.14,3.57,20.17,12.54,2.12,9.07-3.57,18.14-12.54,20.17l-169.25,39.66Zm568.65-1.35l-206.6-50.37,20.65,83.18c3.47,13.99.87,27.98-6.08,39.47-6.85,11.29-18.14,19.97-31.94,23.45l-1.83.48c0,.1-.58.19-.77.19-52.3,8.4-96.5,16.79-134.23,24.41l-.19-.68-76.04,18.53,24.61,94.26c14.64,15.58,14.53,15.41,42.91,15.51,24.29-8.42,24.27-8.66,32.54-30.55l-22.77-92.06c1.16,1.06,2.61,1.93,4.25,2.32l305.22,74.4c4.92,1.25,10.04-1.83,11.19-6.85l45.74-184.6c1.35-4.82-1.74-9.94-6.66-11.1ZM7.03,88.34L363.1.24c5.02-1.16,10.04,1.93,11.29,6.95l46.8,188.46c1.25,4.92-1.83,10.04-6.85,11.19L58.27,294.94c-4.92,1.25-10.04-1.83-11.19-6.85L.28,99.63c-1.25-5.02,1.83-10.04,6.75-11.29Zm477.94,262.08l-76.04-18.53-22,107.4c4.23,26.34,3.74,25.6,26.68,38.88,24.82,2.87,25.17,3.26,46.02-13.91l25.34-113.85Z"/>
|
||||
<path fill="#5B6970" d="m217.55,281.13h91.49v109.1c0,25.25-20.5,45.75-45.75,45.75h0c-25.25,0-45.75-20.5-45.75-45.75v-109.1h0Z" transform="translate(-76.12 71.01) rotate(-13.44)"/>
|
||||
<path fill="#5B6970" d="m388.68,338.32h81.35v114.18c0,22.45-18.23,40.68-40.68,40.68h0c-22.45,0-40.68-18.23-40.68-40.68v-114.18h0Z" transform="translate(104.8 -86.1) rotate(13.03)"/>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 1.9 KiB |
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -0,0 +1 @@
|
|||
import{S as t,i as s,a as e,b as o,s as r,h as a,j as n,n as i,z as d,d as c,o as l}from"./index-0d9f0c09.js";import"../../../../../../../../../js/libraries/authTools.js";function h(t){let s,e,r;return{c(){s=a("h3"),s.textContent="Under development",e=n(),r=a("p"),r.innerHTML='Visit <a href="https://discord.gg/Qk8KUk787z" style="color: #c52a28;">https://discord.gg/Qk8KUk787z</a> and ask for your trade union to be added.',this.c=i,d(r,"position","relative"),d(r,"margin-top","2rem")},m(t,a){o(t,s,a),o(t,e,a),o(t,r,a)},p:i,i:i,o:i,d(t){t&&c(s),t&&c(e),t&&c(r)}}}function p(t){return l((()=>{})),[]}class u extends t{constructor(t){super(),this.shadowRoot.innerHTML="<style>@import '/css/common.css';h3{text-align:center}</style>",s(this,{target:this.shadowRoot,props:e(this.attributes),customElement:!0},p,h,r,{},null),t&&t.target&&o(t.target,this,t.anchor)}}customElements.define("profile-trade-unions",u);export{u as default};
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -13,9 +13,9 @@ export function debounce(func, timeout){
|
|||
}
|
||||
|
||||
export function svgFromObject(object) {
|
||||
var objectDoc = object.contentDocument;
|
||||
var svgItem = objectDoc.querySelector("path");
|
||||
return svgItem
|
||||
var objectDoc = object.contentDocument
|
||||
var svgItems = objectDoc.querySelectorAll("path")
|
||||
return svgItems
|
||||
}
|
||||
|
||||
export function rem2px(rem) {
|
||||
|
|
|
@ -6,7 +6,15 @@ export function addGroupPinContent(g,content,locale) {
|
|||
for (let field of ["location","members","contact"]) {
|
||||
let fieldText = content[field] + ": "
|
||||
if (field=="contact") {
|
||||
text += fieldText + "<a href='" + g.contact + "' target='_blank' rel=noreferrer>" + g.contact + "</a>"
|
||||
if (g.contact.includes("@") && g.contact.trim().split(" ").length==1) {
|
||||
text += fieldText + "<a href='mailto:" + g.contact + "' target='_blank' rel=noreferrer>" + g.contact + "</a>"
|
||||
}
|
||||
else if (g.contact.includes("http")) {
|
||||
text += fieldText + "<a href='" + g.contact + "' target='_blank' rel=noreferrer>" + g.contact + "</a>"
|
||||
}
|
||||
else {
|
||||
text += fieldText + g.contact + "<br>"
|
||||
}
|
||||
}
|
||||
else if (field=="location") {
|
||||
let location = [g.country,g.state,g.town].filter(x => x!=null && x!=undefined)
|
||||
|
@ -176,3 +184,30 @@ export function addPartnersPinContent(g,content,locale) {
|
|||
}
|
||||
return {text,coordinates}
|
||||
}
|
||||
|
||||
export function addTradeUnionPinContent(g,content,locale) {
|
||||
let coordinates
|
||||
let text = "<b>"+content["TradeUnion"]+"</b><br>"
|
||||
for (let field of ["name","location","members","contact"]) {
|
||||
let fieldText = content[field] + ": "
|
||||
if (field=="contact") {
|
||||
text += fieldText + "<a href='" + g.contact + "' target='_blank' rel=noreferrer>" + g.contact + "</a>"
|
||||
}
|
||||
else if (field=="location") {
|
||||
let location = [g.country,g.state,g.town].filter(x => x!=null && x!=undefined)
|
||||
let locationString
|
||||
if (locale=="en") {
|
||||
locationString = location.map(x => x).join(", ")
|
||||
}
|
||||
else {
|
||||
locationString = location.map(x => translate(content, x)).join(", ")
|
||||
}
|
||||
text += fieldText + locationString + "<br>"
|
||||
coordinates = [g.latitude,g.longitude]
|
||||
}
|
||||
else {
|
||||
text += fieldText + g[field] + "<br>"
|
||||
}
|
||||
}
|
||||
return {text,coordinates}
|
||||
}
|
|
@ -1,13 +1,15 @@
|
|||
{
|
||||
"top": "Our organization is a decentralized federation build upon the principle of free association. It consists of many groups of people united around a cause of bringing down exploitative politico-economic systems. We aim to replace them with libertarian socialist systems based on decentralization, direct democracy and worker-ownership of the means of production with the goal of creating an equitable, democratic and sustainable world by stopping exploitation of humans and nature.",
|
||||
"groupsTitle": "GROUPS",
|
||||
"groupsText": "We organize groups for the purposes of education, advocacy, anti-fascist action and mutual aid. Our objective is to demonstrate how the current politico-economic systems detrimentally impact our well-being, present alternative approaches, and engage in mutual aid to alleviate the challenges of living under capitalism.",
|
||||
"groupsText": "We organize groups for the purposes of education, advocacy, anti-fascist action and mutual aid. Our objective is to demonstrate how the current politico-economic systems detrimentally impact our well-being, present alternative approaches, and engage in mutual aid.",
|
||||
"communesTitle": "COMMUNES",
|
||||
"communesText": "We establish communes based on libertarian socialist principles, where commune members have ownership over land, houses, and the means of production as well as make decisions using direct democracy. We are gradually expanding our socialist world, one commune at a time.",
|
||||
"cooperativesTitle": "COOPERATIVES",
|
||||
"cooperativesText": "We form worker cooperatives to finance the operations of our groups and communes. Recognizing that economic power influences political power, we consider the establishment of cooperatives to be one of the initial steps towards achieving socialism.",
|
||||
"cooperativesText": "We form worker cooperatives to finance the operations of our groups and communes. Recognizing that economic power influences political power, we consider the establishment of cooperatives to be a vital activity.",
|
||||
"partiesTitle": "PARTIES",
|
||||
"partiesText": "We create political parties in order to push for reforms allowing us to easier further our goals, to move the Overton window as well as to gain popularity. However, we recognize that we cannot achieve libertarian socialism through institutions which act contrary to our goals.",
|
||||
"tradeUnionsTitle": "TRADE UNIONS",
|
||||
"tradeUnionsText": "We promote trade unions, which empower laborers to collectively advocate for fair treatment, just wages, and improved working conditions. Struggle at a place of work is an integral part of our strategy to achieve libertarian socialism.",
|
||||
"findUs": "Find Us",
|
||||
"whatNow": "What Now?",
|
||||
"joinUs": "Join Us",
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
"communes": "Communes",
|
||||
"cooperatives": "Cooperatives",
|
||||
"parties": "Parties",
|
||||
"tradeUnions": "Trade Unions",
|
||||
"partners": "Partners",
|
||||
"login": "Login",
|
||||
"profile": "Profile"
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"tradeUnions": "Trade Unions",
|
||||
"p1": "Trade unions play a pivotal role in safeguarding the rights and welfare of workers. Trade unions constitute an integral part of our organization, allowing workers to unite and collectively negotiate for fair wages, better working conditions, and improved labour rights. By fostering solidarity and mobilizing for collective action, trade unions contribute to our overarching mission of dismantling exploitative systems and ushering in a world centered on decentralized decision-making, direct democracy, and worker self-management.",
|
||||
"subheading1": "Our Trade Unions",
|
||||
"location": "Location",
|
||||
"members": "Members",
|
||||
"contact": "Contact",
|
||||
"TradeUnion": "Trade union",
|
||||
"tradeUnion": "trade union",
|
||||
"map-prompt": "Want to appear on our map? Contact us!"
|
||||
}
|
|
@ -8,6 +8,8 @@
|
|||
"cooperativesText": "Мы формируем рабочие кооперативы для финансирования операций наших групп и коммун, а также формирования основы новой социалистической экономики. Признавая, что экономическая власть влияет на политическую власть, мы считаем создание кооперативов одним из первых шагов на пути к социализму.",
|
||||
"partiesTitle": "ПАРТИИ",
|
||||
"partiesText": "Мы создаем политические партии, чтобы продвигать реформы, которые позволят легче достичь наших целей, сдвигать окно Овертона и увеличивать нашу популярность. Однако мы признаем, что мы не можем достичь либертарианского социализма с помощью институтов, действующих против наших целей.",
|
||||
"tradeUnionsTitle": "ПРОФСОЮЗЫ",
|
||||
"tradeUnionsText": "Мы поддерживаем профсоюзы, которые дают возможность работникам коллективно выступать за справедливое обращение, справедливую заработную плату и улучшение условий труда. Борьба на месте работы — неотъемлемая часть нашей стратегии по достижению либертарного социализма.",
|
||||
"findUs": "Найди нас",
|
||||
"whatNow": "Что теперь?",
|
||||
"joinUs": "Присоединяйся",
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
"cooperatives": "Кооперативы",
|
||||
"parties": "Партии",
|
||||
"partners": "Партнеры",
|
||||
"tradeUnions": "Профсоюзы",
|
||||
"login": "Войти",
|
||||
"profile": "Профиль"
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"tradeUnions": "Профсоюзы",
|
||||
"p1": "Профсоюзы играют ключевую роль в защите прав и благосостояния трудящихся. Профсоюзы составляют неотъемлемую часть нашей организации, позволяя работникам объединяться и вести коллективные переговоры о справедливой заработной плате, лучших условиях труда и улучшенных трудовых правах. Укрепляя солидарность и мобилизуя для коллективных действий, профсоюзы вносят свой вклад в нашу всеобъемлющую миссию по устранению эксплуататорских систем и установлению мира, основанного на децентрализованном принятии решений, прямой демократии и самоуправлении рабочих.",
|
||||
"subheading1": "Наши профсоюзы",
|
||||
"location": "Локация",
|
||||
"members": "Участники",
|
||||
"contact": "Контакт",
|
||||
"TradeUnion": "Профсоюз",
|
||||
"tradeUnion": "профсоюз",
|
||||
"map-prompt": "Хочешь оказаться на нашей карте? Напиши нам!"
|
||||
}
|
|
@ -88,6 +88,14 @@ route("/:locale/parties-add/*", PartiesController.parties_add, named = :parties_
|
|||
|
||||
route("/:locale/parties-add-post/*", PartiesController.parties_add_post, method = POST, named = :parties_add_post)
|
||||
|
||||
#---Trade unions---------------------------------------------------------
|
||||
|
||||
route("/:locale/trade-unions/*", TradeUnionsController.trade_unions, named = :trade_unions)
|
||||
|
||||
route("/:locale/trade-unions-add/*", TradeUnionsController.trade_unions_add, named = :trade_unions_add)
|
||||
|
||||
route("/:locale/trade-unions-add-post/*", TradeUnionsController.trade_unions_add_post, method = POST, named = :trade_unions_add_post)
|
||||
|
||||
#---Partners---------------------------------------------------------
|
||||
|
||||
route("/:locale/partners/*", PartnersController.partners, named = :partners)
|
||||
|
|
Loading…
Reference in New Issue