Finished groups

This commit is contained in:
a-ill
2023-08-01 15:56:41 +03:00
parent 7c9bb1e830
commit 41e1213566
70 changed files with 2033 additions and 18556 deletions

View File

@@ -169,3 +169,12 @@ label {
margin-top: -0.2rem;
color: #5f5f5f;
}
#content {
position: relative;
display: flex;
justify-content: space-between;
flex-direction: column;
height: 100%;
min-height: 100vh;
}

View File

@@ -0,0 +1,268 @@
/* Header */
#navbar{
position: relative;
top: 0;
width: min(100%,116rem);
z-index: 1000000000;
height: 5.26rem;
padding-left: 0rem;
padding-right: 0rem;
}
#navbar * {
font-family: var(--sans-serif, sans-serif);
}
/* Logo */
#logo-container {
display: flex;
position: absolute;
margin-left: 1rem;
height: 100%;
max-height: 5.26rem;
color: black;
z-index: 1;
flex-direction: row;
flex-wrap: nowrap;
align-items: center;
}
#navbar-logo {
height: 3.5rem;
width: 3.5rem;
object-fit: contain;
border-radius: 10rem;
}
#navbar-logo-text {
position: relative;
word-wrap: normal;
height: 100%;
line-height: 400%;
font-size: 1.4rem;
color: #292222;
font-family: var(--sans-serif, sans-serif);
font-weight: 400;
padding-left: 1.2rem;
}
/* Nav menu */
#nav {
position: fixed;
width: 100%;
height: 100%;
background-color: white;
overflow: hidden;
z-index: 0;
}
#menu > li > a, .options-button {
display: block;
padding: 1.2rem;
padding-top: 1rem;
padding-bottom: 1rem;
color: black;
font-size: 1.4rem;
}
#menu > li > a:active{
}
#menu li {
list-style-type: none;
}
#nav{
max-height: 0;
/*transition: max-height .5s ease-out;*/
}
/* Menu Icon */
#hamb{
position: absolute;
cursor: pointer;
right: 0rem;
padding: 2.8rem 2rem;
z-index: 9999;
}/* Style label tag */
#hamb-line {
background: black;
display: block;
height: 2px;
position: relative;
width: 24px;
} /* Style span tag */
#hamb-line::before,
#hamb-line::after{
background: black;
content: '';
display: block;
height: 100%;
position: absolute;
transition: all .2s ease-out;
width: 100%;
}
#hamb-line::before{
top: 5px;
}
#hamb-line::after{
top: -5px;
}
#side-menu {
display: none;
} /* Hide checkbox */
/* Toggle menu icon */
#side-menu:checked ~ nav {
display: block;
max-height: 100%;
padding-top: 5.625rem;
}
#side-menu:checked ~ #logo-container {
position: fixed;
}
#side-menu:checked ~ #hamb {
position: fixed;
}
#side-menu:checked ~ #logo-container {
position: fixed;
}
#side-menu:checked ~ #hamb #hamb-line {
background: transparent;
}
#side-menu:checked ~ #hamb #hamb-line::before {
transform: rotate(-45deg);
top: 0;
}
#side-menu:checked ~ #hamb #hamb-line::after {
transform: rotate(45deg);
top: 0;
}
/* Options */
.options-dropdown {
position: absolute;
display: none;
top: 5.6rem;
right: 1.8rem;
border: #404040 solid 0.1rem;
background-color: white;
z-index: 10;
}
.options-dropdown button, .options-dropdown a {
display: block;
font-family: var(--sans-serif,sans-serif);
font-size: 1.2rem;
width: 100%;
padding: 1rem;
text-align: left;
}
.options-dropdown button:hover, .options-dropdown a:hover {
background-color: var(--red);
color: white;
}
.options-button {
width: 100%;
text-align: left;
}
/* Localization */
#locales {
position: relative;
}
#locales button {
width: 100%;
text-align: left;
height: 4rem;
}
#locales button:hover {
opacity: 0.5;
}
#locales-img {
position: relative;
top: 0rem;
height: 2rem;
margin-left: 1.2rem;
}
/*
#options-dropdown>:first-child {
padding-bottom: 0.5rem;
}
#options-dropdown>:nth-child(2) {
padding-top: 0.5rem;
}
*/
/* Responsiveness */
@media only screen and (min-width: 1200px) {
#navbar {
position: relative;
width: min(100%,116rem);
left: 50%;
transform: translateX(-50%);
padding-right: 4rem;
padding-left: 4rem;
}
#nav {
max-height: none;
top: 0;
position: relative;
float: right;
width: fit-content;
background-color: transparent;
overflow: visible;
}
#side-menu:checked ~ nav {
padding-top: 0;
}
#menu li {
float: left;
}
#menu > li > a:hover, .options-button:hover, #navbar-logo-text:hover {
color: rgb(127, 127, 127);
}
#menu > li > a, .options-button {
padding: 0.9rem;
padding-top: 1.9rem;
padding-bottom: 1.9rem;
}
#hamb {
display: none;
}
#locales {
position: relative;
margin-right: 1.8rem;
}
#locales-img {
top: 0.9rem;
}
}

View File

