<commit_before>/* eslint-disable import/no-unresolved */
import React, {
  PropTypes,
} from 'react';

import {
  StyleSheet,
  Text,
  TouchableHighlight,
  View,
} from 'react-native';

const Cell = (props) => {
  const {
    accessory,
    accessoryColor,
    allowFontScaling,
    backgroundColor,
    cellStyle,
    cellContentView,
    cellImageView,
    cellAccessoryView,
    contentContainerStyle,
    detail,
    disableImageResize,
    highlightActiveOpacity,
    highlightUnderlayColor,
    image,
    isDisabled,
    onPress,
    onHighlightRow,
    onUnHighlightRow,
    leftDetailColor,
    rightDetailColor,
    title,
    titleTextColor,
    titleStyle,
    titleStyleDisabled,
    detailStyle,
  } = props;

  const isPressable = !!onPress;

  /**
    * Merge styles with props
    */
  // eslint-disable-next-line no-underscore-dangle
  const _styles = {
    ...styles,
    cell: [
      styles.cell,
      {
        backgroundColor,
      },
      contentContainerStyle,
    ],
    cell_title: isDisabled
      ? [...{}, styles.cell_title, styles.cell_text__disabled, titleStyleDisabled]
      : [...{}, styles.cell_title, { color: titleTextColor }, titleStyle],
    cell_leftDetail: [
      styles.cell_leftDetail,
      { color: leftDetailColor },
      detailStyle,
    ],
    cell_leftDetailTitle: isDisabled
      ? [styles.cell_leftDetailTitle, styles.cell_text__disabled]
      : [styles.cell_leftDetailTitle, { color: titleTextColor }],
    cell_rightDetail: [
      styles.cell_rightDetail,
      { color: rightDetailColor },
      detailStyle,
    ],

    accessory_checkmark: [
      styles.accessory_checkmark,
      { borderColor: accessoryColor },
    ],
    accessory_detail: [
      styles.accessory_detail,
      { borderColor: accessoryColor },
    ],
    accessory_detailText: [
      styles.accessory_detailText,
      { color: accessoryColor },
    ],
  };

  /**
    * Render accessoryView
    * Currently available
    * @return {View} View with accessory
    */
  const renderAccessoryView = () => {
    switch (accessory) {
      case 'DisclosureIndicator':
        return (
          <View style={_styles.cellAccessoryView}>
            <View style={_styles.accessory_disclosureIndicator} />
          </View>
        );
      case 'Detail':
        return (
          <View style={_styles.cellAccessoryView}>
            <View style={_styles.accessory_detail}>
              <Text style={_styles.accessory_detailText}>i</Text>
            </View>
          </View>
        );
      case 'DetailDisclosure':
        return (
          <View style={_styles.cellAccessoryView}>
            <View style={_styles.accessory_detailDisclosure}>
              <View style={_styles.accessory_detail}>
                <Text style={_styles.accessory_detailText}>i</Text>
              </View>
              <View style={_styles.accessory_disclosureIndicator} />
            </View>
          </View>
        );
      case 'Checkmark':
        return (
          <View style={_styles.cellAccessoryView}>
            <View style={_styles.accessory_checkmark} />
          </View>
        );
      default:
        return null;
    }
  };

  /**
   * Render imageView
   * @return {Image} Image component with updated props
   */
  const renderImageView = () => {
    if (!image) return null;
    const propsToAdd = {
      style: disableImageResize ? image.props.style : [image.props.style, _styles.image],
    };
    return (
      <View style={_styles.cellImageView}>
        {React.cloneElement(image, propsToAdd)}
      </View>
    );
  };

  /**
    * Render cell of type Basic
    * @return {View} View with Text and Accessory
    */
  const renderCellBasic = () => (
    <View style={_styles.cellContentView}>
      <Text
        allowFontScaling={allowFontScaling}
        numberOfLines={1}
        style={_styles.cell_title}
      >
        {title}
      </Text>
    </View>
  );

  /**
   * Render cell of type RightDetail
   * @return {View} View with Text, Text and Accessory
   */
  const renderCellRightDetail = () => (
    <View style={_styles.cellContentView}>
      <Text
        allowFontScaling={allowFontScaling}
        numberOfLines={1}
        style={_styles.cell_title}
      >
        {title}
      </Text>
      <Text
        allowFontScaling={allowFontScaling}
        numberOfLines={1}
        style={isDisabled ? [_styles.cell_rightDetail, _styles.cell_text__disabled] : _styles.cell_rightDetail}
      >
        {detail}
      </Text>
    </View>
  );

  /**
   * Render cell of type LeftDetail
   * @return {View} View with Text, Text and Accessory
   */
  const renderCellLeftDetail = () => (
    <View style={_styles.cellContentView}>
      <Text
        allowFontScaling={allowFontScaling}
        numberOfLines={1}
        style={isDisabled ? [_styles.cell_leftDetail, _styles.cell_text__disabled] : _styles.cell_leftDetail}
      >
        {detail}
      </Text>
      <Text
        allowFontScaling={allowFontScaling}
        numberOfLines={1}
        style={_styles.cell_leftDetailTitle}
      >
        {title}
      </Text>
    </View>
  );

  /**
    * Render cell of type Subtitle
    * @return {View} View with View, Text, Text and Accessory
    */
  const renderCellSubtitle = () => (
    <View style={[_styles.cellContentView, _styles.cellContentView__type_subtitle]}>
      <View style={_styles.cellinner__subtitle}>
        <Text
          allowFontScaling={allowFontScaling}
          numberOfLines={1}
          style={_styles.cell_title}
        >
          {title}
        </Text>
        <Text
          allowFontScaling={allowFontScaling}
          numberOfLines={1}
          style={isDisabled ? [_styles.cell_subtitle, _styles.cell_text__disabled] : _styles.cell_subtitle}
        >
          {detail}
        </Text>
      </View>
    </View>
  );

  /**
    * Renders correct contentView
    * @return {View} ContentView
    */
  const renderCellContentView = () => {
    switch (cellStyle) {
      case 'Basic':
        return renderCellBasic();
      case 'RightDetail':
        return renderCellRightDetail();
      case 'LeftDetail':
        return renderCellLeftDetail();
      case 'Subtitle':
        return renderCellSubtitle();
      default:
        return renderCellBasic();
    }
  };

  /**
   * Render content of cell
   * @return {View} Complete View with cell elements
   */
  const renderCell = () => (
    <View style={_styles.cell}>
      {cellImageView || renderImageView()}
      {cellContentView || renderCellContentView()}
      {cellAccessoryView || renderAccessoryView()}
    </View>
  );

  if (isPressable && !isDisabled) {
    return (
      <TouchableHighlight
        activeOpacity={highlightActiveOpacity}
        onPress={onPress}
        underlayColor={highlightUnderlayColor}
        onPressIn={onHighlightRow}
        onPressOut={onUnHighlightRow}
      >
        {renderCell()}
      </TouchableHighlight>
    );
  }
  return (<View>{renderCell()}</View>);
};

const styles = StyleSheet.create({
  cell: {
    alignItems: 'center',
    paddingLeft: 15,
    paddingRight: 20,
    minHeight: 44,
    flexDirection: 'row',
  },
  cellContentView: {
    alignItems: 'center',
    flexDirection: 'row',
    flex: 1,
    justifyContent: 'center',
    // independent from other cellViews
    paddingVertical: 10,
  },
  cellContentView__type_subtitle: {
    paddingVertical: 4,
  },
  cellinner__subtitle: {
    flexDirection: 'column',
    flex: 1,
  },
  cell_title: {
    fontSize: 16,
    flex: 1,
  },
  cell_leftDetailTitle: {
    fontSize: 12,
    flex: 1,
  },
  cell_leftDetail: {
    fontSize: 12,
    alignSelf: 'center',
    textAlign: 'right',
    marginRight: 5,
    width: 75,
  },
  cell_rightDetail: {
    fontSize: 16,
    alignSelf: 'center',
    color: '#8E8E93',
  },
  cell_subtitle: {
    fontSize: 11,
  },
  cell_text__disabled: {
    color: 'gray',
  },
  cellImageView: {
    justifyContent: 'center',
    marginRight: 15,
  },
  image: {
    height: 29,
    width: 29,
  },
  cellAccessoryView: {
    justifyContent: 'center',
  },
  accessory_disclosureIndicator: {
    width: 10,
    height: 10,
    marginLeft: 7,
    backgroundColor: 'transparent',
    borderTopWidth: 1,
    borderRightWidth: 1,
    borderColor: '#c7c7cc',
    transform: [{
      rotate: '45deg',
    }],
  },
  accessory_detail: {
    width: 20,
    height: 20,
    marginLeft: 10,
    backgroundColor: 'transparent',
    borderWidth: 1,
    borderRadius: 10,
    alignItems: 'center',
    justifyContent: 'center',
  },
  accessory_detailText: {
    fontSize: 15,
    fontWeight: '400',
    fontFamily: 'Georgia',
  },
  accessory_detailDisclosure: {
    flexDirection: 'row',
    alignItems: 'center',
  },
  accessory_checkmark: {
    width: 13,
    height: 6,
    marginLeft: 7,
    backgroundColor: 'transparent',
    borderBottomWidth: 2,
    borderLeftWidth: 2,
    borderColor: '#007AFF',
    transform: [{
      rotate: '-45deg',
    }],
  },
});

