card display, edit (all fields)

This commit is contained in:
Matilde Park 2019-12-13 01:29:04 -05:00 committed by Logan Allen
parent a10ac18e67
commit 9ea67c20c9
2 changed files with 579 additions and 107 deletions

View File

@ -63098,16 +63098,26 @@ lyrtesmudnytbyrsenwegfyrmurtelreptegpecnelnevfes\
this.state = { this.state = {
edit: false, edit: false,
colorToSet: "", colorToSet: "",
nickNameToSet: "" nickNameToSet: "",
emailToSet: "",
phoneToSet: "",
websiteToSet: "",
notesToSet: ""
}; };
this.editToggle = this.editToggle.bind(this); this.editToggle = this.editToggle.bind(this);
this.sigilColorSet = this.sigilColorSet.bind(this); this.sigilColorSet = this.sigilColorSet.bind(this);
this.nickNameToSet = this.nickNameToSet.bind(this); this.nickNameToSet = this.nickNameToSet.bind(this);
this.emailToSet = this.emailToSet.bind(this);
this.phoneToSet = this.phoneToSet.bind(this);
this.websiteToSet = this.websiteToSet.bind(this);
this.notesToSet = this.notesToSet.bind(this);
this.setField = this.setField.bind(this); this.setField = this.setField.bind(this);
} }
componentDidUpdate() { componentDidUpdate() {
// sigil color updates are done by keystroke parsing on update
// other field edits are exclusively handled by setField()
let currentColor = (this.props.contact.color) ? this.props.contact.color : "0x0"; let currentColor = (this.props.contact.color) ? this.props.contact.color : "0x0";
let currentHex = uxToHex(currentColor); let currentHex = uxToHex(currentColor);
let hexExp = /#?([0-9A-Fa-f]{6})/; let hexExp = /#?([0-9A-Fa-f]{6})/;
@ -63125,10 +63135,30 @@ lyrtesmudnytbyrsenwegfyrmurtelreptegpecnelnevfes\
this.setState({edit: editSwitch}); this.setState({edit: editSwitch});
} }
emailToSet(event) {
this.setState({ emailToSet: event.target.value });
}
nickNameToSet(event) { nickNameToSet(event) {
this.setState({ nickNameToSet: event.target.value }); this.setState({ nickNameToSet: event.target.value });
} }
notesToSet(event) {
this.setState({ notesToSet: event.target.value });
}
phoneToSet(event) {
this.setState({ phoneToSet: event.target.value });
}
sigilColorSet(event) {
this.setState({ colorToSet: event.target.value });
}
websiteToSet(event) {
this.setState({ websiteToSet: event.target.value });
}
shipParser(ship) { shipParser(ship) {
switch (ship.length) { switch (ship.length) {
case 3: return "Galaxy"; case 3: return "Galaxy";
@ -63141,28 +63171,110 @@ lyrtesmudnytbyrsenwegfyrmurtelreptegpecnelnevfes\
setField(field) { setField(field) {
let ship = "~" + this.props.ship; let ship = "~" + this.props.ship;
let emailTest = new RegExp(''
+ /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*/.source
+ /@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/.source
);
let phoneTest = new RegExp(''
+ /^\s*(?:\+?(\d{1,3}))?/.source
+ /([-. (]*(\d{3})[-. )]*)?((\d{3})[-. ]*(\d{2,4})(?:[-.x ]*(\d+))?)\s*$/.source
);
let websiteTest = new RegExp(''
+ /[(http(s)?):\/\/(www\.)?a-zA-Z0-9@:%._\+~#=]{2,256}/.source
+ /\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/.source
);
switch (field) { switch (field) {
case "email": {
if ((this.state.emailToSet === "")
|| (this.state.emailToSet === this.props.contact.email)) {
return false;
}
let emailTestResult = emailTest.exec(this.state.emailToSet);
if (emailTestResult) {
api.contactEdit(this.props.path, ship, { email: this.state.emailToSet });
}
break;
}
case "nickname": { case "nickname": {
if ((this.state.nickNameToSet === "") if ((this.state.nickNameToSet === "")
|| (this.state.nickNameToSet === this.props.contact.nickname)) { || (this.state.nickNameToSet === this.props.contact.nickname)) {
return false; return false;
} }
api.contactEdit(this.props.path, ship, { nickname: this.state.nickNameToSet }); api.contactEdit(this.props.path, ship, { nickname: this.state.nickNameToSet });
break; break;
} }
case "notes": {
if ((this.state.notesToSet === "")
|| (this.state.notesToSet === this.props.contact.notes)) {
return false;
}
api.contactEdit(this.props.path, ship, { notes: this.state.notesToSet });
break;
}
case "phone": {
if ((this.state.phoneToSet === "")
|| (this.state.phoneToSet === this.props.contact.phone)) {
return false;
}
let phoneTestResult = phoneTest.exec(this.state.phoneToSet);
if (phoneTestResult) {
api.contactEdit(this.props.path, ship, { phone: this.state.phoneToSet });
}
break;
}
case "website": {
if ((this.state.websiteToSet === "")
|| (this.state.websiteToSet === this.props.contact.website)) {
return false;
}
let websiteTestResult = websiteTest.exec(this.state.websiteToSet);
if (websiteTestResult) {
api.contactEdit(this.props.path, ship, { website: this.state.websiteToSet });
}
break;
}
case "removeAvatar": { case "removeAvatar": {
api.contactEdit(this.props.path, ship, { avatar: null }); api.contactEdit(this.props.path, ship, { avatar: null });
break; break;
} }
case "removeEmail": {
this.setState({ emailToSet: "" });
api.contactEdit(this.props.path, ship, { email: "" });
this.refs.email.value = "";
break;
}
case "removeNickname": {
this.setState({ nicknameToSet: "" });
api.contactEdit(this.props.path, ship, { nickname: "" });
this.refs.nickname.value = "";
break;
}
case "removePhone": {
this.setState({ phoneToSet: "" });
api.contactEdit(this.props.path, ship, { phone: "" });
this.refs.phone.value = "";
break;
}
case "removeWebsite": {
this.setState({ websiteToSet: "" });
api.contactEdit(this.props.path, ship, { website: "" });
this.refs.website.value = "";
break;
}
case "removeNotes": {
this.setState({ notesToSet: "" });
api.contactEdit(this.props.path, ship, { notes: "" });
this.refs.notes.value = "";
break;
}
} }
} }
sigilColorSet(event) {
this.setState({ colorToSet: event.target.value });
}
renderEditCard() { renderEditCard() {
// if this is our first edit in a new group, propagate from root identity
let defaultValue = { let defaultValue = {
nickname: (this.props.share) nickname: (this.props.share)
? this.props.rootIdentity.nickname ? this.props.rootIdentity.nickname
@ -63175,7 +63287,7 @@ lyrtesmudnytbyrsenwegfyrmurtelreptegpecnelnevfes\
: this.props.contact.phone, : this.props.contact.phone,
website: (this.props.share) website: (this.props.share)
? this.props.rootIdentity.website ? this.props.rootIdentity.website
: this.props.contact.phone, : this.props.contact.website,
notes: (this.props.share) notes: (this.props.share)
? this.props.rootIdentity.notes ? this.props.rootIdentity.notes
: this.props.contact.notes : this.props.contact.notes
@ -63183,16 +63295,21 @@ lyrtesmudnytbyrsenwegfyrmurtelreptegpecnelnevfes\
let shipType = this.shipParser(this.props.ship); let shipType = this.shipParser(this.props.ship);
let currentColor = (this.props.contact.color) ? this.props.contact.color : "0x0"; let currentColor = (this.props.contact.color)
? this.props.contact.color
: "0x0";
let hexColor = uxToHex(currentColor); let hexColor = uxToHex(currentColor);
let sigilColor = ""; let sigilColor = "";
let hasAvatar = (this.props.contact.avatar !== "TODO");
if (!hasAvatar) { if (!hasAvatar) {
sigilColor = ( sigilColor = (
react.createElement('div', { className: "tl mt4 mb4 w-auto ml-auto mr-auto" , react.createElement('div', { className: "tl mt4 mb4 w-auto ml-auto mr-auto" ,
style: { width: "fit-content" }, __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 106}} style: { width: "fit-content" }, __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 223}}
, react.createElement('p', { className: "f9 gray2 lh-copy" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 108}}, "Sigil Color" ) , react.createElement('p', { className: "f9 gray2 lh-copy" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 225}}, "Sigil Color" )
, react.createElement('textarea', { , react.createElement('textarea', {
className: "b--gray4 black f7 ba db pl2" , className: "b--gray4 black f7 ba db pl2" ,
onChange: this.sigilColorSet, onChange: this.sigilColorSet,
@ -63202,22 +63319,21 @@ lyrtesmudnytbyrsenwegfyrmurtelreptegpecnelnevfes\
height: 40, height: 40,
paddingTop: 10, paddingTop: 10,
width: 114 width: 114
}, __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 109}}) }, __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 226}})
) )
); );
//TODO The fields to actually edit, using the api hooks for those atomic actions
} }
let removeImage = ""; let removeImage = "";
let avatar = (hasAvatar) let avatar = (hasAvatar)
? react.createElement('img', { className: "dib h-auto" , width: 128, src: this.props.contact.avatar, __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 126}} ) ? react.createElement('img', { className: "dib h-auto" , width: 128, src: this.props.contact.avatar, __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 242}} )
: react.createElement(Sigil, { ship: this.props.ship, size: 128, color: "#" + hexColor, __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 127}} ); : react.createElement(Sigil, { ship: this.props.ship, size: 128, color: "#" + hexColor, __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 243}} );
if (hasAvatar) { if (hasAvatar) {
removeImage = ( removeImage = (
react.createElement('div', {__self: this, __source: {fileName: _jsxFileName$a, lineNumber: 131}} react.createElement('div', {__self: this, __source: {fileName: _jsxFileName$a, lineNumber: 247}}
, react.createElement('button', { class: "f9 black pointer db" , , react.createElement('button', { class: "f9 black pointer db" ,
onClick: () => this.setField("removeAvatar"), __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 132}}, "Remove photo" onClick: () => this.setField("removeAvatar"), __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 248}}, "Remove photo"
) )
) )
@ -63225,47 +63341,153 @@ lyrtesmudnytbyrsenwegfyrmurtelreptegpecnelnevfes\
} }
return ( return (
react.createElement('div', { className: "w-100 flex justify-center pa4 pa0-xl pt4-xl" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 141}} react.createElement('div', { className: "w-100 mt8 flex justify-center pa4 pt8 pt0-l pa0-xl pt4-xl" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 257}}
, react.createElement('div', { className: "w-100 mw6 tc" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 142}} , react.createElement('div', { className: "w-100 mw6 tc" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 258}}
, avatar , avatar
, sigilColor , sigilColor
, react.createElement('button', { className: "f9 b--black ba pa2" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 145}}, "Upload an Image" ) , react.createElement('button', { className: "f9 b--black ba pa2" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 261}}, "Upload an Image" )
, removeImage , removeImage
, react.createElement('div', { className: "w-100 pt8 lh-copy tl" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 148}} , react.createElement('div', { className: "w-100 pt8 lh-copy tl" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 264}}
, react.createElement('p', { className: "f9 gray2" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 149}}, "Ship Name" ) , react.createElement('p', { className: "f9 gray2" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 265}}, "Ship Name" )
, react.createElement('p', { className: "f8 mono" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 150}}, "~", this.props.ship) , react.createElement('p', { className: "f8 mono" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 266}}, "~", this.props.ship)
, react.createElement('p', { className: "f9 gray2 mt3" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 151}}, "Ship Type" ) , react.createElement('p', { className: "f9 gray2 mt3" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 267}}, "Ship Type" )
, react.createElement('p', { className: "f8", __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 152}}, shipType) , react.createElement('p', { className: "f8", __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 268}}, shipType)
, react.createElement('hr', { className: "mv8 gray4 b--gray4 bb-0 b--solid" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 154}} ) , react.createElement('hr', { className: "mv8 gray4 b--gray4 bb-0 b--solid" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 270}} )
, react.createElement('p', { className: "f9 gray2" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 155}}, "Nickname")
, react.createElement('div', { className: "w-100 flex" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 156}} , react.createElement('p', { className: "f9 gray2" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 272}}, "Nickname")
, react.createElement('div', { className: "w-100 flex" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 273}}
, react.createElement('textarea', { , react.createElement('textarea', {
ref: "nickname",
className: "w-100 ba pl3 b--gray4" , className: "w-100 ba pl3 b--gray4" ,
style: { resize: "none", style: { resize: "none",
height: 40, height: 40,
paddingTop: 10 }, paddingTop: 10 },
onChange: this.nickNameToSet, onChange: this.nickNameToSet,
defaultValue: defaultValue.nickname, __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 157}} defaultValue: defaultValue.nickname, __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 274}})
) , react.createElement('button', { className: "f9 pointer ml3 ba pa2 pl3 pr3 b--red2 red2 " +
, react.createElement('button', { className: "f9 ml3 ba pa2 pl3 pr3 b--red2 red2 " + ((this.props.contact.nickname === "") ? "dn" : "dib"),
((this.props.contact.nickname === "") ? "dn" : "dib"), __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 165}}, "Delete" onClick: () => this.setField("removeNickname"), __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 282}}, "Delete"
) )
) )
, react.createElement('button', { className: "db mv2 f9 ba pa2 pl3 pr3 " + , react.createElement('button', { className: "pointer db mv2 f9 ba pa2 pl3 pr3 " +
(((this.props.contact.nickname === this.state.nickNameToSet) (((this.props.contact.nickname === this.state.nickNameToSet)
|| (this.state.nickNameToSet === "")) || (this.state.nickNameToSet === ""))
? "b--gray4 gray4" ? "b--gray4 gray4"
: "b--black"), : "b--black"),
onClick: () => this.setField("nickname"), __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 170}}, "Save" onClick: () => this.setField("nickname"), __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 288}}, "Save"
)
, react.createElement('p', { className: "f9 gray2" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 297}}, "Email")
, react.createElement('div', { className: "w-100 flex" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 298}}
, react.createElement('textarea', {
ref: "email",
className: "w-100 ba pl3 b--gray4" ,
style: {
resize: "none",
height: 40,
paddingTop: 10
},
onChange: this.emailToSet,
defaultValue: defaultValue.email, __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 299}} )
, react.createElement('button', { className: "f9 pointer ml3 ba pa2 pl3 pr3 b--red2 red2 " +
((this.props.contact.email === "") ? "dn" : "dib"),
onClick: () => this.setField("removeEmail"), __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 309}}, "Delete"
)
)
, react.createElement('button', { className: "pointer db mv2 f9 ba pa2 pl3 pr3 " +
(((this.props.contact.email === this.state.emailToSet)
|| (this.state.emailToSet === ""))
? "b--gray4 gray4"
: "b--black"),
onClick: () => this.setField("email"), __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 315}}, "Save"
)
, react.createElement('p', { className: "f9 gray2" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 324}}, "Phone")
, react.createElement('div', { className: "w-100 flex" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 325}}
, react.createElement('textarea', {
ref: "phone",
className: "w-100 ba pl3 b--gray4" ,
style: {
resize: "none",
height: 40,
paddingTop: 10
},
onChange: this.phoneToSet,
defaultValue: defaultValue.phone, __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 326}} )
, react.createElement('button', { className: "f9 pointer ml3 ba pa2 pl3 pr3 b--red2 red2 " +
((this.props.contact.phone === "") ? "dn" : "dib"),
onClick: () => this.setField("removePhone"), __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 336}}, "Delete"
)
)
, react.createElement('button', { className: "pointer db mv2 f9 ba pa2 pl3 pr3 " +
(((this.props.contact.phone === this.state.phoneToSet)
|| (this.state.phoneToSet === ""))
? "b--gray4 gray4"
: "b--black"),
onClick: () => this.setField("phone"), __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 342}}, "Save"
)
, react.createElement('p', { className: "f9 gray2" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 351}}, "Website")
, react.createElement('div', { className: "w-100 flex" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 352}}
, react.createElement('textarea', {
ref: "website",
className: "w-100 ba pl3 b--gray4" ,
style: {
resize: "none",
height: 40,
paddingTop: 10
},
onChange: this.websiteToSet,
defaultValue: defaultValue.website, __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 353}} )
, react.createElement('button', { className: "f9 pointer ml3 ba pa2 pl3 pr3 b--red2 red2 " +
((this.props.contact.website === "") ? "dn" : "dib"),
onClick: () => this.setField("removeWebsite"), __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 363}}, "Delete"
)
)
, react.createElement('button', { className: "pointer db mv2 f9 ba pa2 pl3 pr3 " +
(((this.props.contact.website === this.state.websiteToSet)
|| (this.state.websitetoSet === ""))
? "b--gray4 gray4"
: "b--black"),
onClick: () => this.setField("website"), __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 369}}, "Save"
)
, react.createElement('p', { className: "f9 gray2" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 378}}, "Notes")
, react.createElement('div', { className: "w-100 flex" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 379}}
, react.createElement('textarea', {
ref: "notes",
className: "w-100 ba pl3 b--gray4" ,
style: {
resize: "none",
height: 40,
paddingTop: 10
},
onChange: this.notesToSet,
defaultValue: defaultValue.notes, __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 380}} )
, react.createElement('button', { className: "f9 pointer ml3 ba pa2 pl3 pr3 b--red2 red2 " +
((this.props.contact.notes === "") ? "dn" : "dib"),
onClick: () => this.setField("removeNotes"), __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 390}}, "Delete"
)
)
, react.createElement('button', { className: "pointer db mv2 f9 ba pa2 pl3 pr3 " +
(((this.props.contact.notes === this.state.notesToSet)
|| (this.state.notesToSet === ""))
? "b--gray4 gray4"
: "b--black"),
onClick: () => this.setField("notes"), __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 396}}, "Save"
) )
, react.createElement('p', { className: "f9 gray2" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 178}}, "Email")
, react.createElement('p', { className: "f9 gray2" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 179}}, "Phone")
, react.createElement('p', { className: "f9 gray2" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 180}}, "Website")
, react.createElement('p', { className: "f9 gray2" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 181}}, "Notes")
) )
) )
@ -63278,63 +63500,76 @@ lyrtesmudnytbyrsenwegfyrmurtelreptegpecnelnevfes\
let currentColor = (this.props.contact.color) ? this.props.contact.color : "0x0"; let currentColor = (this.props.contact.color) ? this.props.contact.color : "0x0";
let hexColor = uxToHex(currentColor); let hexColor = uxToHex(currentColor);
const hasAvatar = (this.props.contact.avatar !== "TODO"); let hasAvatar = (this.props.contact.avatar !== "TODO");
let avatar = (hasAvatar) let avatar = (hasAvatar)
? react.createElement('img', { className: "dib h-auto" , width: 128, src: this.props.contact.avatar, __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 197}} ) ? react.createElement('img', { className: "dib h-auto" , width: 128, src: this.props.contact.avatar, __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 419}} )
: react.createElement(Sigil, { ship: this.props.ship, size: 128, color: "#" + hexColor, __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 198}} ); : react.createElement(Sigil, { ship: this.props.ship, size: 128, color: "#" + hexColor, __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 420}} );
return ( return (
react.createElement('div', { className: "w-100 flex justify-center pa4 pa0-xl pt4-xl" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 201}} react.createElement('div', { className: "w-100 mt8 flex justify-center pa4 pt8 pt0-l pa0-xl pt4-xl" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 423}}
, react.createElement('div', { className: "w-100 mw6 tc" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 202}} , react.createElement('div', { className: "w-100 mw6 tc" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 424}}
, avatar , avatar
, react.createElement('div', { className: "w-100 pt8 lh-copy tl" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 204}} , react.createElement('div', { className: "w-100 pt8 lh-copy tl" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 426}}
, react.createElement('p', { className: "f9 gray2" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 205}}, "Ship Name" ) , react.createElement('p', { className: "f9 gray2" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 427}}, "Ship Name" )
, react.createElement('p', { className: "f8 mono" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 206}}, "~", this.props.ship) , react.createElement('p', { className: "f8 mono" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 428}}, "~", this.props.ship)
, react.createElement('p', { className: "f9 gray2 mt3" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 207}}, "Ship Type" ) , react.createElement('p', { className: "f9 gray2 mt3" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 429}}, "Ship Type" )
, react.createElement('p', { className: "f8", __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 208}}, shipType) , react.createElement('p', { className: "f8", __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 430}}, shipType)
, react.createElement('hr', { className: "mv8 gray4 b--gray4 bb-0 b--solid" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 210}} ) , react.createElement('hr', { className: "mv8 gray4 b--gray4 bb-0 b--solid" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 432}} )
, react.createElement('div', {__self: this, __source: {fileName: _jsxFileName$a, lineNumber: 211}} , react.createElement('div', {__self: this, __source: {fileName: _jsxFileName$a, lineNumber: 433}}
, (() => { , (() => {
if (this.props.contact.nickname) { if (this.props.contact.nickname) {
return ( return (
react.createElement('div', {__self: this, __source: {fileName: _jsxFileName$a, lineNumber: 215}} react.createElement('div', {__self: this, __source: {fileName: _jsxFileName$a, lineNumber: 437}}
, react.createElement('p', { className: "f9 gray2" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 216}}, "Nickname") , react.createElement('p', { className: "f9 gray2" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 438}}, "Nickname")
, react.createElement('p', { className: "f8", __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 217}}, this.props.contact.nickname) , react.createElement('p', { className: "f8", __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 439}}, this.props.contact.nickname)
) )
) )
} }
})()
, (() => {
if (this.props.contact.email) { if (this.props.contact.email) {
return ( return (
react.createElement('div', {__self: this, __source: {fileName: _jsxFileName$a, lineNumber: 224}} react.createElement('div', {__self: this, __source: {fileName: _jsxFileName$a, lineNumber: 447}}
, react.createElement('p', { className: "f9 gray2" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 225}}, "Email") , react.createElement('p', { className: "f9 mt6 gray2" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 448}}, "Email")
, react.createElement('p', { className: "f8", __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 226}}, this.props.contact.email) , react.createElement('p', { className: "f8", __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 449}}, this.props.contact.email)
) )
) )
} }
})()
, (() => {
if (this.props.contact.phone) { if (this.props.contact.phone) {
return ( return (
react.createElement('div', {__self: this, __source: {fileName: _jsxFileName$a, lineNumber: 232}} react.createElement('div', {__self: this, __source: {fileName: _jsxFileName$a, lineNumber: 457}}
, react.createElement('p', { className: "f9 gray2" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 233}}, "Phone") , react.createElement('p', { className: "f9 mt6 gray2" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 458}}, "Phone")
, react.createElement('p', { className: "f8", __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 234}}, this.props.contact.phone) , react.createElement('p', { className: "f8", __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 459}}, this.props.contact.phone)
) )
) )
} }
})()
, (() => {
if (this.props.contact.website) { if (this.props.contact.website) {
let href = (this.props.contact.website.includes("://"))
? this.props.contact.website
: "http://" + this.props.contact.website;
return ( return (
react.createElement('div', {__self: this, __source: {fileName: _jsxFileName$a, lineNumber: 240}} react.createElement('div', {__self: this, __source: {fileName: _jsxFileName$a, lineNumber: 472}}
, react.createElement('p', { className: "f9 gray2" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 241}}, "Website") , react.createElement('p', { className: "f9 mt6 gray2" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 473}}, "Website")
, react.createElement('a', { className: "bb b--black f8" , href: this.props.contact.website, __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 242}}, this.props.contact.website) , react.createElement('a', { target: "_blank", className: "bb b--black f8" ,
href: href, __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 474}}, this.props.contact.website)
) )
) )
} }
})()
, (() => {
if (this.props.contact.notes) { if (this.props.contact.notes) {
return ( return (
react.createElement('div', {__self: this, __source: {fileName: _jsxFileName$a, lineNumber: 248}} react.createElement('div', {__self: this, __source: {fileName: _jsxFileName$a, lineNumber: 483}}
, react.createElement('p', { className: "f9 gray2" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 249}}, "Notes") , react.createElement('p', { className: "f9 mt6 gray2" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 484}}, "Notes")
, react.createElement('p', { className: "f8", __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 250}}, this.props.contact.notes) , react.createElement('p', { className: "f8", __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 485}}, this.props.contact.notes)
) )
) )
} }
@ -63370,21 +63605,22 @@ lyrtesmudnytbyrsenwegfyrmurtelreptegpecnelnevfes\
//TODO "Share card" if it's /me -> sends to /~/default of recipient //TODO "Share card" if it's /me -> sends to /~/default of recipient
return ( return (
react.createElement('div', { className: "h-100 w-100 overflow-x-hidden" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 286}} react.createElement('div', { className: "h-100 w-100 overflow-x-hidden" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 521}}
, react.createElement('div', { className: "w-100 h2 dn-m dn-l dn-xl inter pb6 pl3 pt3 f8" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 287}}
, react.createElement(Link, { to: "/~contacts/", __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 288}}, "⟵") , react.createElement('div', { className: "w-100 bg-white fixed bb b--gray4" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 523}}
) , react.createElement('div', { className: "w-100 h2 dn-m dn-l dn-xl inter pb6 pl3 pt3 f8" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 524}}
, react.createElement('div', { className: "w-100 bb b--gray4" , __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 290}} , react.createElement(Link, { to: "/~contacts/", __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 525}}, "⟵")
)
, react.createElement('button', { , react.createElement('button', {
onClick: this.editToggle, onClick: this.editToggle,
className: `ml3 mt2 mb2 f9 pa2 ba br3 pointer b--black ` + ourOption, __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 291}} className: `ml3 mt2 mb2 f9 pa1 ba br2 pointer b--black ` + ourOption, __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 527}}
, editInfoText , editInfoText
) )
, react.createElement('button', { className: `ml3 mt2 mb2 f9 pa2 ba br3 b--black ` + localOption, __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 296}}, "Share Contact Info" , react.createElement('button', { className: `ml3 mt2 mb2 f9 pa1 ba br2 b--black ` + localOption, __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 532}}, "Share Contact Info"
) )
, react.createElement('button', { className: `ml3 mt2 mb2 f9 pa2 ba red2 br3 b--red2 ` + adminOption, , react.createElement('button', { className: `ml3 mt2 mb2 f9 pa1 ba red2 br2 b--red2 ` + adminOption,
onClick: this.removeContact, __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 299}}, "Remove from Group" onClick: this.removeContact, __self: this, __source: {fileName: _jsxFileName$a, lineNumber: 535}}, "Remove from Group"
) )
) )