@@ -1,12 +1,15 @@
import {getData, sendData} from "/js/libraries/serverTools.js"
export function getUser(user,callbackOuter) {
export function getUser(user,loaded,callbackOuter) {
let callback = function(response) {
Object.assign(user,JSON.parse(response))
if(callbackOuter!=undefined) {
callbackOuter()
}
loaded.update((val) => {
return val + 1
})
}
getData("/xx/get-user",callback)
}

View File

@@ -10,7 +10,7 @@ export function translate(content, x) {
}
}
function addMarkersToLayer(g,layer,content,locale,addPinContent,markerColor) {
function addMarkersToLayer(g,layer,content,locale,addPinContent,markerColor,options) {
let {text,coordinates} = addPinContent(g,content,locale)
var markerIcon = new L.Icon({
iconUrl: 'https://www.libsoc.org/img/common/markers/marker-' + markerColor + '.png',
@@ -21,57 +21,69 @@ function addMarkersToLayer(g,layer,content,locale,addPinContent,markerColor) {
shadowSize: [41, 41]
})
let marker = L.marker(coordinates, {icon: markerIcon})
marker.id = g.id
marker.members = g.members
marker.contact = g.contact
marker.addTo(layer).bindPopup(text)
if (options.pinCallback!=undefined) {
marker.on('click', (event) => options.pinCallback(marker,event))
}
}
export function addMarkersEntries(entries,entriesByCountry,map,content,locale,addPinContent,markerColor) {
export function addMarkersEntries(entries,entriesByCountry,map,content,locale,addPinContent,markerColor,options) {
let entriesMarkersLayer = L.layerGroup()
let entriesMarkersLayerOut = L.layerGroup()
let entriesMarkersLayerIn = L.layerGroup()
for (let g of entries) {
if (g.country!="Online" && g.country!="Worldwide") {
addMarkersToLayer(g,entriesMarkersLayerIn,content,locale,addPinContent,markerColor)
addMarkersToLayer(g,entriesMarkersLayerIn,content,locale,addPinContent,markerColor,options)
}
}
for (let gs of Object.values(entriesByCountry)) {
if (gs.length==1) {
let g = {...gs[0]}
g.country = [g.country]
if (g.country!="Online" && g.country!="Worldwide") {
addMarkersToLayer(g,entriesMarkersLayerOut,content,locale,addPinContent,markerColor)
if (options.enableCountryGrouping) {
for (let gs of Object.values(entriesByCountry)) {
if (gs.length==1) {
let g = {...gs[0]}
g.country = [g.country]
if (g.country!="Online" && g.country!="Worldwide") {
addMarkersToLayer(g,entriesMarkersLayerOut,content,locale,addPinContent,markerColor,options)
}
}
}
else {
if (gs[0].country!="Online" && gs[0].country!="Worldwide") {
let locationName = gs[0].country
let locationCoordinates = [0,0]
let members = 0
let contact = gs[0].contact
for (let g of gs) {
locationCoordinates[0] += g.latitude
locationCoordinates[1] += g.longitude
members += g.members
if (g.contact[0]!=gs[0].contact[0]) {
contact = contactGeneral
else {
if (gs[0].country!="Online" && gs[0].country!="Worldwide") {
let locationName = gs[0].country
let locationCoordinates = [0,0]
let members = 0
let contact = gs[0].contact
for (let g of gs) {
locationCoordinates[0] += g.latitude
locationCoordinates[1] += g.longitude
members += g.members
if (g.contact[0]!=gs[0].contact[0]) {
contact = contactGeneral
}
}
locationCoordinates[0] = locationCoordinates[0]/gs.length
locationCoordinates[1] = locationCoordinates[1]/gs.length
let gNew = {
country: locationName,
latitude: locationCoordinates[0],
longitude: locationCoordinates[1],
members: members,
contact: contact
}
addMarkersToLayer(gNew,entriesMarkersLayerOut,content,locale,addPinContent,markerColor,options)
}
locationCoordinates[0] = locationCoordinates[0]/gs.length
locationCoordinates[1] = locationCoordinates[1]/gs.length
let gNew = {
country: locationName,
latitude: locationCoordinates[0],
longitude: locationCoordinates[1],
members: members,
contact: contact
}
addMarkersToLayer(gNew,entriesMarkersLayerOut,content,locale,addPinContent,markerColor)
}
}
entriesMarkersLayerOut.addTo(entriesMarkersLayer)
map.on("zoomend", () => onZoomEnd(map,entriesMarkersLayer,entriesMarkersLayerOut,entriesMarkersLayerIn))
}
else {
entriesMarkersLayerIn.addTo(entriesMarkersLayer)
}
entriesMarkersLayerOut.addTo(entriesMarkersLayer)
entriesMarkersLayer.addTo(map)
map.on("zoomend", () => onZoomEnd(map,entriesMarkersLayer,entriesMarkersLayerOut,entriesMarkersLayerIn))
return entriesMarkersLayer
}

View File

@@ -67,6 +67,7 @@
<style>
@import '/css/common.css';
@import '/css/auth.css';
span {
font-size: 1.4rem;
@@ -91,7 +92,7 @@
display: flex;
position: absolute;
margin: auto;
top: 40%;
top: 40%;/*40%;*/
left: 50%;
transform: translate(-50%, -50%);
width: 5.4rem;
@@ -115,7 +116,7 @@
}
#auth-or {
top: 46.4rem;
top: 40rem;/*46.4rem;*/
}
#auth-group {

View File

@@ -81,13 +81,14 @@
</div>
<button class="auth-button" on:click="{() => AuthTools.login(msgs,inputs)}">Log in</button>
<a id="forgot-password" href="forgot-password">Forgot password?</a>
<!--
<hr class="auth-line">
<div class="auth-methods-group">
<div id="google-btn-wrapper">
<div bind:this={googleButton} id="google-btn"></div>
<img src="/img/auth/google_icon.svg" id="google-logo" alt="google icon">
</div>
<!--
<button on:click={openGoogleWindow}>
<img src="img/auth/google_icon.svg" id="navbar-logo" alt="google icon">
</button>
@@ -96,8 +97,9 @@
</button>
<button onclick="">
<img src="img/auth/linkedin_icon.svg" id="navbar-logo" alt="linkedin icon">
</button>-->
</button>
</div>
-->
</div>
<style>

View File

@@ -111,18 +111,20 @@
</div>
<button class="auth-button" on:click="{showDialog}">Sign up</button> <!--() => AuthTools.signup(msgs,inputs,AuthTools.toLandingPage)-->
<p id="forgot-password"></p>
<!--
<hr class="auth-line">
<div class="auth-methods-group">
<button on:click="{showDialog}">
<img src="/img/auth/google_icon.svg" id="navbar-logo" alt="google icon">
</button>
<!--<button onclick="">
<button onclick="">
<img src="img/auth/facebook_icon.svg" id="navbar-logo" alt="facebook icon">
</button>
<button onclick="">
<img src="img/auth/linkedin_icon.svg" id="navbar-logo" alt="linkedin icon">
</button>-->
</button>
</div>
-->
</div>
<div bind:this={dialog} id="dialog">

View File

@@ -43,7 +43,10 @@
function mapCallback(createMap,content,locale) {
let map = createMap([22, 0],2)
addMarkersEntries(entries,entriesByCountry,map,content,locale,addCommunePinContent,"red")
let options = {
enableCountryGrouping: true,
}
addMarkersEntries(entries,entriesByCountry,map,content,locale,addCommunePinContent,"red",options)
}
function getCountry(x) {

View File

@@ -9,6 +9,7 @@
// Export statements
export let callback = null
export let colors = null
export let map = null
// Main code
let mapContainer

View File

@@ -43,7 +43,10 @@
function mapCallback(createMap,content,locale) {
let map = createMap([22, 0],2)
addMarkersEntries(entries,entriesByCountry,map,content,locale,addCoopPinContent,"blue")
let options = {
enableCountryGrouping: true,
}
addMarkersEntries(entries,entriesByCountry,map,content,locale,addCoopPinContent,"blue",options)
}
function getCountry(x) {

View File

@@ -2,19 +2,26 @@
<script>
// Import statements
import { onMount } from 'svelte'
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 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)
@@ -41,11 +48,32 @@
let confirmationMsg
let addressInput
let contactInput
let addressVec
let userPinLat = 0
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,"groups-component",loaded)
loadLocaleContent(content,"countries",loaded)
@@ -105,23 +133,25 @@
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
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]
}
else {
state = ""
}
if (city!=undefined) {
fullAddress += ", " + city
}
else {
city = ""
}
addressVec = [country,state,city]
}
getData(url,callback)
}
@@ -153,85 +183,180 @@
return {text,coordinates}
}
function mapCallback(createMap,content,locale) {
let map = createMap([22, 0],2)
addMarkersEntries(entries,entriesByCountry,map,content,locale,addGroupPinContent,"green")
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) {
let lat = event.latlng.lat;
let lng = event.latlng.lng;
userPinLat = lat
userPinLng = lng
updatePin(userPin,lat,lng)
userPin.setOpacity(1)
reverseGeocodeLocal(lat, lng)
reverseGeocode(lat, lng)
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) {
confirmationMsg.innerHTML = "You have been added to our database! Now go to our Discord to verify yourself."
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!=undefined) {
let data = {
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: userPinLat,
longitude: userPinLng,
contact: contactInput.value
latitude: userPinData["latitude"],
longitude: userPinData["longitude"],
contact: contactVal=="" ? null : contactVal,
members: membersVal=="" ? null : parseInt(membersVal),
group_id: userPinData["id"],
mode: mode
}
if (data.state=="") {
data.state = null
if (userData.state=="") {
userData.state = null
}
if (data.town=="") {
data.town = null
}
if (data.contact=="") {
data.contact = null
if (userData.town=="") {
userData.town = null
}
let url = "/" + locale + "/groups-add-post/"
sendData(url,data,updateConfirmationMsg)
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 group"
}
}
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">
<h1>Add a Group</h1>
<img id="groups-img" src="/img/common/groups.svg" alt="groups">
<p class="description">If there are no groups in your town with whom you can organize then do the following:</p>
<ol>
<li>Click on the map to show us where you are located;</li>
<li>Add a way to contact you (an invite link or an email, not a phone number) or leave blank for a pin to point to our discord;</li>
<li>Press "Submit" to add yourself to our map;</li>
<li>Verify yourself by having a chat with us at our Discord server to show on the map;</li>
</ol>
{#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">
@@ -239,16 +364,30 @@
<div class="ghost-input"></div>
</div>
</div>
<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>
{#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="text" value={1}>
</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>
<map-component id="map" callback={(createMap) => mapCallback(createMap,$content,locale)}></map-component>
{#if !(has_group && pendingGroup)}
<map-component id="map" callback={(createMap) => mapCallback(createMap,$content,locale)}></map-component>
{/if}
</div>
</div>
{/if}
@@ -257,13 +396,75 @@
<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: 3rem;
margin-left: 1rem;
margin-bottom: 0.5rem;
}
@@ -273,7 +474,7 @@
font-size: 1.15rem;
line-height: 160%;
color: #222222;
width: 5.5rem;
width: 6rem;
}
input, .ghost-input {
@@ -296,6 +497,14 @@
margin-bottom: 1rem;
}
#members-input-wrapper {
margin-bottom: 1rem;
}
#members-input {
width: 5rem;
}
.ghost-input {
display: block;
visibility: hidden;
@@ -339,42 +548,6 @@
color: white;
}
#add-prompt {
margin-bottom: 2rem;
}
#groups-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;
@@ -389,16 +562,6 @@
margin: auto;
}
h1 {
margin-bottom: 1rem;
font-size: 2.2rem;
text-align: center;
}
h3 {
margin-bottom: 1rem;
}
#container {
margin: auto;
max-width: 800px;

View File

@@ -62,10 +62,13 @@
function mapCallback(createMap,content,locale) {
let map = createMap([22, 0],2)
let groupsMarkersLayer = addMarkersEntries(entries["groups"],entriesByCountry["groups"],map,content,locale,addGroupPinContent,"green")
let communesMarkersLayer = addMarkersEntries(entries["communes"],entriesByCountry["communes"],map,content,locale,addCommunePinContent,"red")
let coopsMarkersLayer = addMarkersEntries(entries["cooperatives"],entriesByCountry["cooperatives"],map,content,locale,addCoopPinContent,"blue")
let partiesMarkersLayer = addMarkersEntries(entries["parties"],entriesByCountry["parties"],map,content,locale,addPartyPinContent,"gold")
let options = {
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 overlayMaps = {}
overlayMaps[content.groups] = groupsMarkersLayer

View File

@@ -146,274 +146,6 @@
<style>
@import '/css/common.css';
/* Header */
#navbar{
position: relative;
top: 0;
width: min(100%,116rem);
z-index: 1000000000;
height: 5.26rem;
padding-left: 0rem;
padding-right: 0rem;
}
#navbar * {
font-family: var(--sans-serif, sans-serif);
}
/* Logo */
#logo-container {
display: flex;
position: absolute;
margin-left: 1rem;
height: 100%;
max-height: 5.26rem;
color: black;
z-index: 1;
flex-direction: row;
flex-wrap: nowrap;
align-items: center;
}
#navbar-logo {
height: 3.5rem;
width: 3.5rem;
object-fit: contain;
border-radius: 10rem;
}
#navbar-logo-text {
position: relative;
word-wrap: normal;
height: 100%;
line-height: 400%;
font-size: 1.4rem;
color: #292222;
font-family: var(--sans-serif, sans-serif);
font-weight: 400;
padding-left: 1.2rem;
}
/* Nav menu */
#nav {
position: fixed;
width: 100%;
height: 100%;
background-color: white;
overflow: hidden;
z-index: 0;
}
#menu > li > a, .options-button {
display: block;
padding: 1.2rem;
padding-top: 1rem;
padding-bottom: 1rem;
color: black;
font-size: 1.4rem;
}
#menu > li > a:active{
background-color: #f7aec0;
}
#menu li {
list-style-type: none;
}
#nav{
max-height: 0;
/*transition: max-height .5s ease-out;*/
}
/* Menu Icon */
#hamb{
position: absolute;
cursor: pointer;
right: 0rem;
padding: 2.8rem 2rem;
z-index: 9999;
}/* Style label tag */
#hamb-line {
background: black;
display: block;
height: 2px;
position: relative;
width: 24px;
} /* Style span tag */
#hamb-line::before,
#hamb-line::after{
background: black;
content: '';
display: block;
height: 100%;
position: absolute;
transition: all .2s ease-out;
width: 100%;
}
#hamb-line::before{
top: 5px;
}
#hamb-line::after{
top: -5px;
}
#side-menu {
display: none;
} /* Hide checkbox */
/* Toggle menu icon */
#side-menu:checked ~ nav {
display: block;
max-height: 100%;
padding-top: 5.625rem;
}
#side-menu:checked ~ #logo-container {
position: fixed;
}
#side-menu:checked ~ #hamb {
position: fixed;
}
#side-menu:checked ~ #logo-container {
position: fixed;
}
#side-menu:checked ~ #hamb #hamb-line {
background: transparent;
}
#side-menu:checked ~ #hamb #hamb-line::before {
transform: rotate(-45deg);
top: 0;
}
#side-menu:checked ~ #hamb #hamb-line::after {
transform: rotate(45deg);
top: 0;
}
/* Options */
.options-dropdown {
position: absolute;
display: none;
top: 5.6rem;
right: 1.8rem;
border: #404040 solid 0.1rem;
background-color: white;
z-index: 10;
}
.options-dropdown button, .options-dropdown a {
display: block;
font-family: var(--sans-serif,sans-serif);
font-size: 1.2rem;
width: 100%;
padding: 1rem;
text-align: left;
}
.options-dropdown button:hover, .options-dropdown a:hover {
background-color: var(--red);
color: white;
}
.options-button {
width: 100%;
text-align: left;
}
/* Localization */
#locales {
position: relative;
}
#locales button {
width: 100%;
text-align: left;
height: 4rem;
}
#locales button:hover {
opacity: 0.5;
}
#locales-img {
position: relative;
top: 0rem;
height: 2rem;
margin-left: 1.2rem;
}
/*
#options-dropdown>:first-child {
padding-bottom: 0.5rem;
}
#options-dropdown>:nth-child(2) {
padding-top: 0.5rem;
}
*/
/* Responsiveness */
@media only screen and (min-width: 1200px) {
#navbar {
position: relative;
width: min(100%,116rem);
left: 50%;
transform: translateX(-50%);
padding-right: 4rem;
padding-left: 4rem;
}
#nav {
max-height: none;
top: 0;
position: relative;
float: right;
width: fit-content;
background-color: transparent;
overflow: visible;
}
#side-menu:checked ~ nav {
padding-top: 0;
}
#menu li {
float: left;
}
#menu > li > a:hover, .options-button:hover, #navbar-logo-text:hover {
color: rgb(127, 127, 127);
}
#menu > li > a, .options-button {
padding: 0.9rem;
padding-top: 1.9rem;
padding-bottom: 1.9rem;
}
#hamb {
display: none;
}
#locales {
position: relative;
margin-right: 1.8rem;
}
#locales-img {
top: 0.9rem;
}
}
@import '/css/navbar.css';
</style>