Cell.propTypes = {
  accessory: PropTypes.oneOfType([
    PropTypes.bool,
    PropTypes.string,
  ]),
  accessoryColor: PropTypes.string.isRequired,
  allowFontScaling: PropTypes.bool,
  cellStyle: PropTypes.string,
  cellContentView: PropTypes.element,
  cellImageView: PropTypes.element,
  cellAccessoryView: PropTypes.element,
  contentContainerStyle: View.propTypes.style,
  backgroundColor: PropTypes.string.isRequired,
  detail: PropTypes.oneOfType([
    PropTypes.string,
    PropTypes.number,
  ]),
  disableImageResize: PropTypes.bool,
  highlightActiveOpacity: PropTypes.number,
  highlightUnderlayColor: PropTypes.string,
  image: PropTypes.element,
  isDisabled: PropTypes.bool,
  leftDetailColor: PropTypes.string,
  onHighlightRow: PropTypes.func,
  onUnHighlightRow: PropTypes.func,
  rightDetailColor: PropTypes.string,
  title: PropTypes.oneOfType([
    PropTypes.string,
    PropTypes.number,
    PropTypes.element,
  ]),
  titleStyle: View.propTypes.style,
  titleStyleDisabled: View.propTypes.style,
  detailStyle: View.propTypes.style,
  titleTextColor: PropTypes.string,
  onPress: PropTypes.oneOfType([
    PropTypes.bool,
    PropTypes.func,
  ]),
};

Cell.defaultProps = {
  accessory: false,
  accessoryColor: '#007AFF',
  allowFontScaling: true,
  cellStyle: 'Basic',
  cellContentView: null,
  cellImageView: null,
  cellAccessoryView: null,
  contentContainerStyle: {},
  backgroundColor: '#FFF',
  detail: '',
  disableImageResize: false,
  highlightActiveOpacity: 0.8,
  highlightUnderlayColor: 'black',
  image: null,
  isDisabled: false,
  leftDetailColor: '#007AFF',
  onHighlightRow: null,
  onUnHighlightRow: null,
  onPress: false,
  rightDetailColor: '#8E8E93',
  title: '',
  titleTextColor: '#000',
};

export default Cell;
<commit_msg>More linting issues<commit_after>/* eslint-disable import/no-unresolved */
import React, {
  PropTypes,
} from 'react';

import {
  StyleSheet,
  Text,
  TouchableHighlight,
  View,
} from 'react-native';

const Cell = (props) => {
  const {
    accessory,
    accessoryColor,
    allowFontScaling,
    backgroundColor,
    cellStyle,
    cellContentView,
    cellImageView,
    cellAccessoryView,
    contentContainerStyle,
    detail,
    disableImageResize,
    highlightActiveOpacity,
    highlightUnderlayColor,
    image,
    isDisabled,
    onPress,
    onHighlightRow,
    onUnHighlightRow,
    leftDetailColor,
    rightDetailColor,
    title,
    titleTextColor,
    titleStyle,
    titleStyleDisabled,
    detailStyle,
  } = props;

  const isPressable = !!onPress;

  /**
    * Merge styles with props
    */
  // eslint-disable-next-line no-underscore-dangle
  const _styles = {
    ...styles,
    cell: [
      styles.cell,
      {
        backgroundColor,
      },
      contentContainerStyle,
    ],
    cell_title: isDisabled
      ? [...{}, styles.cell_title, styles.cell_text__disabled, titleStyleDisabled]
      : [...{}, styles.cell_title, { color: titleTextColor }, titleStyle],
    cell_leftDetail: [
      styles.cell_leftDetail,
      { color: leftDetailColor },
      detailStyle,
    ],
    cell_leftDetailTitle: isDisabled
      ? [styles.cell_leftDetailTitle, styles.cell_text__disabled]
      : [styles.cell_leftDetailTitle, { color: titleTextColor }],
    cell_rightDetail: [
      styles.cell_rightDetail,
      { color: rightDetailColor },
      detailStyle,
    ],

    accessory_checkmark: [
      styles.accessory_checkmark,
      { borderColor: accessoryColor },
    ],
    accessory_detail: [
      styles.accessory_detail,
      { borderColor: accessoryColor },
    ],
    accessory_detailText: [
      styles.accessory_detailText,
      { color: accessoryColor },
    ],
  };

  /**
    * Render accessoryView
    * Currently available
    * @return {View} View with accessory
    */
  const renderAccessoryView = () => {
    switch (accessory) {
      case 'DisclosureIndicator':
        return (
          <View style={_styles.cellAccessoryView}>
            <View style={_styles.accessory_disclosureIndicator} />
          </View>
        );
      case 'Detail':
        return (
          <View style={_styles.cellAccessoryView}>
            <View style={_styles.accessory_detail}>
              <Text style={_styles.accessory_detailText}>i</Text>
            </View>
          </View>
        );
      case 'DetailDisclosure':
        return (
          <View style={_styles.cellAccessoryView}>
            <View style={_styles.accessory_detailDisclosure}>
              <View style={_styles.accessory_detail}>
                <Text style={_styles.accessory_detailText}>i</Text>
              </View>
              <View style={_styles.accessory_disclosureIndicator} />
            </View>
          </View>
        );
      case 'Checkmark':
        return (
          <View style={_styles.cellAccessoryView}>
            <View style={_styles.accessory_checkmark} />
          </View>
        );
      default:
        return null;
    }
  };

  /**
   * Render imageView
   * @return {Image} Image component with updated props
   */
  const renderImageView = () => {
    if (!image) return null;
    const propsToAdd = {
      style: disableImageResize ? image.props.style : [image.props.style, _styles.image],
    };
    return (
      <View style={_styles.cellImageView}>
        {React.cloneElement(image, propsToAdd)}
      </View>
    );
  };

  /**
    * Render cell of type Basic
    * @return {View} View with Text and Accessory
    */
  const renderCellBasic = () => (
    <View style={_styles.cellContentView}>
      <Text
        allowFontScaling={allowFontScaling}
        numberOfLines={1}
        style={_styles.cell_title}
      >
        {title}
      </Text>
    </View>
  );

  /**
   * Render cell of type RightDetail
   * @return {View} View with Text, Text and Accessory
   */
  const renderCellRightDetail = () => (
    <View style={_styles.cellContentView}>
      <Text
        allowFontScaling={allowFontScaling}
        numberOfLines={1}
        style={_styles.cell_title}
      >
        {title}
      </Text>
      <Text
        allowFontScaling={allowFontScaling}
        numberOfLines={1}
        style={isDisabled ? [_styles.cell_rightDetail, _styles.cell_text__disabled] : _styles.cell_rightDetail}
      >
        {detail}
      </Text>
    </View>
  );

  /**
   * Render cell of type LeftDetail
   * @return {View} View with Text, Text and Accessory
   */
  const renderCellLeftDetail = () => (
    <View style={_styles.cellContentView}>
      <Text
        allowFontScaling={allowFontScaling}
        numberOfLines={1}
        style={isDisabled ? [_styles.cell_leftDetail, _styles.cell_text__disabled] : _styles.cell_leftDetail}
      >
        {detail}
      </Text>
      <Text
        allowFontScaling={allowFontScaling}
        numberOfLines={1}
        style={_styles.cell_leftDetailTitle}
      >
        {title}
      </Text>
    </View>
  );

  /**
    * Render cell of type Subtitle
    * @return {View} View with View, Text, Text and Accessory
    */
  const renderCellSubtitle = () => (
    <View style={[_styles.cellContentView, _styles.cellContentView__type_subtitle]}>
      <View style={_styles.cellinner__subtitle}>
        <Text
          allowFontScaling={allowFontScaling}
          numberOfLines={1}
          style={_styles.cell_title}
        >
          {title}
        </Text>
        <Text
          allowFontScaling={allowFontScaling}
          numberOfLines={1}
          style={isDisabled ? [_styles.cell_subtitle, _styles.cell_text__disabled] : _styles.cell_subtitle}
        >
          {detail}
        </Text>
      </View>
    </View>
  );

  /**
    * Renders correct contentView
    * @return {View} ContentView
    */
  const renderCellContentView = () => {
    switch (cellStyle) {
      case 'Basic':
        return renderCellBasic();
      case 'RightDetail':
        return renderCellRightDetail();
      case 'LeftDetail':
        return renderCellLeftDetail();
      case 'Subtitle':
        return renderCellSubtitle();
      default:
        return renderCellBasic();
    }
  };

  /**
   * Render content of cell
   * @return {View} Complete View with cell elements
   */
  const renderCell = () => (
    <View style={_styles.cell}>
      {cellImageView || renderImageView()}
      {cellContentView || renderCellContentView()}
      {cellAccessoryView || renderAccessoryView()}
    </View>
  );

  if (isPressable && !isDisabled) {
    return (
      <TouchableHighlight
        activeOpacity={highlightActiveOpacity}
        onPress={onPress}
        underlayColor={highlightUnderlayColor}
        onPressIn={onHighlightRow}
        onPressOut={onUnHighlightRow}
      >
        {renderCell()}
      </TouchableHighlight>
    );
  }
  return (<View>{renderCell()}</View>);
};

const styles = StyleSheet.create({
  cell: {
    alignItems: 'center',
    paddingLeft: 15,
    paddingRight: 20,
    minHeight: 44,
    flexDirection: 'row',
  },
  cellContentView: {
    alignItems: 'center',
    flexDirection: 'row',
    flex: 1,
    justifyContent: 'center',
    // independent from other cellViews
    paddingVertical: 10,
  },
  cellContentView__type_subtitle: {
    paddingVertical: 4,
  },
  cellinner__subtitle: {
    flexDirection: 'column',
    flex: 1,
  },
  cell_title: {
    fontSize: 16,
    flex: 1,
  },
  cell_leftDetailTitle: {
    fontSize: 12,
    flex: 1,
  },
  cell_leftDetail: {
    fontSize: 12,
    alignSelf: 'center',
    textAlign: 'right',
    marginRight: 5,
    width: 75,
  },
  cell_rightDetail: {
    fontSize: 16,
    alignSelf: 'center',
    color: '#8E8E93',
  },
  cell_subtitle: {
    fontSize: 11,
  },
  cell_text__disabled: {
    color: 'gray',
  },
  cellImageView: {
    justifyContent: 'center',
    marginRight: 15,
  },
  image: {
    height: 29,
    width: 29,
  },
  cellAccessoryView: {
    justifyContent: 'center',
  },
  accessory_disclosureIndicator: {
    width: 10,
    height: 10,
    marginLeft: 7,
    backgroundColor: 'transparent',
    borderTopWidth: 1,
    borderRightWidth: 1,
    borderColor: '#c7c7cc',
    transform: [{
      rotate: '45deg',
    }],
  },
  accessory_detail: {
    width: 20,
    height: 20,
    marginLeft: 10,
    backgroundColor: 'transparent',
    borderWidth: 1,
    borderRadius: 10,
    alignItems: 'center',
    justifyContent: 'center',
  },
  accessory_detailText: {
    fontSize: 15,
    fontWeight: '400',
    fontFamily: 'Georgia',
  },
  accessory_detailDisclosure: {
    flexDirection: 'row',
    alignItems: 'center',
  },
  accessory_checkmark: {
    width: 13,
    height: 6,
    marginLeft: 7,
    backgroundColor: 'transparent',
    borderBottomWidth: 2,
    borderLeftWidth: 2,
    borderColor: '#007AFF',
    transform: [{
      rotate: '-45deg',
    }],
  },
});

