add / edit card.js toggle

This commit is contained in:
Matilde Park 2019-12-12 01:01:53 -05:00 committed by Logan Allen
parent 9e4a192fa5
commit 8ec9031be3
2 changed files with 270 additions and 96 deletions

View File

@ -1,10 +1,182 @@
import React, { Component } from 'react';
import { Sigil } from './icons/sigil';
import { uxToHex } from '/lib/util';
import { api } from '/api';
import { Route, Link } from 'react-router-dom';
export class ContactCard extends Component {
constructor() {
super();
this.state = {
edit: false,
colorToSet: ""
}
this.editToggle = this.editToggle.bind(this);
this.sigilColorSet = this.sigilColorSet.bind(this);
}
editToggle() {
let editSwitch = this.state.edit;
editSwitch = !editSwitch;
this.setState({edit: editSwitch});
}
sigilColorSet(event) {
//TODO regex for complete hex value and submit as change
this.setState({colorToSet: event.target.value});
}
shipParser(ship) {
switch(ship.length) {
case 3: return "Galaxy";
case 6: return "Star";
case 13: return "Planet";
case 56: return "Comet";
default: return "Unknown";
}
}
renderEditCard() {
//TODO if the path is our special invite flow path, autofill the details from /~/default's version of your contact, not this one
let shipType = this.shipParser(this.props.ship);
let currentColor = (this.props.contact.color) ? this.props.contact.color : "0x0";
let hexColor = uxToHex(currentColor);
let sigilColor = ""
if (this.props.contact.avatar === "TODO") { //TODO change to empty string once we have avatars
sigilColor = (
<div className="tl mt4 mb4 w-auto ml-auto mr-auto"
style={{ width: "fit-content" }}>
<p className="f9 gray2 lh-copy">Sigil Color</p>
<textarea
className="b--gray4 black f7 ba db pl2"
onChange={this.sigilColorSet}
defaultValue={"#" + hexColor}
style={{
resize: "none",
height: 48,
paddingTop: 14,
width: 114
}}></textarea>
</div>
)
//TODO The fields to actually edit, using the api hooks for those atomic actions
}
return (
<div className="w-100 flex justify-center pa4 pa0-xl pt4-xl">
<div className="w-100 mw6 tc">
<Sigil ship={this.props.ship} size={128} color={hexColor} />
{sigilColor}
<button className="f9 b--black ba pa2">Upload an Image</button>
<div className="w-100 pt8 lh-copy tl">
<p className="f9 gray2">Ship Name</p>
<p className="f8 mono">~{this.props.ship}</p>
<p className="f9 gray2 mt3">Ship Type</p>
<p className="f8">{shipType}</p>
<hr className="mv8 gray4 b--gray4 bb-0 b--solid" />
</div>
</div>
</div>
)
}
renderCard() {
let shipType = this.shipParser(this.props.ship);
let currentColor = (this.props.contact.color) ? this.props.contact.color : "0x0";
let hexColor = uxToHex(currentColor);
return (
<div className="w-100 flex justify-center pa4 pa0-xl pt4-xl">
<div className="w-100 mw6 tc">
{/*TODO default to sigil, but show avatar if exists for contact */}
<Sigil ship={this.props.ship} size={128} color={hexColor} />
<div className="w-100 pt8 lh-copy tl">
<p className="f9 gray2">Ship Name</p>
<p className="f8 mono">~{this.props.ship}</p>
<p className="f9 gray2 mt3">Ship Type</p>
<p className="f8">{shipType}</p>
<hr className="mv8 gray4 b--gray4 bb-0 b--solid" />
<div>
{(() => {
if (this.props.contact.nickname) {
return (
<div>
<p className="f9 gray2">Nickname</p>
<p className="f8">{this.props.contact.nickname}</p>
</div>
)
}
if (this.props.contact.email) {
return (
<div>
<p className="f9 gray2">Email</p>
<p className="f8">{this.props.contact.email}</p>
</div>
)
}
if (this.props.contact.phone) {
return (
<div>
<p className="f9 gray2">Phone</p>
<p className="f8">{this.props.contact.phone}</p>
</div>
)
}
if (this.props.contact.website) {
return (
<div>
<p className="f9 gray2">Website</p>
<p className="f8">{this.props.contact.website}</p>
</div>
)
}
if (this.props.contact.notes) {
return (
<div>
<p className="f9 gray2">Notes</p>
<p className="f8">{this.props.contact.notes}</p>
</div>
)
}
})()}
</div>
</div>
</div>
</div>
)
}
render() {
let ourOption = (this.props.ship === window.ship)
? "dib"
: "dn";
let localOption = ((this.props.ship === window.ship) && (this.props.path === "/~/default"))
? "dib"
: "dn";
let editInfoText = (this.state.edit)
? "Finish Editing"
: "Edit Contact Info";
let adminOption = (this.props.path.includes(window.ship) && (this.props.ship !== window.ship))
? "dib"
: "dn";
let card = (this.state.edit)
? this.renderEditCard()
: this.renderCard();
//TODO "Share card" if it's /me -> sends to /~/default of recipient
return (
<div className="h-100 w-100 overflow-x-hidden">
@ -12,18 +184,19 @@ export class ContactCard extends Component {
<Link to="/~contacts/">{"⟵"}</Link>
</div>
<div className="w-100 bb b--gray4">
<button className="ml3 mt2 mb2 f9 pa2 ba br3 b--black">Edit Contact Info</button>
</div>
<div className="w-100 flex justify-center pa4 pa0-xl pt4-xl">
<div className="w-100 mw6 tc">
{/*TODO default to sigil, but show avatar if exists for contact */}
<Sigil ship={this.props.ship} size={128} color={this.props.contact.color}/>
<div className="w-100 pt8 lh-copy tl">
<p className="f9 gray2">Ship Name</p>
<p className="f8 mono">~{this.props.ship}</p>
</div>
</div>
<button
onClick={this.editToggle}
className={`ml3 mt2 mb2 f9 pa2 ba br3 pointer b--black ` + ourOption}>
{editInfoText}
</button>
<button className={`ml3 mt2 mb2 f9 pa2 ba br3 b--black ` + localOption}>
Share Contact Info
</button>
<button className={`ml3 mt2 mb2 f9 pa2 ba red2 br3 b--red2 ` + adminOption}>
Remove from Group
</button>
</div>
{card}
</div>
)
}

View File

@ -7,7 +7,7 @@ import urbitOb from 'urbit-ob';
export class NewScreen extends Component {
constructor(props) {
super(props);
this.state = {
groupName: '',
invites: '',
@ -15,30 +15,30 @@ export class NewScreen extends Component {
groupNameError: false,
inviteError: false
};
this.groupNameChange = this.groupNameChange.bind(this);
this.invChange = this.invChange.bind(this);
// this.colorChange = this.colorChange.bind(this);
}
groupNameChange(event) {
this.setState({
groupName: event.target.value
});
}
invChange(event) {
this.setState({
invites: event.target.value
});
}
// colorChange(event) {
// this.setState({
// color: event.target.value
// });
// }
onClickCreate() {
const { props, state } = this;
if (!state.groupName) {
@ -49,21 +49,21 @@ export class NewScreen extends Component {
return;
}
let group = `/~${window.ship}` + `/${state.groupName}`;
let aud = [];
let isValid = true;
if (state.invites.length > 2) {
aud = state.invites.split(',')
.map((mem) => `~${deSig(mem.trim())}`);
aud.forEach((mem) => {
if (!urbitOb.isValidPatp(mem)) {
isValid = false;
}
});
}
if (!isValid) {
this.setState({
inviteError: true,
@ -71,7 +71,7 @@ export class NewScreen extends Component {
});
return;
}
if (this.textarea) {
this.textarea.value = '';
}
@ -90,96 +90,97 @@ export class NewScreen extends Component {
});
});
}
render() {
let groupNameErrElem = (<span />);
if (this.state.groupNameError) {
groupNameErrElem = (
<span className="f9 inter red2 ml3 mt1 db">
Group must have a valid name.
Group must have a valid name.
</span>
);
}
let invErrElem = (<span />);
if (this.state.inviteError) {
invErrElem = (
<span className="f9 inter red2 ml3 mb5 db">
);
}
let invErrElem = (<span />);
if (this.state.inviteError) {
invErrElem = (
<span className="f9 inter red2 ml3 mb5 db">
Invites must be validly formatted ship names.
</span>
);
}
return (
<div className="h-100 w-100 flex flex-column overflow-y-scroll">
<div className="w-100 dn-m dn-l dn-xl inter pt1 pb6 pl3 pt3 f8">
</span>
);
}
return (
<div className="h-100 w-100 flex flex-column overflow-y-scroll">
<div className="w-100 dn-m dn-l dn-xl inter pt1 pb6 pl3 pt3 f8">
<Link to="/~contacts/">{"⟵ All Groups"}</Link>
</div>
<div className="w-100 w-50-l w-50-xl mb4 pr6 pr0-l pr0-xl">
</div>
<div className="w-100 w-50-l w-50-xl mb4 pr6 pr0-l pr0-xl">
<h2 className="f8 pl3 pt4">Create New Group</h2>
<h2 className="f8 pl3 pt6">Group Name</h2>
<p className="f9 pl3 gray2 lh-copy">Alphanumeric characters and hyphens only</p>
<textarea
className="f7 ba b--gray3 w-100 pa3 ml3 mt2"
rows={1}
placeholder="example-group-name"
style={{
resize: "none",
height: 48,
paddingTop: 14
}}
onChange={this.groupNameChange}/>
className="f7 ba b--gray3 w-100 pa3 ml3 mt2"
rows={1}
placeholder="example-group-name"
style={{
resize: "none",
height: 48,
paddingTop: 14
}}
onChange={this.groupNameChange}/>
{groupNameErrElem}
{/* <h2 className="f8 pl3 pt6">Group Avatar</h2>
<p className="f9 pl3 gray2 lh-copy">
Select a color to represent your group
Select a color to represent your group
</p>
<textarea
className="f7 ba b--gray3 w-50 w-25-xl pa3 ml3 mt2"
rows={1}
placeholder="#000000"
style={{
resize: "none",
height: 48,
paddingTop: 14
}}
/> */}
<h2 className="f8 pl3 pt6">Add Group Members</h2>
<p className="f9 pl3 gray2 lh-copy">
Invite ships to your group
</p>
<div className="relative">
<textarea
className="f8 ba b--gray3 w-100 pa3 pl3 ml3 mt2 mb2"
rows={1}
placeholder="~zod, ~dopzod, ~ravmel-ropdyl"
style={{
resize: "none",
height: 48,
paddingTop: 15
}}
onChange={this.invChange}/>
{invErrElem}
{/* <span className="f5 gray3 absolute"
style={{transform: "rotate(-45deg)",
left: 21,
top: 18}}>
</span> */}
</div>
<button
onClick={this.onClickCreate.bind(this)}
className="ml3 f8 ba pa2 b--green2 green2 pointer">
Start Group
</button>
<Link to="/~contacts">
<button className="f8 ml3 ba pa2 b--black pointer">Cancel</button>
</Link>
</div>
className="f7 ba b--gray3 w-50 w-25-xl pa3 ml3 mt2"
rows={1}
placeholder="#000000"
style={{
resize: "none",
height: 48,
paddingTop: 14
}}
/> */}
<h2 className="f8 pl3 pt6">Add Group Members</h2>
<p className="f9 pl3 gray2 lh-copy">
Invite ships to your group
</p>
<div className="relative">
<textarea
className="f8 ba b--gray3 w-100 pa3 pl3 ml3 mt2 mb2"
rows={1}
placeholder="~zod, ~dopzod, ~ravmel-ropdyl"
style={{
resize: "none",
height: 48,
paddingTop: 15
}}
onChange={this.invChange}/>
{invErrElem}
{/* <span className="f5 gray3 absolute"
style={{transform: "rotate(-45deg)",
left: 21,
top: 18}}>
</span> */}
</div>
);
<button
onClick={this.onClickCreate.bind(this)}
className="ml3 f8 ba pa2 b--green2 green2 pointer">
Start Group
</button>
<Link to="/~contacts">
<button className="f8 ml3 ba pa2 b--black pointer">Cancel</button>
</Link>
</div>
</div>
);
}
}
}
export default NewScreen
export default NewScreen