View File

@@ -147,274 +147,5 @@
<style>
@import '/css/common.css';
/* Header */
#navbar{
position: relative;
top: 0;
width: min(100%,116rem);
z-index: 1000000000;
height: 5.26rem;
padding-left: 0rem;
padding-right: 0rem;
}
#navbar * {
font-family: var(--sans-serif, sans-serif);
}
/* Logo */
#logo-container {
display: flex;
position: absolute;
margin-left: 1rem;
height: 100%;
max-height: 5.26rem;
color: black;
z-index: 1;
flex-direction: row;
flex-wrap: nowrap;
align-items: center;
}
#navbar-logo {
height: 3.5rem;
width: 3.5rem;
object-fit: contain;
border-radius: 10rem;
}
#navbar-logo-text {
position: relative;
word-wrap: normal;
height: 100%;
line-height: 400%;
font-size: 1.4rem;
color: #292222;
font-family: var(--sans-serif, sans-serif);
font-weight: 400;
padding-left: 1.2rem;
}
/* Nav menu */
#nav {
position: fixed;
width: 100%;
height: 100%;
background-color: white;
overflow: hidden;
z-index: 0;
}
#menu > li > a, .options-button {
display: block;
padding: 1.2rem;
padding-top: 1rem;
padding-bottom: 1rem;
color: black;
font-size: 1.4rem;
}
#menu > li > a:active{
background-color: #f7aec0;
}
#menu li {
list-style-type: none;
}
#nav{
max-height: 0;
/*transition: max-height .5s ease-out;*/
}
/* Menu Icon */
#hamb{
position: absolute;
cursor: pointer;
right: 0rem;
padding: 2.8rem 2rem;
z-index: 9999;
}/* Style label tag */
#hamb-line {
background: black;
display: block;
height: 2px;
position: relative;
width: 24px;
} /* Style span tag */
#hamb-line::before,
#hamb-line::after{
background: black;
content: '';
display: block;
height: 100%;
position: absolute;
transition: all .2s ease-out;
width: 100%;
}
#hamb-line::before{
top: 5px;
}
#hamb-line::after{
top: -5px;
}
#side-menu {
display: none;
} /* Hide checkbox */
/* Toggle menu icon */
#side-menu:checked ~ nav {
display: block;
max-height: 100%;
padding-top: 5.625rem;
}
#side-menu:checked ~ #logo-container {
position: fixed;
}
#side-menu:checked ~ #hamb {
position: fixed;
}
#side-menu:checked ~ #logo-container {
position: fixed;
}
#side-menu:checked ~ #hamb #hamb-line {
background: transparent;
}
#side-menu:checked ~ #hamb #hamb-line::before {
transform: rotate(-45deg);
top: 0;
}
#side-menu:checked ~ #hamb #hamb-line::after {
transform: rotate(45deg);
top: 0;
}
/* Options */
.options-dropdown {
position: absolute;
display: none;
top: 5.6rem;
right: 1.8rem;
border: #404040 solid 0.1rem;
background-color: white;
z-index: 10;
}
.options-dropdown button, .options-dropdown a {
display: block;
font-family: var(--sans-serif,sans-serif);
font-size: 1.2rem;
width: 100%;
padding: 1rem;
text-align: left;
}
.options-dropdown button:hover, .options-dropdown a:hover {
background-color: var(--red);
color: white;
}
.options-button {
width: 100%;
text-align: left;
}
/* Localization */
#locales {
position: relative;
}
#locales button {
width: 100%;
text-align: left;
height: 4rem;
}
#locales button:hover {
opacity: 0.5;
}
#locales-img {
position: relative;
top: 0rem;
height: 2rem;
margin-left: 1.2rem;
}
/*
#options-dropdown>:first-child {
padding-bottom: 0.5rem;
}
#options-dropdown>:nth-child(2) {
padding-top: 0.5rem;
}
*/
/* Responsiveness */
@media only screen and (min-width: 1200px) {
#navbar {
position: relative;
width: min(100%,116rem);
left: 50%;
transform: translateX(-50%);
padding-right: 4rem;
padding-left: 4rem;
}
#nav {
max-height: none;
top: 0;
position: relative;
float: right;
width: fit-content;
background-color: transparent;
overflow: visible;
}
#side-menu:checked ~ nav {
padding-top: 0;
}
#menu li {
float: left;
}
#menu > li > a:hover, .options-button:hover, #navbar-logo-text:hover {
color: rgb(127, 127, 127);
}
#menu > li > a, .options-button {
padding: 0.9rem;
padding-top: 1.9rem;
padding-bottom: 1.9rem;
}
#hamb {
display: none;
}
#locales {
position: relative;
margin-right: 1.8rem;
}
#locales-img {
top: 0.9rem;
}
}
@import '/css/navbar.css';
</style>