Cell.propTypes = {
  accessory: PropTypes.oneOfType([
    PropTypes.bool,
    PropTypes.string,
  ]),
  accessoryColor: PropTypes.string.isRequired,
  allowFontScaling: PropTypes.bool,
  cellStyle: PropTypes.string,
  cellContentView: PropTypes.element,
  cellImageView: PropTypes.element,
  cellAccessoryView: PropTypes.element,
  contentContainerStyle: View.propTypes.style,
  backgroundColor: PropTypes.string.isRequired,
  detail: PropTypes.oneOfType([
    PropTypes.string,
    PropTypes.number,
  ]),
  disableImageResize: PropTypes.bool,
  highlightActiveOpacity: PropTypes.number,
  highlightUnderlayColor: PropTypes.string,
  image: PropTypes.element,
  isDisabled: PropTypes.bool,
  leftDetailColor: PropTypes.string,
  onHighlightRow: PropTypes.func,
  onUnHighlightRow: PropTypes.func,
  rightDetailColor: PropTypes.string,
  title: PropTypes.oneOfType([
    PropTypes.string,
    PropTypes.number,
    PropTypes.element,
  ]),
  titleStyle: View.propTypes.style,
  titleStyleDisabled: View.propTypes.style,
  detailStyle: View.propTypes.style,
  titleTextColor: PropTypes.string,
  onPress: PropTypes.oneOfType([
    PropTypes.bool,
    PropTypes.func,
  ]),
};

Cell.defaultProps = {
  accessory: false,
  accessoryColor: '#007AFF',
  allowFontScaling: true,
  cellStyle: 'Basic',
  cellContentView: null,
  cellImageView: null,
  cellAccessoryView: null,
  contentContainerStyle: {},
  backgroundColor: '#FFF',
  detail: '',
  disableImageResize: false,
  highlightActiveOpacity: 0.8,
  highlightUnderlayColor: 'black',
  image: null,
  isDisabled: false,
  leftDetailColor: '#007AFF',
  onHighlightRow: null,
  onUnHighlightRow: null,
  onPress: false,
  rightDetailColor: '#8E8E93',
  title: '',
  titleStyle: {},
  titleStyleDisabled: {},
  detailStyle: {},
  titleTextColor: '#000',
};

export default Cell;
<|endoftext|>


<commit_before>import React, { Component} from 'react'
import { Button } from 'react-native'
import { TouchableOpacity, Picker, StyleSheet, View, Text, Image, Dimensions, Alert } from 'react-native'
import { WheelPicker} from 'react-native-wheel-picker-android'
import DateTimePicker from 'react-native-modal-datetime-picker';

import ValidationScreen from './Validation.js'

 class Home extends Component{
    static navigationOptions = {header:null }

    state={ isDatePickerVisible: false, chosenDate: new Date()};

   // When the Hour Picker wheel changes set the hour_value
   // variable to be returned in view2
    _setHour = (hour) => {
        this.hour_value = hour;
        // Alert.alert("Hour is: " + this.hour_value);
        console.log("Hour is: " + this.hour_value);
   }
   // Getter method to return hour_value.. Doesn't work :-(
   _getHour = () => {
       return this.hour_value;
   }

   _showDatepicker = () => this.setState({ isDatePickerVisible: true});
   _hideDatepicker = () => this.setState({ isDatePickerVisible: false});

   _handleDatePicked = (date) => {
       this.setState({chosenDate: date});

       this._hideDatepicker();
   }

   arr = [1,2,3,4,5,6,7,8,9,10,11,12];

    now = new Date();

   //Used to let the user select the number of hours volunteered

   render() {
    const {navigate} = this.props.navigation;
    const date = new Date();
    const dateInfo = this.state.chosenDate;
    return (
        <View  style = {styles.container}>
            <Image source={require('./img/paws-screen2-bg-hi_res.png')}
                style = {styles.bgImgContainer}>
                {/*
                    * HEADER
                */}
                    <Text style = {styles.header}>
                        Please enter your volunteer time below
                    </Text>

                {/*
                    * DATE PICKER
                */}
                <DatePicker
                    initdate={now.toISOString()}
                    onDateSelected={ (date) => this.onDateSelected(date)}
                    style = {styles.datePicker}
                />
                */}

                <View>
                    <Text onPress={this._showDatepicker} style={styles.date_picker}>{("0" + dateInfo.getDate()).toString().substr(-2)} <Text style={styles.gold_text_large}>|</Text> {("0" + (dateInfo.getMonth() + 1)).toString().substr(-2)} <Text style={styles.gold_text_large}>|</Text> {dateInfo.getFullYear().toString().substr(-2)}</Text>
                    <View style={styles.center_align}><Text style={styles.gold_text}>Date</Text></View>
                </View>

                <DateTimePicker
                    isVisible={this.state.isDatePickerVisible}
                    onConfirm={this._handleDatePicked}
                    onCancel={this._hideDatepicker}
                    date={this.state.chosenDate}
                    maximumDate={new Date()}
                />

                {/*
                    * TIME PICKER
                */}

                <View style={styles.wp_view}>
                    <Text style={styles.gold_text_hours}>Hours</Text>
                        <WheelPicker
                            onItemSelected={(event) => {this._setHour(event["data"])}}
                            isCurved
                            isAtmospheric
                            visibleItemCount={2}
                            itemSpace={50}
                            itemTextSize={170}
                            itemTextColor="white"
                            data={this.arr}
                            style = {styles.wheelpicker}
                        />

                </View>

                {/*
                    * SUBMIT BUTTON
                */}
                <View style={styles.submit_box}>
                    <TouchableOpacity onPress ={ () => {navigate('Validation', ({date: "7/14/2017", hours: 6}))}} style = {styles.submit}>
                        <Text style = {styles.text}>
                            Submit
                        </Text>
                    </TouchableOpacity>
                </View>
            </Image>
        </View>
    );
   }
}
export default Home

const styles =  StyleSheet.create({

    container: {
        flex: 1,
        flexDirection: 'column',
        justifyContent: 'space-between',
        alignItems: 'center',
        backgroundColor: 'black',
    },
    bgImgContainer:{
        flex:1,
        flexDirection: 'column',
        justifyContent: 'space-between',
        alignItems: 'center',
        resizeMode: 'contain'
    },
    label:{
        color: "white",
        fontSize: 15,
        // marginBottom:10,
        // marginTop:70,
    },
    center_align:{
        justifyContent:'center',
        alignItems: 'center',
    },
    wp_text:{

    },
    wp_view:{
        flexDirection: 'column',
        justifyContent:'center',
        alignItems: 'center',
        width:175,
        height:175,
        borderWidth:3,
        borderRadius: 300,
        borderColor: "white",

        // marginTop: 100,
        // marginBottom: 100,
        paddingTop:10,
        paddingBottom:10,
        marginBottom: 20
    },
    date_picker:{
        fontSize: 60,
        color: 'white'
    },
    gold_text: {
        fontFamily: 'sans-serif-medium',
        fontSize: 22,
        color: '#9c8158',
        justifyContent:'center',
        top: -10
    },
    gold_text_hours: {
        fontFamily: 'sans-serif-medium',
        fontSize: 22,
        color: '#9c8158',
        top: 56,
        left: 45
    },
    gold_text_large: {
        fontFamily: 'sans-serif-thin',
        fontSize: 72,
        color: '#9c8158',
    },
    wheelpicker: {
        flexDirection: 'column',
        justifyContent:'center',
        alignItems: 'center',
        width:140,
        height:120,
        left: -30,
        top: -20,
        // marginTop: 15,
        // marginBottom: 15,
        borderRadius: 500,
        borderColor: "white",
        borderWidth:2

    },
    datePicker: {
        width: 50,
        height: 100,
        // marginBottom: 10,
        // marginTop: 10,
        paddingLeft: 500,
        backgroundColor: 'white'

    },
     header: {
        alignItems: 'flex-start',
         textAlign: 'center',
         color: 'white',
         fontSize: 18,
         marginTop: 20
     },
     picker: {
         backgroundColor: '#E5E5E5'
     },
    submit: {
       justifyContent: 'flex-end',
       width: 200,
       height: 75,
       marginTop: 25,
       backgroundColor: 'white',
       borderRadius: 50,
    },
    submit_box:{
        alignSelf: 'stretch',
        height: 125,
        backgroundColor: 'black',
        alignItems: 'center'
    },
    text: {
        width: 200,
        height: 75,
        borderRadius: 50,
        marginTop: 25,
        padding: 20,
        paddingTop: 15,
        fontSize: 30,
        textAlign: 'center',
        color: 'black'
    }
})<commit_msg>Fixed error created by merge in relation to the date picker.<commit_after>import React, { Component} from 'react'
import { Button } from 'react-native'
import { TouchableOpacity, Picker, StyleSheet, View, Text, Image, Dimensions, Alert } from 'react-native'
import { WheelPicker} from 'react-native-wheel-picker-android'
import DateTimePicker from 'react-native-modal-datetime-picker';