View File

@ -11,16 +11,26 @@ export class ContactCard extends Component {
this.state = { this.state = {
edit: false, edit: false,
colorToSet: "", colorToSet: "",
nickNameToSet: "" nickNameToSet: "",
emailToSet: "",
phoneToSet: "",
websiteToSet: "",
notesToSet: ""
} }
this.editToggle = this.editToggle.bind(this); this.editToggle = this.editToggle.bind(this);
this.sigilColorSet = this.sigilColorSet.bind(this); this.sigilColorSet = this.sigilColorSet.bind(this);
this.nickNameToSet = this.nickNameToSet.bind(this); this.nickNameToSet = this.nickNameToSet.bind(this);
this.emailToSet = this.emailToSet.bind(this);
this.phoneToSet = this.phoneToSet.bind(this);
this.websiteToSet = this.websiteToSet.bind(this);
this.notesToSet = this.notesToSet.bind(this);
this.setField = this.setField.bind(this); this.setField = this.setField.bind(this);
} }
componentDidUpdate() { componentDidUpdate() {
// sigil color updates are done by keystroke parsing on update
// other field edits are exclusively handled by setField()
let currentColor = (this.props.contact.color) ? this.props.contact.color : "0x0"; let currentColor = (this.props.contact.color) ? this.props.contact.color : "0x0";
let currentHex = uxToHex(currentColor); let currentHex = uxToHex(currentColor);
let hexExp = /#?([0-9A-Fa-f]{6})/ let hexExp = /#?([0-9A-Fa-f]{6})/
@ -38,10 +48,30 @@ export class ContactCard extends Component {
this.setState({edit: editSwitch}); this.setState({edit: editSwitch});
} }
emailToSet(event) {
this.setState({ emailToSet: event.target.value });
}
nickNameToSet(event) { nickNameToSet(event) {
this.setState({ nickNameToSet: event.target.value }); this.setState({ nickNameToSet: event.target.value });
} }
notesToSet(event) {
this.setState({ notesToSet: event.target.value });
}
phoneToSet(event) {
this.setState({ phoneToSet: event.target.value });
}
sigilColorSet(event) {
this.setState({ colorToSet: event.target.value });
}
websiteToSet(event) {
this.setState({ websiteToSet: event.target.value });
}
shipParser(ship) { shipParser(ship) {
switch (ship.length) { switch (ship.length) {
case 3: return "Galaxy"; case 3: return "Galaxy";
@ -54,28 +84,110 @@ export class ContactCard extends Component {
setField(field) { setField(field) {
let ship = "~" + this.props.ship; let ship = "~" + this.props.ship;
let emailTest = new RegExp(''
+ /[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*/.source
+ /@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?/.source
);
let phoneTest = new RegExp(''
+ /^\s*(?:\+?(\d{1,3}))?/.source
+ /([-. (]*(\d{3})[-. )]*)?((\d{3})[-. ]*(\d{2,4})(?:[-.x ]*(\d+))?)\s*$/.source
);
let websiteTest = new RegExp(''
+ /[(http(s)?):\/\/(www\.)?a-zA-Z0-9@:%._\+~#=]{2,256}/.source
+ /\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/.source
);
switch (field) { switch (field) {
case "email": {
if ((this.state.emailToSet === "")
|| (this.state.emailToSet === this.props.contact.email)) {
return false;
}
let emailTestResult = emailTest.exec(this.state.emailToSet);
if (emailTestResult) {
api.contactEdit(this.props.path, ship, { email: this.state.emailToSet });
}
break;
}
case "nickname": { case "nickname": {
if ((this.state.nickNameToSet === "") if ((this.state.nickNameToSet === "")
|| (this.state.nickNameToSet === this.props.contact.nickname)) { || (this.state.nickNameToSet === this.props.contact.nickname)) {
return false; return false;
} }
api.contactEdit(this.props.path, ship, { nickname: this.state.nickNameToSet }); api.contactEdit(this.props.path, ship, { nickname: this.state.nickNameToSet });
break; break;
} }
case "notes": {
if ((this.state.notesToSet === "")
|| (this.state.notesToSet === this.props.contact.notes)) {
return false;
}
api.contactEdit(this.props.path, ship, { notes: this.state.notesToSet });
break;
}
case "phone": {
if ((this.state.phoneToSet === "")
|| (this.state.phoneToSet === this.props.contact.phone)) {
return false;
}
let phoneTestResult = phoneTest.exec(this.state.phoneToSet);
if (phoneTestResult) {
api.contactEdit(this.props.path, ship, { phone: this.state.phoneToSet });
}
break;
}
case "website": {
if ((this.state.websiteToSet === "")
|| (this.state.websiteToSet === this.props.contact.website)) {
return false;
}
let websiteTestResult = websiteTest.exec(this.state.websiteToSet);
if (websiteTestResult) {
api.contactEdit(this.props.path, ship, { website: this.state.websiteToSet });
}
break;
}
case "removeAvatar": { case "removeAvatar": {
api.contactEdit(this.props.path, ship, { avatar: null }); api.contactEdit(this.props.path, ship, { avatar: null });
break; break;
} }
case "removeEmail": {
this.setState({ emailToSet: "" });
api.contactEdit(this.props.path, ship, { email: "" });
this.refs.email.value = "";
break;
}
case "removeNickname": {
this.setState({ nicknameToSet: "" });
api.contactEdit(this.props.path, ship, { nickname: "" });
this.refs.nickname.value = "";
break;
}
case "removePhone": {
this.setState({ phoneToSet: "" });
api.contactEdit(this.props.path, ship, { phone: "" });
this.refs.phone.value = "";
break;
}
case "removeWebsite": {
this.setState({ websiteToSet: "" });
api.contactEdit(this.props.path, ship, { website: "" });
this.refs.website.value = "";
break;
}
case "removeNotes": {
this.setState({ notesToSet: "" });
api.contactEdit(this.props.path, ship, { notes: "" });
this.refs.notes.value = "";
break;
}
} }
} }
sigilColorSet(event) {
this.setState({ colorToSet: event.target.value });
}
renderEditCard() { renderEditCard() {
// if this is our first edit in a new group, propagate from root identity
let defaultValue = { let defaultValue = {
nickname: (this.props.share) nickname: (this.props.share)
? this.props.rootIdentity.nickname ? this.props.rootIdentity.nickname
@ -88,7 +200,7 @@ export class ContactCard extends Component {
: this.props.contact.phone, : this.props.contact.phone,
website: (this.props.share) website: (this.props.share)
? this.props.rootIdentity.website ? this.props.rootIdentity.website
: this.props.contact.phone, : this.props.contact.website,
notes: (this.props.share) notes: (this.props.share)
? this.props.rootIdentity.notes ? this.props.rootIdentity.notes
: this.props.contact.notes : this.props.contact.notes
@ -96,10 +208,15 @@ export class ContactCard extends Component {
let shipType = this.shipParser(this.props.ship); let shipType = this.shipParser(this.props.ship);
let currentColor = (this.props.contact.color) ? this.props.contact.color : "0x0"; let currentColor = (this.props.contact.color)
? this.props.contact.color
: "0x0";
let hexColor = uxToHex(currentColor); let hexColor = uxToHex(currentColor);
let sigilColor = "" let sigilColor = "";
let hasAvatar = (this.props.contact.avatar !== "TODO");
if (!hasAvatar) { if (!hasAvatar) {
sigilColor = ( sigilColor = (
@ -118,7 +235,6 @@ export class ContactCard extends Component {
}}></textarea> }}></textarea>
</div> </div>
) )
//TODO The fields to actually edit, using the api hooks for those atomic actions
} }
let removeImage = ""; let removeImage = "";
@ -138,7 +254,7 @@ export class ContactCard extends Component {
} }
return ( return (
<div className="w-100 flex justify-center pa4 pa0-xl pt4-xl"> <div className="w-100 mt8 flex justify-center pa4 pt8 pt0-l pa0-xl pt4-xl">
<div className="w-100 mw6 tc"> <div className="w-100 mw6 tc">
{avatar} {avatar}
{sigilColor} {sigilColor}
@ -152,22 +268,24 @@ export class ContactCard extends Component {
<p className="f8">{shipType}</p> <p className="f8">{shipType}</p>
<hr className="mv8 gray4 b--gray4 bb-0 b--solid" /> <hr className="mv8 gray4 b--gray4 bb-0 b--solid" />
<p className="f9 gray2">Nickname</p> <p className="f9 gray2">Nickname</p>
<div className="w-100 flex"> <div className="w-100 flex">
<textarea <textarea
ref="nickname"
className="w-100 ba pl3 b--gray4" className="w-100 ba pl3 b--gray4"
style={{ resize: "none", style={{ resize: "none",
height: 40, height: 40,
paddingTop: 10 }} paddingTop: 10 }}
onChange={this.nickNameToSet} onChange={this.nickNameToSet}
defaultValue={defaultValue.nickname} defaultValue={defaultValue.nickname}/>
/> <button className={"f9 pointer ml3 ba pa2 pl3 pr3 b--red2 red2 " +
<button className={"f9 ml3 ba pa2 pl3 pr3 b--red2 red2 " + ((this.props.contact.nickname === "") ? "dn" : "dib")}
((this.props.contact.nickname === "") ? "dn" : "dib")}> onClick={() => this.setField("removeNickname")}>
Delete Delete
</button> </button>
</div> </div>
<button className={"db mv2 f9 ba pa2 pl3 pr3 " + <button className={"pointer db mv2 f9 ba pa2 pl3 pr3 " +
(((this.props.contact.nickname === this.state.nickNameToSet) (((this.props.contact.nickname === this.state.nickNameToSet)
|| (this.state.nickNameToSet === "")) || (this.state.nickNameToSet === ""))
? "b--gray4 gray4" ? "b--gray4 gray4"
@ -175,10 +293,114 @@ export class ContactCard extends Component {
onClick={() => this.setField("nickname")}> onClick={() => this.setField("nickname")}>
Save Save
</button> </button>
<p className="f9 gray2">Email</p> <p className="f9 gray2">Email</p>
<div className="w-100 flex">
<textarea
ref="email"
className="w-100 ba pl3 b--gray4"
style={{
resize: "none",
height: 40,
paddingTop: 10
}}
onChange={this.emailToSet}
defaultValue={defaultValue.email} />
<button className={"f9 pointer ml3 ba pa2 pl3 pr3 b--red2 red2 " +
((this.props.contact.email === "") ? "dn" : "dib")}
onClick={() => this.setField("removeEmail")}>
Delete
</button>
</div>
<button className={"pointer db mv2 f9 ba pa2 pl3 pr3 " +
(((this.props.contact.email === this.state.emailToSet)
|| (this.state.emailToSet === ""))
? "b--gray4 gray4"
: "b--black")}
onClick={() => this.setField("email")}>
Save
</button>
<p className="f9 gray2">Phone</p> <p className="f9 gray2">Phone</p>
<div className="w-100 flex">
<textarea
ref="phone"
className="w-100 ba pl3 b--gray4"
style={{
resize: "none",
height: 40,
paddingTop: 10
}}
onChange={this.phoneToSet}
defaultValue={defaultValue.phone} />
<button className={"f9 pointer ml3 ba pa2 pl3 pr3 b--red2 red2 " +
((this.props.contact.phone === "") ? "dn" : "dib")}
onClick={() => this.setField("removePhone")}>
Delete
</button>
</div>
<button className={"pointer db mv2 f9 ba pa2 pl3 pr3 " +
(((this.props.contact.phone === this.state.phoneToSet)
|| (this.state.phoneToSet === ""))
? "b--gray4 gray4"
: "b--black")}
onClick={() => this.setField("phone")}>
Save
</button>
<p className="f9 gray2">Website</p> <p className="f9 gray2">Website</p>
<div className="w-100 flex">
<textarea
ref="website"
className="w-100 ba pl3 b--gray4"
style={{
resize: "none",
height: 40,
paddingTop: 10
}}
onChange={this.websiteToSet}
defaultValue={defaultValue.website} />
<button className={"f9 pointer ml3 ba pa2 pl3 pr3 b--red2 red2 " +
((this.props.contact.website === "") ? "dn" : "dib")}
onClick={() => this.setField("removeWebsite")}>
Delete
</button>
</div>
<button className={"pointer db mv2 f9 ba pa2 pl3 pr3 " +
(((this.props.contact.website === this.state.websiteToSet)
|| (this.state.websitetoSet === ""))
? "b--gray4 gray4"
: "b--black")}
onClick={() => this.setField("website")}>
Save
</button>
<p className="f9 gray2">Notes</p> <p className="f9 gray2">Notes</p>
<div className="w-100 flex">
<textarea
ref="notes"
className="w-100 ba pl3 b--gray4"
style={{
resize: "none",
height: 40,
paddingTop: 10
}}
onChange={this.notesToSet}
defaultValue={defaultValue.notes} />
<button className={"f9 pointer ml3 ba pa2 pl3 pr3 b--red2 red2 " +
((this.props.contact.notes === "") ? "dn" : "dib")}
onClick={() => this.setField("removeNotes")}>
Delete
</button>
</div>
<button className={"pointer db mv2 f9 ba pa2 pl3 pr3 " +
(((this.props.contact.notes === this.state.notesToSet)
|| (this.state.notesToSet === ""))
? "b--gray4 gray4"
: "b--black")}
onClick={() => this.setField("notes")}>
Save
</button>
</div> </div>
</div> </div>
@ -191,14 +413,14 @@ export class ContactCard extends Component {
let currentColor = (this.props.contact.color) ? this.props.contact.color : "0x0"; let currentColor = (this.props.contact.color) ? this.props.contact.color : "0x0";
let hexColor = uxToHex(currentColor); let hexColor = uxToHex(currentColor);
const hasAvatar = (this.props.contact.avatar !== "TODO"); let hasAvatar = (this.props.contact.avatar !== "TODO");
let avatar = (hasAvatar) let avatar = (hasAvatar)
? <img className="dib h-auto" width={128} src={this.props.contact.avatar} /> ? <img className="dib h-auto" width={128} src={this.props.contact.avatar} />
: <Sigil ship={this.props.ship} size={128} color={"#" + hexColor} />; : <Sigil ship={this.props.ship} size={128} color={"#" + hexColor} />;
return ( return (
<div className="w-100 flex justify-center pa4 pa0-xl pt4-xl"> <div className="w-100 mt8 flex justify-center pa4 pt8 pt0-l pa0-xl pt4-xl">
<div className="w-100 mw6 tc"> <div className="w-100 mw6 tc">
{avatar} {avatar}
<div className="w-100 pt8 lh-copy tl"> <div className="w-100 pt8 lh-copy tl">
@ -218,35 +440,48 @@ export class ContactCard extends Component {
</div> </div>
) )
} }
})()}
{(() => {
if (this.props.contact.email) { if (this.props.contact.email) {
return ( return (
<div> <div>
<p className="f9 gray2">Email</p> <p className="f9 mt6 gray2">Email</p>
<p className="f8">{this.props.contact.email}</p> <p className="f8">{this.props.contact.email}</p>
</div> </div>
) )
} }
})()}
{(() => {
if (this.props.contact.phone) { if (this.props.contact.phone) {
return ( return (
<div> <div>
<p className="f9 gray2">Phone</p> <p className="f9 mt6 gray2">Phone</p>
<p className="f8">{this.props.contact.phone}</p> <p className="f8">{this.props.contact.phone}</p>
</div> </div>
) )
} }
})()}
{(() => {
if (this.props.contact.website) { if (this.props.contact.website) {
let href = (this.props.contact.website.includes("://"))
? this.props.contact.website
: "http://" + this.props.contact.website;
return ( return (
<div> <div>
<p className="f9 gray2">Website</p> <p className="f9 mt6 gray2">Website</p>
<a className="bb b--black f8" href={this.props.contact.website}>{this.props.contact.website}</a> <a target="_blank" className="bb b--black f8"
href={href}>{this.props.contact.website}</a>
</div> </div>
) )
} }
})()}
{(() => {
if (this.props.contact.notes) { if (this.props.contact.notes) {
return ( return (
<div> <div>
<p className="f9 gray2">Notes</p> <p className="f9 mt6 gray2">Notes</p>
<p className="f8">{this.props.contact.notes}</p> <p className="f8">{this.props.contact.notes}</p>
</div> </div>
) )
@ -284,19 +519,20 @@ export class ContactCard extends Component {
//TODO "Share card" if it's /me -> sends to /~/default of recipient //TODO "Share card" if it's /me -> sends to /~/default of recipient
return ( return (
<div className="h-100 w-100 overflow-x-hidden"> <div className="h-100 w-100 overflow-x-hidden">
<div className="w-100 h2 dn-m dn-l dn-xl inter pb6 pl3 pt3 f8">
<Link to="/~contacts/">{"⟵"}</Link> <div className="w-100 bg-white fixed bb b--gray4">
</div> <div className="w-100 h2 dn-m dn-l dn-xl inter pb6 pl3 pt3 f8">
<div className="w-100 bb b--gray4"> <Link to="/~contacts/">{"⟵"}</Link>
</div>
<button <button
onClick={this.editToggle} onClick={this.editToggle}
className={`ml3 mt2 mb2 f9 pa2 ba br3 pointer b--black ` + ourOption}> className={`ml3 mt2 mb2 f9 pa1 ba br2 pointer b--black ` + ourOption}>
{editInfoText} {editInfoText}
</button> </button>
<button className={`ml3 mt2 mb2 f9 pa2 ba br3 b--black ` + localOption}> <button className={`ml3 mt2 mb2 f9 pa1 ba br2 b--black ` + localOption}>
Share Contact Info Share Contact Info
</button> </button>
<button className={`ml3 mt2 mb2 f9 pa2 ba red2 br3 b--red2 ` + adminOption} <button className={`ml3 mt2 mb2 f9 pa1 ba red2 br2 b--red2 ` + adminOption}
onClick={this.removeContact}> onClick={this.removeContact}>
Remove from Group Remove from Group
</button> </button>