View File

@@ -14,7 +14,16 @@
</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 commune to be added.</p>
<style>
@import '/css/common.css';
h3 {
text-align: center;
}
</style>

View File

@@ -4,6 +4,7 @@
// Import libraries
import { onMount, afterUpdate, setContext } from 'svelte'
import { writable } from 'svelte/store'
import * as AuthTools from "/js/libraries/authTools.js"
import {svgFromObject} from "/js/libraries/miscTools.js"
@@ -11,6 +12,10 @@
import "/js/components/pane-aligner.js"
import "/js/components/profile-general.js"
import "/js/components/profile-groups.js"
import "/js/components/profile-communes.js"
import "/js/components/profile-coops.js"
import "/js/components/profile-parties.js"
import "/js/components/groups-add-component.js"
// Main code
AuthTools.redirectNotLogged()
@@ -22,6 +27,7 @@
let coops
let parties
let panes
let groupsAdd
let generalButton
let groupsButton
@@ -29,11 +35,17 @@
let coopsButton
let partiesButton
let buttons
let currentPaneIndex = 0
let locationPopup
let maps = {}
let user = {}
AuthTools.getUser(user)
let loaded = writable(0)
let reloadTriggerVal = writable(0)
AuthTools.getUser(user,loaded)
function changePane(pane,button) {
for (let p of panes) {
@@ -48,10 +60,24 @@
}
function styleField(div,weight,color) {
div.style.fontWeight = weight
let svgObject = div.querySelector("object")
let svgItem = svgFromObject(svgObject)
svgItem.setAttribute("fill", color)
if (svgObject==null) {
let f = () => styleField(div,weight,color)
setTimeout(f,100)
}
else {
let svgItem = svgFromObject(svgObject)
if (svgItem==null) {
let f = () => styleField(div,weight,color)
setTimeout(f,100)
}
else {
div.style.fontWeight = weight
svgItem.setAttribute("fill", color)
}
}
}
function fillFields() {
@@ -59,37 +85,54 @@
for (let b of buttons) {
styleField(b,400,"#636363")
}
styleField(generalButton,500,"#c52a28")
styleField(buttons[currentPaneIndex],500,"#c52a28")
}
else {
setTimeout(fillFields, 100)
}
}
function showLocationOverlay() {
locationPopup.style.display = "block"
function valid(el) {
return (el!=undefined) && (el!=null)
}
setContext("profile-component",showLocationOverlay)
onMount(() => {
general.user = user
function init() {
panes = [general,groups,communes,coops,parties]
buttons = [generalButton,groupsButton,communesButton,coopsButton,partiesButton]
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]
fillFields()
general.style.display = "initial"
fillFields()
general.style.display = "initial"
}
else {
let f = () => init()
setTimeout(f,100)
}
}
function reloadTrigger() {
reloadTriggerVal.update((val) => {
return val + 1
})
}
setContext("profile-component",{user,maps,reloadTrigger})
onMount(() => {
init()
})
</script>
<!--
<div bind:this={locationPopup} class="overlay" style="display: none">
<div id="location-overlay-content">
<p>wegwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww</p>
</div>
<button class="overlay-button" on:click={() => locationPopup.style.display = "none"}></button>
</div>
-->
<pane-aligner>
<div id="left-column" class="pane" slot="sidebar-left" bind:this={root}>
<button bind:this={generalButton} on:click={() => changePane(general,generalButton)}>
@@ -118,11 +161,15 @@
</button>
</div>
<div id="main-column" slot="main">
<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>
{#key $loaded}
{#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>
{/if}
{/key}
</div>
</pane-aligner>
@@ -131,34 +178,6 @@
@import '/css/common.css';
#location-overlay-content {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
height: 40rem;
width: 40rem;
background: white;
z-index: 10000;
}
.overlay {
top: 0;
position: absolute;
width: 100%;
height: 100%;
z-index: 10000;
}
.overlay-button {
position: absolute;
background: gray;
opacity: 0.5;
width: 100vw;
height: 100vh;
z-index: 1000;
}
#general-img {
top: 0rem;
}

View File

@@ -14,7 +14,16 @@
</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 cooperative to be added.</p>
<style>
@import '/css/common.css';
h3 {
text-align: center;
}
</style>

View File

@@ -3,7 +3,7 @@
<script>
// Import statements
import { onMount, setContext } from 'svelte'
import { onMount, getContext } from 'svelte'
import * as AuthTools from "/js/libraries/authTools.js"
//Import components
@@ -11,7 +11,6 @@
import "/js/components/switch-component.js"
//Export statements
export let user = null
// Main code
let emailInput
@@ -30,6 +29,9 @@
let emailInputDiv
let prevEmail
let context = getContext("profile-component")
let user = context.user
function showSaveButton(button) {
prevEmail = emailInput.value
button.style.display = "initial"
@@ -166,11 +168,27 @@
</button>
</div>
</div>
<div>
<div id="verifiedDiv">
<span>Verified:</span>
<span style="color: {user.verified ? "green" : "red"}">{user.verified}</span>
</div>
</div>
</section>
<style>
@import '/css/common.css';
#verifiedDiv {
display: inline;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
height: 2rem;
width: 100%;
}
/*---General section-----------------------------------------------------------*/
.ghost-input {

View File

@@ -5,20 +5,24 @@
// Import statements
import { onMount, getContext } from 'svelte'
import { writable } from 'svelte/store'
import { getData } from "/js/libraries/serverTools.js"
import { getData, sendData } from "/js/libraries/serverTools.js"
//Import components
import "/js/components/select-component.js"
import "/js/components/switch-component.js"
//Export statements
export let groups = null
// Main code
let section
let user_groups
let userGroups = []
let groupsRequests = []
let content = writable({})
let loaded = writable(0)
let keyRequests = 0
let numLoaded = 2
let mainPane
let groupsAdd
let membersInput
let saveMembersButton
@@ -30,22 +34,46 @@
let locale = "en"
let inputLocation
let inputContact
let inputMembers
let pencilMembers
let pencilContact
let pencilButtonMembers
let pencilButtonContact
let myGroupLocation
let myGroupStatus
let context = getContext("profile-component")
let maps = context.maps
function groups_callback(response) {
user_groups = JSON.parse(response)
inputContact = getContact(user_groups[0].contact)
inputMembers = user_groups[0].members
userGroups = JSON.parse(response)
context["userGroups"] = userGroups
loaded.update((val) => {
return val + 1
})
}
getData("/xx/get_user_groups",groups_callback)
getData("/xx/get-user-groups",groups_callback)
function requests_callback(response) {
let parsed = JSON.parse(response)
groupsRequests.push(...parsed)
loaded.update((val) => {
return val + 1
})
}
getData("/xx/get-group-requests",requests_callback)
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(", ")
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 group"
}
}
function getContact(c) {
@@ -65,8 +93,10 @@
}
function showSaveButton(button) {
button.style.display = "initial"
function showSaveButton(button,input) {
if (!input.readOnly) {
button.style.display = "initial"
}
}
function resetMembersField() {
@@ -89,73 +119,178 @@
function saveContact() {}
let showLocationOverlay = getContext("profile-component")
function updateUserGroup(newInfo) {
if (newInfo!=undefined) {
myGroupLocation.innerHTML = getAddress(newInfo)
}
}
onMount(() => {
document.addEventListener("click", function(event) {
if (membersInputDiv.focused) {
resetContactField()
}
else if (contactInputDiv.focused) {
resetMembersField()
function onLoadedGroups() {
let els = [saveMembersButton,saveContactButton,membersInputDiv,contactInputDiv]
if ($loaded==numLoaded && els.every(x => x!=undefined && x!=null)) {
document.addEventListener("click", function(event) {
let activeEl
let shadowRoot = this.activeElement.shadowRoot
if (shadowRoot!=null) {
activeEl = shadowRoot.activeElement
shadowRoot = activeEl.shadowRoot
if (shadowRoot!=null) {
activeEl = shadowRoot.activeElement
}
}
if (activeEl == membersInput || activeEl == saveMembersButton) {
resetContactField()
}
else if (activeEl == contactInput || activeEl == saveContactButton) {
resetMembersField()
}
else {
resetMembersField()
resetContactField()
}
})
context["updateUserGroup"] = updateUserGroup
inputLocation = getAddress(userGroups[0])
if (userGroups.length==0) {
inputContact = ""
inputMembers = ""
}
else {
resetMembersField()
resetContactField()
let group = userGroups[0]
inputContact = getContact(group.contact)
inputMembers = group.members
let status = group.status
if (status!=undefined) {
if (status==0) {
myGroupStatus.innerHTML = "(pending)"
myGroupStatus.style.color = "#FFC90E"
}
else if (status==2) {
myGroupStatus.innerHTML = "(rejected)"
myGroupStatus.style.color = "#c52a28"
}
pencilMembers.style.display = "none"
pencilContact.style.display = "none"
pencilButtonContact.style.cursor = "default"
pencilButtonMembers.style.cursor = "default"
membersInput.readOnly = true
contactInput.readOnly = true
}
}
})
}
else {
let f = () => onLoadedGroups()
setTimeout(f, 100)
}
}
function focus(el) {
el.focus()
el.click()
}
function approveRequest(ind,user_id) {
sendData("/xx/group-approve-request",{user_id: user_id})
groupsRequests.splice(ind,1)
keyRequests = keyRequests + 1
}
function rejectRequest(ind,user_id) {
sendData("/xx/group-reject-request",{user_id: user_id})
groupsRequests.splice(ind,1)
keyRequests = keyRequests + 1
}
function launchGroupsAdd() {
groupsAdd.style.display = "block"
mainPane.style.display = "none"
if (maps["groupsAdd"]!=undefined) {
maps["groupsAdd"].invalidateSize()
}
}
function closeGroupsAdd() {
groupsAdd.style.display = "none"
mainPane.style.display = "block"
}
context["onLoadedGroups"] = onLoadedGroups
context["launchGroupsAdd"] = launchGroupsAdd
context["closeGroupsAdd"] = closeGroupsAdd
onMount(() => {
onLoadedGroups()
})
</script>
{#key $loaded}
{#if $loaded==1}
<h2>Groups</h2>
<h3>My group</h3>
<section bind:this={section} class="entries-section">
{#if $loaded==numLoaded}
<div bind:this={mainPane}>
<h2>Groups</h2>
<div>
<div class="change-field-line">
<span>Location:</span>
<div class="change-field-div">
<button class="change-field-button" on:click={launchChangeLocation}>{getAddress(user_groups[0])}
<object type="image/svg+xml" data="/img/profile/icons/pencil.svg" title="pencil-icon" class="pencil"></object>
</button>
<h3 class="group-heading">My group</h3>
<span bind:this={myGroupStatus} class="status"></span>
</div>
<section bind:this={section} class="entries-section">
<div>
<div class="change-field-line">
<span>Location:</span>
<div class="change-field-div">
<button class="change-field-button" bind:this={myGroupLocation} on:click={launchGroupsAdd}>{inputLocation}
<object type="image/svg+xml" data="/img/profile/icons/pencil.svg" title="pencil-icon" class="pencil"></object>
</button>
</div>
</div>
</div>
</div>
<div>
<div class="change-field-line">
<span>Members:</span>
<div bind:this={membersInputDiv} class="change-field-div input-pencil">
<button bind:this={saveMembersButton} class="save-button" on:click={saveMembers}>save</button>
<input bind:this={membersInput} id="membersInput" class="text-input" type="text" bind:value={inputMembers} on:click={() => showSaveButton(saveMembersButton)}>
<button class="text-input-pencil-button" on:click={() => membersInput.focus()}>
<object type="image/svg+xml" data="/img/profile/icons/pencil.svg" title="pencil-icon" class="pencil"></object>
</button>
<div>
<div class="change-field-line">
<span>Members:</span>
<div bind:this={membersInputDiv} class="change-field-div input-pencil">
<div class="save-button-wrapper">
<button bind:this={saveMembersButton} on:click={saveMembers} class="save-button" style="display: none">save</button>
</div>
<input bind:this={membersInput} id="membersInput" class="text-input" type="text" bind:value={inputMembers} on:click={() => showSaveButton(saveMembersButton,membersInput)}>
<button bind:this={pencilButtonMembers} class="text-input-pencil-button" on:click={() => {focus(membersInput)}}>
<object bind:this={pencilMembers} type="image/svg+xml" data="/img/profile/icons/pencil.svg" title="pencil-icon" class="pencil"></object>
</button>
</div>
</div>
</div>
</div>
<div>
<div class="change-field-line">
<span>Contact:</span>
<div bind:this={contactInputDiv} class="change-field-div input-pencil">
<button bind:this={saveContactButton} class="save-button" on:click={saveContact}>save</button>
<input bind:this={contactInput} id="contactInput" class="text-input" type="text" bind:value={inputContact} on:click={() => showSaveButton(saveContactButton)}>
<button class="text-input-pencil-button" on:click={() => contactInput.focus()}>
<object type="image/svg+xml" data="/img/profile/icons/pencil.svg" title="pencil-icon" class="pencil"></object>
</button>
<div>
<div class="change-field-line">
<span>Contact:</span>
<div bind:this={contactInputDiv} class="change-field-div input-pencil">
<div class="save-button-wrapper">
<button bind:this={saveContactButton} on:click={saveContact} class="save-button" style="display: none">save</button>
</div>
<input bind:this={contactInput} id="contactInput" class="text-input" type="text" bind:value={inputContact} on:click={() => showSaveButton(saveContactButton,contactInput)}>
<button bind:this={pencilButtonContact} class="text-input-pencil-button" on:click={focus(contactInput)}>
<object bind:this={pencilContact} type="image/svg+xml" data="/img/profile/icons/pencil.svg" title="pencil-icon" class="pencil"></object>
</button>
</div>
</div>
</div>
</div>
</section>
<h3>Requests</h3>
<section bind:this={section} class="entries-section">
</section>
</section>
<h3>Requests</h3>
<section bind:this={section} class="entries-section">
{#key keyRequests}
{#each groupsRequests as req,ind}
<div>
<div class="change-field-line">
<span>{req.email}</span>
<div class="request-button-wrapper">
<button on:click={() => approveRequest(ind,req.user_id)} class="approve-button">approve</button>
<button on:click={() => rejectRequest(ind,req.user_id)} class="approve-button" style="display:visible">reject</button>
</div>
</div>
</div>
{/each}
{/key}
</section>
</div>
<!--Helper panes-->
<groups-add-component bind:this={groupsAdd} style="display: none;"></groups-add-component>
{/if}
{/key}
@@ -163,10 +298,42 @@
<style>
@import '/css/common.css';
.request-button-wrapper {
display: flex;
gap: 1rem;
}
.approve-button {
height: 2.7rem;
padding: 0rem 1rem;
font-family: var(--sans-serif,sans-serif);
font-size: 1.15rem;
color: white;
background-color: var(--red);
border-color: var(--red);
border-radius: 0.5rem;
margin-top: -0.5rem;
}
.group-heading {
display: inline-block;
}
.status {
display: inline-block;
font-size: 1.15rem;
font-family: var(--sans-serif,sans-serif);
margin-left: 0.5rem;
}
input {
font-family: var(--sans-serif,sans-serif)
}
.text-input-pencil-button {
display: inline-block;
position: relative;
height: 2.3rem;
height: 2.7rem;
width: 2rem;
}
@@ -187,10 +354,10 @@
direction: rtl;
border: 0;
outline: none;
bottom: 0.341rem;
position: relative;
top: 0.1rem;
font-style: var(--sans-serif,sans-serif)
height: 2.7rem;
font-style: var(--sans-serif,sans-serif);
background: transparent;
margin-top: -0.5rem;
}
#membersInput {
@@ -202,17 +369,24 @@
}
.save-button {
position: relative;
bottom: 0.34rem;
position: absolute;
right: 0;
top: -0.4rem;
margin-right: 0.6rem;
height: 2.73rem;
width: 4.778rem;
height: 2.7rem;
width: 5rem;
font-family: var(--sans-serif,sans-serif);
font-size: 1.15rem;
color: white;
background-color: var(--red);
border-color: var(--red);
border-radius: 0.512rem;
border-radius: 0.5rem;
}
.save-button-wrapper {
display: inline-block;
position: relative;
height: 2rem;
}
h2 {
@@ -248,12 +422,14 @@
.change-field-div {
width: max-content;
position: relative;
display: flex;
}
.change-field-button {
position: relative;
cursor: pointer;
height: 2.73rem;
height: 2.7rem;
font-size: 1.15rem;
font-family: var(--sans-serif,sans-serif);
font-weight: 500;
@@ -270,31 +446,10 @@
h3 {
margin-bottom: 0.5rem;
}
.entry-container {
margin-top: 0.5rem;
margin-bottom: 0.5rem;
}
.entry {
font-family: var(--sans-serif,sans-serif);
font-size: 1.15rem;
}
span {
font-family: var(--sans-serif,sans-serif);
font-size: 1.15rem;
}
#groups-section {
display: flex;
flex-direction: column;
}
#groups-section h2 {
margin: auto;
margin-top: 0;
margin-bottom: 0;
}
</style>

View File

@@ -14,7 +14,16 @@
</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 party to be added.</p>
<style>
@import '/css/common.css';
h3 {
text-align: center;
}
</style>