import ValidationScreen from './Validation.js'

 class Home extends Component{
    static navigationOptions = {header:null }

    state={ isDatePickerVisible: false, chosenDate: new Date()};

   // When the Hour Picker wheel changes set the hour_value
   // variable to be returned in view2
    _setHour = (hour) => {
        this.hour_value = hour;
        // Alert.alert("Hour is: " + this.hour_value);
        console.log("Hour is: " + this.hour_value);
   }
   // Getter method to return hour_value.. Doesn't work :-(
   _getHour = () => {
       return this.hour_value;
   }

   _showDatepicker = () => this.setState({ isDatePickerVisible: true});
   _hideDatepicker = () => this.setState({ isDatePickerVisible: false});

   _handleDatePicked = (date) => {
       this.setState({chosenDate: date});

       this._hideDatepicker();
   }

   arr = [1,2,3,4,5,6,7,8,9,10,11,12];

    now = new Date();

   //Used to let the user select the number of hours volunteered

   render() {
    const {navigate} = this.props.navigation;
    const date = new Date();
    const dateInfo = this.state.chosenDate;
    return (
        <View  style = {styles.container}>
            <Image source={require('./img/paws-screen2-bg-hi_res.png')}
                style = {styles.bgImgContainer}>
                {/*
                    * HEADER
                */}
                    <Text style = {styles.header}>
                        Please enter your volunteer time below
                    </Text>

                {/*
                    * DATE PICKER
                */}
                <View>
                    <Text onPress={this._showDatepicker} style={styles.date_picker}>{("0" + dateInfo.getDate()).toString().substr(-2)} <Text style={styles.gold_text_large}>|</Text> {("0" + (dateInfo.getMonth() + 1)).toString().substr(-2)} <Text style={styles.gold_text_large}>|</Text> {dateInfo.getFullYear().toString().substr(-2)}</Text>
                    <View style={styles.center_align}><Text style={styles.gold_text}>Date</Text></View>
                </View>

                <DateTimePicker
                    isVisible={this.state.isDatePickerVisible}
                    onConfirm={this._handleDatePicked}
                    onCancel={this._hideDatepicker}
                    date={this.state.chosenDate}
                    maximumDate={new Date()}
                />

                {/*
                    * TIME PICKER
                */}

                <View style={styles.wp_view}>
                    <Text style={styles.gold_text_hours}>Hours</Text>
                        <WheelPicker
                            onItemSelected={(event) => {this._setHour(event["data"])}}
                            isCurved
                            isAtmospheric
                            visibleItemCount={2}
                            itemSpace={50}
                            itemTextSize={170}
                            itemTextColor="white"
                            data={this.arr}
                            style = {styles.wheelpicker}
                        />

                </View>

                {/*
                    * SUBMIT BUTTON
                */}
                <View style={styles.submit_box}>
                    <TouchableOpacity onPress ={ () => {navigate('Validation', ({date: "7/14/2017", hours: 6}))}} style = {styles.submit}>
                        <Text style = {styles.text}>
                            Submit
                        </Text>
                    </TouchableOpacity>
                </View>
            </Image>
        </View>
    );
   }
}
export default Home

const styles =  StyleSheet.create({

    container: {
        flex: 1,
        flexDirection: 'column',
        justifyContent: 'space-between',
        alignItems: 'center',
        backgroundColor: 'black',
    },
    bgImgContainer:{
        flex:1,
        flexDirection: 'column',
        justifyContent: 'space-between',
        alignItems: 'center',
        resizeMode: 'contain'
    },
    label:{
        color: "white",
        fontSize: 15,
        // marginBottom:10,
        // marginTop:70,
    },
    center_align:{
        justifyContent:'center',
        alignItems: 'center',
    },
    wp_text:{

    },
    wp_view:{
        flexDirection: 'column',
        justifyContent:'center',
        alignItems: 'center',
        width:175,
        height:175,
        borderWidth:3,
        borderRadius: 300,
        borderColor: "white",

        // marginTop: 100,
        // marginBottom: 100,
        paddingTop:10,
        paddingBottom:10,
        marginBottom: 20
    },
    date_picker:{
        fontSize: 60,
        color: 'white'
    },
    gold_text: {
        fontFamily: 'sans-serif-medium',
        fontSize: 22,
        color: '#9c8158',
        justifyContent:'center',
        top: -10
    },
    gold_text_hours: {
        fontFamily: 'sans-serif-medium',
        fontSize: 22,
        color: '#9c8158',
        top: 56,
        left: 45
    },
    gold_text_large: {
        fontFamily: 'sans-serif-thin',
        fontSize: 72,
        color: '#9c8158',
    },
    wheelpicker: {
        flexDirection: 'column',
        justifyContent:'center',
        alignItems: 'center',
        width:140,
        height:120,
        left: -30,
        top: -20,
        // marginTop: 15,
        // marginBottom: 15,
        borderRadius: 500,
        borderColor: "white",
        borderWidth:2

    },
    datePicker: {
        width: 50,
        height: 100,
        // marginBottom: 10,
        // marginTop: 10,
        paddingLeft: 500,
        backgroundColor: 'white'

    },
     header: {
        alignItems: 'flex-start',
         textAlign: 'center',
         color: 'white',
         fontSize: 18,
         marginTop: 20
     },
     picker: {
         backgroundColor: '#E5E5E5'
     },
    submit: {
       justifyContent: 'flex-end',
       width: 200,
       height: 75,
       marginTop: 25,
       backgroundColor: 'white',
       borderRadius: 50,
    },
    submit_box:{
        alignSelf: 'stretch',
        height: 125,
        backgroundColor: 'black',
        alignItems: 'center'
    },
    text: {
        width: 200,
        height: 75,
        borderRadius: 50,
        marginTop: 25,
        padding: 20,
        paddingTop: 15,
        fontSize: 30,
        textAlign: 'center',
        color: 'black'
    }
})<|endoftext|>


<commit_before>//Configure RequireJS
require({
    paths:{
//        'jquery': 'https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min'
        'jquery': 'jquery'
    },
    priority: ['jquery']
});

require(['jquery', 'utils/css', 'utils/pubsub', 'sammy-0.6.3.min', 'flipcard/flipcard', 'text!css/reset.css', 'text!css/theme.css'], function($, css, pubsub, sammy, FlipCard, reset, theme){
    css.loadInternal(reset, 'css/reset.css', true);
    css.loadInternal(theme, 'css/theme.css');

    var container = $('#container'),
        flipCards = [];

    //-----instanciate FlipCards from json data
    $.ajax({
        url: "data/baby-animals.json",
        dataType: "json",
        success: function(response) {
            var fragment = document.createDocumentFragment();
            for (var i = 0; i < response.length; i += 1) {
                var id = i + 1;
                var obj = response[i];
                var flipCard = new FlipCard(id);
                flipCard.title.html(obj.name);
                flipCard.image.attr('src', 'components/images/' + obj.image);
                flipCards.push(flipCard);
                //add the element (not the jQuery wrapper) to the doc fragment
                fragment.appendChild(flipCard.element.get(0));
            }

            //arrange flipcards
            flipCards[0].element.addClass('left');
            flipCards[2].element.addClass('right');

            //insert into DOM
            container.append(fragment);
        }
    });

    //-----subscribe to flipcard-select event
    pubsub.on('flipcard-selected', function(flipCard){
        deselectOtherFlipCards(flipCard);
    });

    //-----sammy single-page routes
//    var app = $.sammy(function() {
//        this.get('#/flipcard/:flipcard', function() {
//            alert(this.params['flipcard']);
//            var flipcard = getFlipCard(this.params['flipcard']);
//            flipcard.select();
//            deselectOtherFlipCards(flipcard);
//        });
//    });
//    app.run();

    //-----application code needed for example
    function getFlipCard(id){
        for(var i=0; i < flipCards.length; i += 1){
            if(flipCards[i].id === id){
                return flipCards[i];
            }
        }
    }

    function deselectOtherFlipCards(flipCard){
        for(var i=0; i < flipCards.length; i += 1){
            if(flipCards[i] !== flipCard){
                flipCards[i].deselect();
            }
        }
    }

});<commit_msg>refactoring<commit_after>//Configure RequireJS
require({
    paths:{
//        'jquery': 'https://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min'
        'jquery': 'jquery'
    },
    priority: ['jquery']
});

require(['jquery', 'utils/css', 'utils/pubsub', 'sammy-0.6.3.min', 'flipcard/flipcard', 'text!css/reset.css', 'text!css/theme.css'], function($, css, pubsub, sammy, FlipCard, reset, theme){
    css.loadInternal(reset, 'css/reset.css', true);
    css.loadInternal(theme, 'css/theme.css');

    var container = $('#container'),
        flipCards = [];

    //get data and populate
    $.ajax({
            url: "data/baby-animals.json",
            dataType: "json",
            success: populate
        });

    //-----subscribe to flipcard-select event
    pubsub.on('flipcard-selected', function(flipCard){
        deselectOtherFlipCards(flipCard);
    });

    //-----sammy single-page routes
//    var app = $.sammy(function() {
//        this.get('#/flipcard/:flipcard', function() {
//            alert(this.params['flipcard']);
//            var flipcard = getFlipCard(this.params['flipcard']);
//            flipcard.select();
//            deselectOtherFlipCards(flipcard);
//        });
//    });
//    app.run();

    function populate(data){
        var fragment = document.createDocumentFragment();
        for (var i = 0; i < data.length; i += 1) {
            var id = i + 1;
            var obj = data[i];
            var flipCard = new FlipCard(id);
            flipCard.title.html(obj.name);
            flipCard.image.attr('src', 'components/images/' + obj.image);
            flipCards.push(flipCard);
            //add the element (not the jQuery wrapper) to the doc fragment
            fragment.appendChild(flipCard.element.get(0));
        }

        //arrange flipcards
        flipCards[0].element.addClass('left');
        flipCards[2].element.addClass('right');

        //insert into DOM
        container.append(fragment);
    }

    function getFlipCard(id){
        for(var i=0; i < flipCards.length; i += 1){
            if(flipCards[i].id === id){
                return flipCards[i];
            }
        }
    }

    function deselectOtherFlipCards(flipCard){
        for(var i=0; i < flipCards.length; i += 1){
            if(flipCards[i] !== flipCard){
                flipCards[i].deselect();
            }
        }
    }

});<|endoftext|>


<commit_before>import React, { useState } from "react";

import { CSSTransition } from "react-transition-group";
import Image from "next/image";
import Link from "next/link";
import styled from "styled-components";

const Menu = () => {
  const [open, setOpen] = useState(false);
  const pages = [
    { num: "000", href: "/", title: "Home" },
    { num: "001", href: "/about", title: "About" },
    { num: "002", href: "/code", title: "Code" },
    { num: "003", href: "/art", title: "Art" },
    { num: "004", href: "/contact", title: "Contact" },
    { num: "005", href: "https://blog.bythewood.me/", title: "Blog" },
  ];

  const toggleMenu = () => {
    if (open === false) {
      setOpen(true);
      document.body.style.overflowY = "hidden";
    } else {
      setOpen(false);
      document.body.style.overflowY = "scroll";
    }
  };

  return (
    <>
      <Hamburger onClick={toggleMenu} aria-label="Hamburger">
        <Patty style={{ width: "15px" }} />
        <Patty />
        <Patty style={{ width: "20px" }} />
      </Hamburger>
      <CSSTransition in={open} timeout={500} classNames="transition">
        <Overlay>
          <OverlayGrid>
            <CSSTransition
              in={open}
              timeout={500}
              classNames="transition"
              appear
            >
              <OverlayGridLeft>
                {pages.map((page) => {
                  return (
                    <Link key={page.href} href={page.href} passHref>
                      <OverlayLink data-text={page.title} onClick={toggleMenu}>
                        {page.title}
                      </OverlayLink>
                    </Link>
                  );
                })}
                <BottomBar>
                  <Image
                    src="/static/images/avatar.webp"
                    alt="Isaac Bythewood"
                    width={50}
                    height={50}
                  />
                  <Bar />
                </BottomBar>
              </OverlayGridLeft>
            </CSSTransition>
            <CSSTransition
              in={open}
              timeout={500}
              classNames="transition"
              appear
            >
              <OverlayGridRight>
                <Image
                  src="/static/images/art/006.jpg"
                  alt="#006 Molten Copper"
                  loading="lazy"
                  layout="fill"
                />
              </OverlayGridRight>
            </CSSTransition>
          </OverlayGrid>
        </Overlay>
      </CSSTransition>
    </>
  );
};

export default Menu;

const Hamburger = styled.button`
  position: fixed;
  top: 30px;
  right: 0;
  padding: 20px 15px;
  background: white;
  z-index: 5001;
  border: none;
  cursor: pointer;

  &:hover * {
    width: 30px !important;
  }

  @media (${(props) => props.theme.breakpoints.tablet}) {
    top: 0;
    padding-bottom: 21px;
  }
`;

const Patty = styled.div`
  background: black;
  width: 30px;
  height: 3px;
  margin-bottom: 5px;
  margin-left: auto;
  transition-duration: 250ms;
  transition-property: width;

  &:last-child {
    margin-bottom: 0;
  }
`;

const Overlay = styled.div`
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: -5000;

  &.transition-enter {
    z-index: 5000;
  }

  &.transition-enter-active {
    z-index: 5000;
  }

  &.transition-enter-done {
    z-index: 5000;
  }

  &.transition-exit {
    z-index: 5000;
  }

  &.transition-exit-active {
    z-index: 5000;
  }

  &.transition-exit-done {
    z-index: -5000;
  }
`;

const OverlayGrid = styled.div`
  display: grid;
  grid-template-columns: 60% 40%;

  @media (${(props) => props.theme.breakpoints.mobile}) {
    grid-template-columns: 100%;
  }
`;

const OverlayGridLeft = styled.div`
  grid-area: 1/1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  background: white;
  transition-duration: 500ms;
  transition-property: transform;
  transform: translateX(-100%);

  &.transition-enter {
    transform: translateX(-100%);
  }

  &.transition-enter-active {
    transform: translateX(0);
  }

  &.transition-enter-done {
    transform: translateX(0);
  }

  &.transition-exit {
    transform: translateX(0);
  }

  &.transition-exit-active {
    transform: translateX(-100%);
  }

  &.transition-exit-done {
    transform: translateX(-100%);
  }
`;

const OverlayGridRight = styled.div`
  grid-area: 1/2;
  height: 100vh;
  overflow: hidden;
  transition-duration: 500ms;
  transition-property: transform;
  transform: translateX(100%);

  &.transition-enter {
    transform: translateX(100%);
  }

  &.transition-enter-active {
    transform: translateX(0);
  }

  &.transition-enter-done {
    transform: translateX(0);
  }

  &.transition-exit {
    transform: translateX(0);
  }

  &.transition-exit-active {
    transform: translateX(100%);
  }

  &.transition-exit-done {
    transform: translateX(100%);
  }

  img {
    object-fit: cover;
    height: 100vh;
  }
`;

const OverlayLink = styled.a`
  font-weight: 900;
  text-decoration: none;
  margin-bottom: 10px;
  font-size: 3em;
  color: black;
  position: relative;

  &:last-child {
    margin-bottom: 0;
  }

  &::before {
    content: attr(data-text);
    color: white;
    position: absolute;
    width: 0;
    left: 0;
    bottom: 3px;
    height: 27px;
    background-color: black;
    transition-property: width;
    transition-duration: 200ms;
    line-height: 0;
    overflow: hidden;
  }

  &:hover {
    &::before {
      width: 100%;
    }
  }
`;

const BottomBar = styled.div`
  display: flex;
  width: 100%;
  position: absolute;
  left: 20px;
  bottom: 20px;
  align-items: center;
`;

const Bar = styled.div`
  width: 100%;
  height: 1px;
  background: rgba(0, 0, 0, 0.3);
  margin-left: 40px;
  margin-right: 60px;
`;
<commit_msg>Add more links to menu<commit_after>import React, { useState } from "react";

import { CSSTransition } from "react-transition-group";
import Image from "next/image";
import Link from "next/link";
import styled from "styled-components";

const Menu = () => {
  const [open, setOpen] = useState(false);
  const pages = [
    { num: "000", href: "/", title: "Home" },
    { num: "001", href: "/about", title: "About" },
    { num: "002", href: "/code", title: "Code" },
    { num: "003", href: "/art", title: "Art" },
    { num: "004", href: "/contact", title: "Contact" },
  ];

  const toggleMenu = () => {
    if (open === false) {
      setOpen(true);
      document.body.style.overflowY = "hidden";
    } else {
      setOpen(false);
      document.body.style.overflowY = "scroll";
    }
  };

  return (
    <>
      <Hamburger onClick={toggleMenu} aria-label="Hamburger">
        <Patty style={{ width: "15px" }} />
        <Patty />
        <Patty style={{ width: "20px" }} />
      </Hamburger>
      <CSSTransition in={open} timeout={500} classNames="transition">
        <Overlay>
          <OverlayGrid>
            <CSSTransition
              in={open}
              timeout={500}
              classNames="transition"
              appear
            >
              <OverlayGridLeft>
                <TopBar>
                  <Link href="https://blog.bythewood.me/" passHref>
                    <TopLink>Blog</TopLink>
                  </Link>
                  <Link href="https://status.bythewood.me/" passHref>
                    <TopLink>Status</TopLink>
                  </Link>
                  <Link href="https://analytics.bythewood.me/" passHref>
                    <TopLink>Analytics</TopLink>
                  </Link>
                  <Link href="https://github.com/overshard" passHref>
                    <TopLink>GitHub</TopLink>
                  </Link>
                  <Bar />
                </TopBar>
                {pages.map((page) => {
                  return (
                    <Link key={page.href} href={page.href} passHref>
                      <OverlayLink data-text={page.title} onClick={toggleMenu}>
                        {page.title}
                      </OverlayLink>
                    </Link>
                  );
                })}
                <BottomBar>
                  <Image
                    src="/static/images/avatar.webp"
                    alt="Isaac Bythewood"
                    width={50}
                    height={50}
                  />
                  <Bar />
                </BottomBar>
              </OverlayGridLeft>
            </CSSTransition>
            <CSSTransition
              in={open}
              timeout={500}
              classNames="transition"
              appear
            >
              <OverlayGridRight>
                <Image
                  src="/static/images/art/006.jpg"
                  alt="#006 Molten Copper"
                  loading="lazy"
                  layout="fill"
                />
              </OverlayGridRight>
            </CSSTransition>
          </OverlayGrid>
        </Overlay>
      </CSSTransition>
    </>
  );
};

export default Menu;

const Hamburger = styled.button`
  position: fixed;
  top: 30px;
  right: 0;
  padding: 20px 15px;
  background: white;
  z-index: 5001;
  border: none;
  cursor: pointer;

  &:hover * {
    width: 30px !important;
  }

  @media (${(props) => props.theme.breakpoints.tablet}) {
    top: 0;
    padding-bottom: 21px;
  }
`;

const Patty = styled.div`
  background: black;
  width: 30px;
  height: 3px;
  margin-bottom: 5px;
  margin-left: auto;
  transition-duration: 250ms;
  transition-property: width;

  &:last-child {
    margin-bottom: 0;
  }
`;

const Overlay = styled.div`
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  left: 0;
  z-index: -5000;

  &.transition-enter {
    z-index: 5000;
  }

  &.transition-enter-active {
    z-index: 5000;
  }

  &.transition-enter-done {
    z-index: 5000;
  }

  &.transition-exit {
    z-index: 5000;
  }

  &.transition-exit-active {
    z-index: 5000;
  }

  &.transition-exit-done {
    z-index: -5000;
  }
`;

const OverlayGrid = styled.div`
  display: grid;
  grid-template-columns: 60% 40%;

  @media (${(props) => props.theme.breakpoints.mobile}) {
    grid-template-columns: 100%;
  }
`;

const OverlayGridLeft = styled.div`
  grid-area: 1/1;
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  background: white;
  transition-duration: 500ms;
  transition-property: transform;
  transform: translateX(-100%);

  &.transition-enter {
    transform: translateX(-100%);
  }

  &.transition-enter-active {
    transform: translateX(0);
  }

  &.transition-enter-done {
    transform: translateX(0);
  }

  &.transition-exit {
    transform: translateX(0);
  }

  &.transition-exit-active {
    transform: translateX(-100%);
  }

  &.transition-exit-done {
    transform: translateX(-100%);
  }
`;

const OverlayGridRight = styled.div`
  grid-area: 1/2;
  height: 100vh;
  overflow: hidden;
  transition-duration: 500ms;
  transition-property: transform;
  transform: translateX(100%);

  &.transition-enter {
    transform: translateX(100%);
  }

  &.transition-enter-active {
    transform: translateX(0);
  }

  &.transition-enter-done {
    transform: translateX(0);
  }

  &.transition-exit {
    transform: translateX(0);
  }

  &.transition-exit-active {
    transform: translateX(100%);
  }

  &.transition-exit-done {
    transform: translateX(100%);
  }

  img {
    object-fit: cover;
    height: 100vh;
  }
`;

const OverlayLink = styled.a`
  font-weight: 900;
  text-decoration: none;
  margin-bottom: 10px;
  font-size: 3em;
  color: black;
  position: relative;

  &:last-child {
    margin-bottom: 0;
  }

  &::before {
    content: attr(data-text);
    color: white;
    position: absolute;
    width: 0;
    left: 0;
    bottom: 3px;
    height: 27px;
    background-color: black;
    transition-property: width;
    transition-duration: 200ms;
    line-height: 0;
    overflow: hidden;
  }

  &:hover {
    &::before {
      width: 100%;
    }
  }
`;

const TopBar = styled.div`
  display: flex;
  width: 100%;
  position: absolute;
  left: 20px;
  top: 20px;
  align-items: center;
  justify-content: start;
`;

const TopLink = styled.a`
  text-decoration: none;
  color: white;
  background-color: rgba(0, 0, 0, 1);
  padding: 0.25rem 0.5rem;
  margin-left: 1rem;
  transition: background-color 0.2s ease-in-out, color 0.2s ease-in-out;
  font-family: ui-monospace, Menlo, Monaco, "Cascadia Mono", "Segoe UI Mono",
    "Roboto Mono", "Oxygen Mono", "Ubuntu Monospace", "Source Code Pro",
    "Fira Mono", "Droid Sans Mono", "Courier New", monospace;

  &:hover {
    background-color: rgba(0, 0, 0, 0.1);
    color: black;
  }

  @media (${(props) => props.theme.breakpoints.mobile}) {
    font-size: 0.8em;
    margin-left: 0.5rem;
  }
`;

const BottomBar = styled.div`
  display: flex;
  width: 100%;
  position: absolute;
  left: 20px;
  bottom: 20px;
  align-items: center;
`;

const Bar = styled.div`
  width: 100%;
  height: 1px;
  background: rgba(0, 0, 0, 0.3);
  margin-left: 40px;
  margin-right: 60px;
`;
<|endoftext|>


<commit_before>import React from 'react';
import Countdown from './countdown/countdown';

class Quiz extends React.Component {
	constructor(props) {
		super(props);
		this.state = {
			questionsWithShuffledAnswers: [],
      currentQuestion: 0,
      initialCountdownTime: 20,
      timePerQuestion: {},
      remainingTime: 20,
      displayCorrectness: false,
      displayCorrectnessCorrect: false
    }
    this.checkCorrectness = this.checkCorrectness.bind(this);
    this.shuffleAnswers = this.shuffleAnswers.bind(this);
    this.updateTimer = this.updateTimer.bind(this);
    this.advanceQuiz = this.advanceQuiz.bind(this);
	}

	componentWillReceiveProps(nextProps) {
		if (nextProps.questions) {
			this.shuffleAnswers(nextProps.questions);
		}
	}

	render() {
		const {questionsWithShuffledAnswers, currentQuestion, remainingTime, displayCorrectness} = this.state;
		let content = null;

		// if shuffleAnswer function finished running, display questions
		questionsWithShuffledAnswers.length < 1 ?
		content = ("Quiz is loading...") :
		content = questionsWithShuffledAnswers.map((question, i) => {
			return (

 { question.text }

					{ question.answers.map( (answer, index) => (
						<button key={index}
										value={answer}
										disabled={displayCorrectness}
										className="btn answer-btn"
										onClick={ (evt) => this.checkCorrectness(evt.target.value, currentQuestion) } >
							{ answer }
						</button>
					) ) }

					{ displayCorrectness === true && this.state.displayCorrectnessCorrect === true ?

you answered the question correctly
 : null }
					{ displayCorrectness === true && this.state.displayCorrectnessCorrect === false ?

you answered the question incorrectly
 : null }

			)
		});

		// displaying container for "content"
		return (

				{content}

				<Countdown currentQuestion={ currentQuestion }
									 amountOfQuestions= { questionsWithShuffledAnswers.length }
									 remainingTime={ remainingTime }
									 updateTimer={ this.updateTimer } />

		)
	}

	shuffleAnswers(questions) {
		const length = questions.length;
		// putting all the answers together in order to shuffle them
		let questionsWithShuffledAnswers = [];

		// the if statement part is necessary so that when component first mounts, the code does not break
		if (length < 1) {
			return;
		} else {
			// loop through all the questions and shuffle the answers
			for (let i = 0; i < length; i++) {
				let shuffledAnswers = [];
				let currentQuestion = questions[i].text;
				let currentSetOfAnswers = questions[i].answers;

				// push all the current answers into shuffledAnswers array
				currentSetOfAnswers.incorrect.map((incorrectAnswer) => shuffledAnswers.push(incorrectAnswer));
				shuffledAnswers.push(currentSetOfAnswers.correct);

				// shuffle shuffledAnswers array
				let currentIndex = shuffledAnswers.length;
				let temporaryValue;
				let randomIndex;

				// While there remain elements to shuffle...
				while (0 !== currentIndex) {

					// Pick a remaining element...
					randomIndex = Math.floor(Math.random() * currentIndex);
					currentIndex -= 1;

					// And swap it with the current element.
					temporaryValue = shuffledAnswers[currentIndex];
					shuffledAnswers[currentIndex] = shuffledAnswers[randomIndex];
					shuffledAnswers[randomIndex] = temporaryValue;
				}

				// push an object containing the shuffledAnswers & the question into the questionsWithShuffledAnswers array
				questionsWithShuffledAnswers.push({
					text: currentQuestion,
					answers: shuffledAnswers
				});
			}

			// update questionsWithShuffledAnswers and reset the countdown to initial time
			this.setState({
				questionsWithShuffledAnswers: questionsWithShuffledAnswers,
				remainingTime: this.state.initialCountdownTime
			})
		}
	}

	updateTimer(newTime) {
		this.setState({
			remainingTime: newTime
		});
	}

	displayCorrectAnswer(correctAnswer){
		this.setState({
			displayCorrectness: true
		});
	}

	advanceQuiz(currentQuestion){
		// move advancing quiz by updating state here so it can be called when appropriate
		this.setState({
			currentQuestion: (currentQuestion + 1),
			remainingTime: this.state.initialCountdownTime,
			displayCorrectness: false
		})
	}

	checkCorrectness(answer, index) {
		const { timePerQuestion, currentQuestion, remainingTime } = this.state;
		let correctAnswer = this.props.questions[index].answers.correct;

		this.displayCorrectAnswer(correctAnswer);

		// if the correct answer is chosen, pair the remaining time
		// and the question index in an object and add it to timePerQuestion object
		if (answer === correctAnswer) {
			timePerQuestion[index] = remainingTime;
			this.setState({
				timePerQuestion: timePerQuestion,
				displayCorrectnessCorrect: true
			});
			// this.advanceQuiz(currentQuestion);

		} else {
		// else if the wrong answer is chosen, pair 0 with the question index
		// and add it to timePerQuestion object
			timePerQuestion[index] = 0;
			this.setState({
				timePerQuestion: timePerQuestion
			});
			// this.advanceQuiz(currentQuestion);
		}

		console.log('quiz.js: here are the time per question: ', timePerQuestion);
	}

}

export default Quiz;<commit_msg>feat: show correct answer and advance quiz only when user ready<commit_after>import React from 'react';
import Countdown from './countdown/countdown';

class Quiz extends React.Component {
	constructor(props) {
		super(props);
		this.state = {
			questionsWithShuffledAnswers: [],
      currentQuestion: 0,
      initialCountdownTime: 20,
      timePerQuestion: {},
      remainingTime: 20,
      displayCorrectness: false,
      displayCorrectnessCorrect: false,
      totalScoreForQuiz: 0,
      correctAnswer: null
    }
    this.checkCorrectness = this.checkCorrectness.bind(this);
    this.shuffleAnswers = this.shuffleAnswers.bind(this);
    this.updateTimer = this.updateTimer.bind(this);
    this.advanceQuiz = this.advanceQuiz.bind(this);
	}

	componentWillReceiveProps(nextProps) {
		if (nextProps.questions) {
			this.shuffleAnswers(nextProps.questions);
		}
	}

	render() {
		const {questionsWithShuffledAnswers, currentQuestion, remainingTime, displayCorrectness, timePerQuestion } = this.state;
		let content = null;

		// if shuffleAnswer function finished running, display questions
		questionsWithShuffledAnswers.length < 1 ?
		content = ("Quiz is loading...") :
		content = questionsWithShuffledAnswers.map((question, i) => {
			return (

 { question.text }

					{ question.answers.map( (answer, index) => (
						<button key={index}
										value={answer}
										disabled={displayCorrectness}
										className={answer + " btn answer-btn"}
										onClick={ (evt) => this.checkCorrectness(evt.target.value, currentQuestion) } >
							{ answer }
						</button>
					) ) }

					{ displayCorrectness === true && this.state.displayCorrectnessCorrect === true ?

you answered the question correctly, you get {timePerQuestion[i]} points

								<button onClick={(evt) => this.advanceQuiz(evt.target.value, currentQuestion)}>Next Question</button>

						: null }
					{ displayCorrectness === true && this.state.displayCorrectnessCorrect === false ?

you answered the question incorrectly

the correct answer is {this.state.correctAnswer}

								<button onClick={(evt) => this.advanceQuiz(evt.target.value, currentQuestion)}>Next Question</button>

						: null }

			)
		});

		// displaying container for "content"
		return (

				{content}

				<Countdown currentQuestion={ currentQuestion }
									 amountOfQuestions= { questionsWithShuffledAnswers.length }
									 remainingTime={ remainingTime }
									 updateTimer={ this.updateTimer } />

		)
	}

	shuffleAnswers(questions) {
		const length = questions.length;
		// putting all the answers together in order to shuffle them
		let questionsWithShuffledAnswers = [];

		// the if statement part is necessary so that when component first mounts, the code does not break
		if (length < 1) {
			return;
		} else {
			// loop through all the questions and shuffle the answers
			for (let i = 0; i < length; i++) {
				let shuffledAnswers = [];
				let currentQuestion = questions[i].text;
				let currentSetOfAnswers = questions[i].answers;

				// push all the current answers into shuffledAnswers array
				currentSetOfAnswers.incorrect.map((incorrectAnswer) => shuffledAnswers.push(incorrectAnswer));
				shuffledAnswers.push(currentSetOfAnswers.correct);

				// shuffle shuffledAnswers array
				let currentIndex = shuffledAnswers.length;
				let temporaryValue;
				let randomIndex;

				// While there remain elements to shuffle...
				while (0 !== currentIndex) {

					// Pick a remaining element...
					randomIndex = Math.floor(Math.random() * currentIndex);
					currentIndex -= 1;

					// And swap it with the current element.
					temporaryValue = shuffledAnswers[currentIndex];
					shuffledAnswers[currentIndex] = shuffledAnswers[randomIndex];
					shuffledAnswers[randomIndex] = temporaryValue;
				}

				// push an object containing the shuffledAnswers & the question into the questionsWithShuffledAnswers array
				questionsWithShuffledAnswers.push({
					text: currentQuestion,
					answers: shuffledAnswers
				});
			}

			// update questionsWithShuffledAnswers and reset the countdown to initial time
			this.setState({
				questionsWithShuffledAnswers: questionsWithShuffledAnswers,
				remainingTime: this.state.initialCountdownTime
			})
		}
	}

	updateTimer(newTime) {
		this.setState({
			remainingTime: newTime
		});
	}

	displayCorrectAnswer(correctAnswer){
		this.setState({
			displayCorrectness: true,
			correctAnswer: correctAnswer
		});
	}

	advanceQuiz(index, currentQuestion){
		// move advancing quiz by updating state here so it can be called when appropriate
		this.setState({
			currentQuestion: (currentQuestion + 1),
			remainingTime: this.state.initialCountdownTime,
			displayCorrectness: false
		})
	}

	checkCorrectness(answer, index) {
		const { timePerQuestion, currentQuestion, remainingTime } = this.state;
		let correctAnswer = this.props.questions[index].answers.correct;

		this.displayCorrectAnswer(correctAnswer);

		// if the correct answer is chosen, pair the remaining time
		// and the question index in an object and add it to timePerQuestion object
		if (answer === correctAnswer) {
			timePerQuestion[index] = remainingTime;
			this.setState({
				timePerQuestion: timePerQuestion,
				displayCorrectnessCorrect: true
			});
			// this.advanceQuiz(currentQuestion);

		} else {
		// else if the wrong answer is chosen, pair 0 with the question index
		// and add it to timePerQuestion object
			timePerQuestion[index] = 0;
			this.setState({
				timePerQuestion: timePerQuestion
			});
			// this.advanceQuiz(currentQuestion);
		}

		console.log('quiz.js: here are the times per question: ', timePerQuestion);
	}

}

export default Quiz;<|endoftext|>


<commit_before>/*globals define, _, $*/
/*jshint browser: true, camelcase: false*/

/**
 * @author brollb / https://github.com/brollb
 */

define([
    'js/Constants',
    'js/NodePropertyNames',
    'widgets/EasyDAG/EasyDAGWidget.DecoratorBase',
    'css!./LayerDecorator.EasyDAGWidget.css',
    'd3'
], function (
    CONSTANTS,
    nodePropertyNames,
    DecoratorBase
) {

    'use strict';

    var LayerDecorator,
        DECORATOR_ID = 'LayerDecorator',

    LayerDecorator = function (options) {
        var opts = _.extend({}, options);

        this._node = options.node;
        this._attrToDisplayName = {};
        this.attributeFields = {};
        this.setAttributes();

        this.color = this.color || '#ff9800';
        // Set width, height values
        if (!this.size) {
            this.size = {
                width: 100,
                height: 50
            };
        }

        if (!this.dense) {  // condensed size
            this.dense = {};
            this.dense.width = this.size.width;
            this.dense.height = this.size.height;
        }

        this.width = this.dense.width;
        this.height = this.dense.height;

        DecoratorBase.call(this, options);
        this.initialize();
        this.condense();
        this.logger.debug('LayerDecorator ctor');
    };

    _.extend(LayerDecorator.prototype, DecoratorBase.prototype);

    LayerDecorator.prototype.initialize = function() {
        this.width = this.dense.width;
        this.height = this.dense.height;

        this.$body = this.$el
            .append('path')
            .attr('class', 'layer-decorator');

        this.$name = this.$el.append('text')
            .attr('class', 'name')
            .style('font-size', '16px')  // FIXME: Move this to css
            .attr('fill', 'black');

        this.$attributes = this.$el.append('g')
            .attr('fill', '#222222');
    };

    LayerDecorator.prototype.expand = function() {
        var height,
            rx = this.size.width/2,
            ry = this.size.height/2,
            attrNames = Object.keys(this._attributes),
            displayName,
            path,
            textHeight = 15,

            // Attributes
            initialY = 20,
            attributeMargin = 10,
            leftCol,
            rightCol,
            y = 5;

        // Get the height from the number of attributes
        height = y + this.dense.height + textHeight*attrNames.length;

        path = [
            `M${-rx},0`,
            `l ${this.size.width} 0`,
            `l 0 ${height}`,
            `l -${this.size.width} 0`,
            `l 0 -${height}`
        ].join(' ');

        this.$body
            .attr('d', path);

        // Shift name down
        this.$name.attr('y', '20');

        // Add the attribute fields
        y += initialY;
        leftCol = -rx + attributeMargin;
        rightCol = rx - attributeMargin;
        this.$attributes.remove();
        this.$attributes = this.$el.append('g')
            .attr('fill', '#222222');
        for (var i = attrNames.length; i--;) {
            // Create two text boxes (2nd is editable)
            y += textHeight;
            displayName = this._attrToDisplayName[attrNames[i]];
            // Attribute name
            this.$attributes.append('text')
                .attr('y', y)
                .attr('x', leftCol)
                .attr('font-style', 'italic')  // FIXME: move this to css
                .attr('class', 'attr-title')
                .attr('text-anchor', 'start')
                .text(`${displayName}: `);

            // Attribute value
            this.attributeFields[attrNames[i]] = this.$attributes.append('text')
                .attr('y', y)
                .attr('x', rightCol)
                .attr('text-anchor', 'end')  // FIXME: move this to css
                .text(`${this._attributes[attrNames[i]]}`)
                .on('click', this.editAttribute.bind(this, attrNames[i], rightCol, y))
        }

        // Update width, height
        this.height = height;
        this.width = this.size.width;
        this.expanded = true;
        this.$el
            .attr('transform', `translate(${this.width/2}, 0)`);
        this.onResize();
    };

    LayerDecorator.prototype.condense = function() {
        var path,
            rx = this.dense.width/2,
            ry = this.dense.height/2;

        path = [
            `M${-rx},0`,
            `a${rx},${ry} 0 1,0 ${this.dense.width},0`,
            `a${rx},${ry} 0 1,0 -${this.dense.width},0`
        ].join(' ');

        this.$body
            .attr('d', path);

        // Clear the attributes
        this.$attributes.remove();
        this.$attributes = this.$el.append('g')
            .attr('fill', '#222222');

        this.height = this.dense.height;
        this.width = this.dense.width;

        this.$name.attr('y', '0');

        this.$el
            .attr('transform', `translate(${this.width/2}, ${this.height/2})`);
        this.expanded = false;
        this.onResize();
    };

    LayerDecorator.prototype.onSelect = function() {
        this.expand();
    };

    LayerDecorator.prototype.onDeselect = function() {
        this.condense();
    };

    LayerDecorator.prototype.setAttributes = function() {
        var attrNames = Object.keys(this._node.attributes),
            name;
        this.name = this._node.baseName;  // Using the base node name for title

        this._attributes = {};
        for (var i = attrNames.length; i--;) {
            name = this.getAttributeDisplayName(attrNames[i]);
            if (name !== null) {
                this._attrToDisplayName[attrNames[i]] = name;
                this._attributes[attrNames[i]] = this._node.attributes[attrNames[i]];
            }
        }
    };

    LayerDecorator.prototype.getAttributeDisplayName = function(name) {
        if (name === 'name') {
            return null;
        }
        return name.replace(/_/g, ' ');
    };

    LayerDecorator.prototype.editAttribute = function(attr, x, y) {
        // Edit the node's attribute
        var html = this.attributeFields[attr][0][0],
            position = html.getBoundingClientRect(),

            width = Math.max(position.right-position.left, 15),
            container = $('<div>'),
            parentHtml = $('body'),
            values = this.getEnumValues(attr);

        // foreignObject was not working so we are using a tmp container
        // instead
        container.css('top', position.top);
        container.css('left', position.left);
        container.css('position', 'absolute');
        container.css('width', width);
        container.attr('id', 'CONTAINER-TMP');

        $(parentHtml).append(container);

        // Get the attribute schema
        if (values) {
            var dropdown = document.createElement('select'),
                option,
                self = this,
                arrowMargin = 30;

            for (var i = values.length; i--;) {
                option = document.createElement('option');
                option.setAttribute('value', values[i]);
                option.innerHTML = values[i];
                // set the default
                if (this._attributes[attr] === values[i]) {
                    option.setAttribute('selected', 'selected');
                }
                dropdown.appendChild(option);
            }
            dropdown.style.width = (width + arrowMargin)+ 'px';
            container.append(dropdown);
            dropdown.focus();
            // on select
            dropdown.onblur = function() {
                if (this.value) {
                    self.saveAttribute(attr, this.value);
                }
                container.remove();
            };

        } else {
            container.editInPlace({
                    enableEmpty: true,
                    value: this._attributes[attr],
                    css: {'z-index': 10000,
                          'id': 'asdf',
                          'width': width,
                          'xmlns': 'http://www.w3.org/1999/xhtml'},
                    onChange: (oldValue, newValue) => {
                        this.saveAttribute(attr, newValue);
                    },
                    onFinish: function () {
                        $(this).remove();
                    }
                });
        }
    };

    LayerDecorator.prototype.render = function() {
        this.$body
            .transition()
            .attr('stroke', this.color)
            .attr('style', `fill:${this.color}`);

        this.$name
            .attr('text-anchor', 'middle')
            .text(this.name);
    };

    LayerDecorator.prototype.update = function(node) {
        this._node = node;
        // Update the attributes
        this.setAttributes();
        if (this.expanded) {
            this.expand();
        } else {
            this.condense();
        }
    };

    LayerDecorator.prototype.DECORATORID = DECORATOR_ID;

    /*********************** OVERRIDE DiagramDesignerWidgetDecoratorBase MEMBERS **************************/

    return LayerDecorator;
});
<commit_msg>Removed expansion of attribute-less layers. Fixes #162<commit_after>/*globals define, _, $*/
/*jshint browser: true, camelcase: false*/

/**
 * @author brollb / https://github.com/brollb
 */

define([
    'js/Constants',
    'js/NodePropertyNames',
    'widgets/EasyDAG/EasyDAGWidget.DecoratorBase',
    'css!./LayerDecorator.EasyDAGWidget.css',
    'd3'
], function (
    CONSTANTS,
    nodePropertyNames,
    DecoratorBase
) {

    'use strict';

    var LayerDecorator,
        DECORATOR_ID = 'LayerDecorator',

    LayerDecorator = function (options) {
        var opts = _.extend({}, options);

        this._node = options.node;
        this._attrToDisplayName = {};
        this.attributeFields = {};
        this.setAttributes();

        this.color = this.color || '#ff9800';
        // Set width, height values
        if (!this.size) {
            this.size = {
                width: 100,
                height: 50
            };
        }

        if (!this.dense) {  // condensed size
            this.dense = {};
            this.dense.width = this.size.width;
            this.dense.height = this.size.height;
        }

        this.width = this.dense.width;
        this.height = this.dense.height;

        DecoratorBase.call(this, options);
        this.initialize();
        this.condense();
        this.logger.debug('LayerDecorator ctor');
    };

    _.extend(LayerDecorator.prototype, DecoratorBase.prototype);

    LayerDecorator.prototype.initialize = function() {
        this.width = this.dense.width;
        this.height = this.dense.height;

        this.$body = this.$el
            .append('path')
            .attr('class', 'layer-decorator');

        this.$name = this.$el.append('text')
            .attr('class', 'name')
            .style('font-size', '16px')  // FIXME: Move this to css
            .attr('fill', 'black');

        this.$attributes = this.$el.append('g')
            .attr('fill', '#222222');
    };

    LayerDecorator.prototype.expand = function() {
        var height,
            rx = this.size.width/2,
            ry = this.size.height/2,
            attrNames = Object.keys(this._attributes),
            displayName,
            path,
            textHeight = 15,

            // Attributes
            initialY = 20,
            attributeMargin = 10,
            leftCol,
            rightCol,
            y = 5;

        // Only expand if the node has attributes to show
        if (attrNames.length > 0) {

            // Get the height from the number of attributes
            height = y + this.dense.height + textHeight*attrNames.length;

            path = [
                `M${-rx},0`,
                `l ${this.size.width} 0`,
                `l 0 ${height}`,
                `l -${this.size.width} 0`,
                `l 0 -${height}`
            ].join(' ');

            this.$body
                .attr('d', path);

            // Shift name down
            this.$name.attr('y', '20');

            // Add the attribute fields
            y += initialY;
            leftCol = -rx + attributeMargin;
            rightCol = rx - attributeMargin;
            this.$attributes.remove();
            this.$attributes = this.$el.append('g')
                .attr('fill', '#222222');
            for (var i = attrNames.length; i--;) {
                // Create two text boxes (2nd is editable)
                y += textHeight;
                displayName = this._attrToDisplayName[attrNames[i]];
                // Attribute name
                this.$attributes.append('text')
                    .attr('y', y)
                    .attr('x', leftCol)
                    .attr('font-style', 'italic')  // FIXME: move this to css
                    .attr('class', 'attr-title')
                    .attr('text-anchor', 'start')
                    .text(`${displayName}: `);

                // Attribute value
                this.attributeFields[attrNames[i]] = this.$attributes.append('text')
                    .attr('y', y)
                    .attr('x', rightCol)
                    .attr('text-anchor', 'end')  // FIXME: move this to css
                    .text(`${this._attributes[attrNames[i]]}`)
                    .on('click', this.editAttribute.bind(this, attrNames[i], rightCol, y))
            }

            // Update width, height
            this.height = height;
            this.width = this.size.width;
            this.expanded = true;
            this.$el
                .attr('transform', `translate(${this.width/2}, 0)`);
        }

        this.onResize();
    };

    LayerDecorator.prototype.condense = function() {
        var path,
            rx = this.dense.width/2,
            ry = this.dense.height/2;

        path = [
            `M${-rx},0`,
            `a${rx},${ry} 0 1,0 ${this.dense.width},0`,
            `a${rx},${ry} 0 1,0 -${this.dense.width},0`
        ].join(' ');

        this.$body
            .attr('d', path);

        // Clear the attributes
        this.$attributes.remove();
        this.$attributes = this.$el.append('g')
            .attr('fill', '#222222');

        this.height = this.dense.height;
        this.width = this.dense.width;

        this.$name.attr('y', '0');

        this.$el
            .attr('transform', `translate(${this.width/2}, ${this.height/2})`);
        this.expanded = false;
        this.onResize();
    };

    LayerDecorator.prototype.onSelect = function() {
        this.expand();
    };

    LayerDecorator.prototype.onDeselect = function() {
        this.condense();
    };

    LayerDecorator.prototype.setAttributes = function() {
        var attrNames = Object.keys(this._node.attributes),
            name;
        this.name = this._node.baseName;  // Using the base node name for title

        this._attributes = {};
        for (var i = attrNames.length; i--;) {
            name = this.getAttributeDisplayName(attrNames[i]);
            if (name !== null) {
                this._attrToDisplayName[attrNames[i]] = name;
                this._attributes[attrNames[i]] = this._node.attributes[attrNames[i]];
            }
        }
    };

    LayerDecorator.prototype.getAttributeDisplayName = function(name) {
        if (name === 'name') {
            return null;
        }
        return name.replace(/_/g, ' ');
    };

    LayerDecorator.prototype.editAttribute = function(attr, x, y) {
        // Edit the node's attribute
        var html = this.attributeFields[attr][0][0],
            position = html.getBoundingClientRect(),

            width = Math.max(position.right-position.left, 15),
            container = $('<div>'),
            parentHtml = $('body'),
            values = this.getEnumValues(attr);

        // foreignObject was not working so we are using a tmp container
        // instead
        container.css('top', position.top);
        container.css('left', position.left);
        container.css('position', 'absolute');
        container.css('width', width);
        container.attr('id', 'CONTAINER-TMP');

        $(parentHtml).append(container);

        // Get the attribute schema
        if (values) {
            var dropdown = document.createElement('select'),
                option,
                self = this,
                arrowMargin = 30;

            for (var i = values.length; i--;) {
                option = document.createElement('option');
                option.setAttribute('value', values[i]);
                option.innerHTML = values[i];
                // set the default
                if (this._attributes[attr] === values[i]) {
                    option.setAttribute('selected', 'selected');
                }
                dropdown.appendChild(option);
            }
            dropdown.style.width = (width + arrowMargin)+ 'px';
            container.append(dropdown);
            dropdown.focus();
            // on select
            dropdown.onblur = function() {
                if (this.value) {
                    self.saveAttribute(attr, this.value);
                }
                container.remove();
            };

        } else {
            container.editInPlace({
                    enableEmpty: true,
                    value: this._attributes[attr],
                    css: {'z-index': 10000,
                          'id': 'asdf',
                          'width': width,
                          'xmlns': 'http://www.w3.org/1999/xhtml'},
                    onChange: (oldValue, newValue) => {
                        this.saveAttribute(attr, newValue);
                    },
                    onFinish: function () {
                        $(this).remove();
                    }
                });
        }
    };

    LayerDecorator.prototype.render = function() {
        this.$body
            .transition()
            .attr('stroke', this.color)
            .attr('style', `fill:${this.color}`);

        this.$name
            .attr('text-anchor', 'middle')
            .text(this.name);
    };

    LayerDecorator.prototype.update = function(node) {
        this._node = node;
        // Update the attributes
        this.setAttributes();
        if (this.expanded) {
            this.expand();
        } else {
            this.condense();
        }
    };

    LayerDecorator.prototype.DECORATORID = DECORATOR_ID;

    /*********************** OVERRIDE DiagramDesignerWidgetDecoratorBase MEMBERS **************************/

    return LayerDecorator;
});
<|endoftext|>