Exercise 7Extra Credit Components

Property Status

PropertyStatus.cmp
<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId" access="global">

	<aura:attribute name="recordId" type="Id" />
	<aura:attribute name="property" type="Property__c" />

	<!-- LDS to fetch the record value -->
	<force:recordData aura:id="propertyService" recordId="{!v.recordId}" targetFields="{!v.property}" layoutType="FULL" mode="EDIT" />

	<div class="slds-card">
		<lightning:picklistPath aura:id="picklistPath" recordId="{!v.recordId}" picklistFieldApiName="Status__c" onselect="{!c.handleSelect}" />
	</div>
</aura:component>
PropertyStatusController.js
({
	handleSelect: function(component, event, helper) {
		var stepName = event.getParam("detail").value;
		component.set("v.property.Status__c", stepName);
		component.find("propertyService")
			.saveRecord($A.getCallback(function(result) {
				// alert(result.state);
				if (result.state === "SUCCESS" || result.state === "DRAFT") {
					var toastEvent = $A.get("e.force:showToast");
					toastEvent.setParams({
						"title": "Success!",
						"message": "The property's status has been updated.",
						"type": "success"
					});
					toastEvent.fire();
				}
			}));
	}
})
PropertyStatus.css
.THIS .slds-icon-text-default {
    fill: rgb(255, 255, 255);
}
PropertyStatus.svg
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg width="100px" height="100px" viewBox="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
<g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
	<path d="M120,108 C120,114.6 114.6,120 108,120 L12,120 C5.4,120 0,114.6 0,108 L0,12 C0,5.4 5.4,0 12,0 L108,0 C114.6,0 120,5.4 120,12 L120,108 L120,108 Z" id="Shape" fill="#ff0000"/>
	<path fill="#fff" d="m15.2 68.2l14.2-17.2c0.4-0.7 0.4-1.5 0-2.1l-14.2-17c-0.1-0.2-0.2-0.4-0.2-0.6 0-0.6 0.5-1 1-1h20.7c0.6 0 1.1 0.2 1.4 0.7l14.9 18c0.4 0.6 0.4 1.4 0 2.1l-14.8 18c-0.3 0.4-0.9 0.7-1.4 0.7h-20.7c-0.6 0-1-0.4-1-1-0.1-0.2 0-0.5 0.1-0.6z m31.6 0l14.1-17.2c0.4-0.7 0.4-1.5 0-2.1l-14.2-17c-0.1-0.2-0.2-0.4-0.2-0.6 0-0.6 0.5-1 1-1h20.7c0.6 0 1.1 0.2 1.4 0.7l14.9 18c0.4 0.6 0.4 1.4 0 2.1l-14.8 18c-0.3 0.4-0.9 0.7-1.4 0.7h-20.7c-0.6 0-1-0.4-1-1 0-0.2 0.1-0.5 0.2-0.6z"></path>
</g>
</svg>

Contract Upload

ContractUpload.cmp
<aura:component implements="flexipage:availableForRecordHome,force:hasRecordId">
	<aura:attribute name="myRecordId" type="String" description="Record to which the files should be attached" />
	<lightning:card title="Upload Contract" iconName="custom:custom15">
		<div class="slds-p-left_large slds-p-right_medium slds-align_absolute-center">
			<lightning:fileUpload label="Please upload the signed contracts and other files." recordId="{!v.recordId}" accept="['.pdf', '.png']" onuploadfinished="{!c.handleFilesChange}" class="slds-show" />
		</div>
	</lightning:card>
</aura:component>
ContractUploadController.js
({
    handleUploadFinished: function (cmp, event) {
        // Get the list of uploaded files
        var uploadedFiles = event.getParam("files");
        alert("Files uploaded : " + uploadedFiles.length);
    }
})

Days on the Market

DaysOnTheMarket.cmp
<aura:component implements="force:hasRecordId,flexipage:availableForAllPageTypes" access="global">
    
    <aura:attribute name="recordId" type="Id" />
    <aura:attribute name="property" type="Property__c" /> 
    <aura:attribute name="formattedDateListed" type="String" /> 
    <aura:attribute name="status" type="String" /> 
    
    <force:recordData aura:id="service" 
                      recordId="{!v.recordId}"
                      targetFields="{!v.property}" 
                      fields="Id, Date_Listed__c, Days_On_Market__c" 
                      recordUpdated="{!c.recordUpdated}"
                      />
    <lightning:card iconName="standard:event" title="Days on the Market">
        <div class="indent">
        <lightning:layout >
            <lightning:layoutitem class="{! 'days-block ' + v.status + ' bgcolor'}">
                <div class="days">{!v.property.Days_On_Market__c}</div>days
            </lightning:layoutitem>
            <lightning:layoutitem flexibility="grow" class="chart">
                <div class="{! 'bar ' + v.status }" style="{! 'width:' + v.property.Days_On_Market__c / 90 * 100 + '%' }"/>
                <div class="axis bgcolor">
                    <div><div class="legend">{!v.formattedDateListed}</div></div>
                    <div><div class="legend">30 days</div></div>
                    <div><div class="legend">60 days</div></div>
                </div>
            </lightning:layoutitem>
        </lightning:layout>
            </div>
    </lightning:card>
</aura:component>
DaysOnTheMarketController.js
({
	recordUpdated : function(component, event, helper) {
		var changeType = event.getParams().changeType;
        if (changeType === "LOADED" || changeType === "CHANGED") {
			helper.showDaysOnMarket(component);
        }
	}
})
DaysOnTheMarketHelper.js
({
	showDaysOnMarket : function(component) {
    	var property = component.get("v.property");
        var daysOnMarket = property.Days_On_Market__c;
        var status = "green";
        if (daysOnMarket > 60) {
            status = 'red';
        } else if (daysOnMarket > 30) {
            status = 'orange'
        }
        component.set("v.status", status);
        component.set("v.formattedDateListed", new Date(property.Date_Listed__c).toLocaleString('en-US', {month: 'short', year: 'numeric', day: 'numeric'}));
	}
})
DaysOnTheMarket.design
<design:component label="Days on the Market">
	
</design:component>
DaysOnTheMarket.css
.THIS .days-block {
    text-align: center;
    margin-right: 8px;
    padding: 8px 12px;
    border-radius: 0.25rem;
    border: solid 1px rgb(216, 221, 230);
} 
.THIS .indent {
    margin: 0 24px;
}
.THIS .bgcolor {
    background-color: #FFF;
}
.THIS .days-block.red {
    color: #C23934;
    border: solid 1px #C23934;
} 

.THIS .days-block.green {
    color: #00716B;
    border: solid 1px #00716B;
} 

.THIS .days-block.orange {
    color: #FFB75D;
    border: solid 1px #FFB75D;
} 

.THIS .days {
    font-size: 32px;
    line-height: 32px;
    font-weight: 300;
    margin-right: 12px;
    margin: 0;
    padding: 0;
} 

.THIS .chart {
    position: relative;
    height: 40px;
}

.THIS .bar {
    -webkit-transform: translate3d(0, 0, 0);
    transform: translate3d(0, 0, 0);
    height: 34px;
    width: 0;
    transition: all .5s ease-in-out;
    position: absolute;
    bottom: 0px;
    left: 0px;
    right: 0;
    z-index: 20;
}

.THIS .bar.green {
    background-color: #00716B;
}

.THIS .bar.orange {
    background-color: #FFB75D;
}

.THIS .bar.red {
    background-color: #C23934;
}

.THIS .axis {
    position: absolute;
    left: 0;
    right: 0;
    display: flex;
    bottom: 0;
    
}

.THIS .axis > div {
    height: 34px;
    flex: 1;
    border: solid 1px rgb(216, 221, 230);
    z-index: 20;
    position: relative;
}

.THIS .axis .legend {
    margin-top: 36px;
}
DaysOnTheMarket.svg
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 16.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
	 width="88.316px" height="88.318px" viewBox="0 0 88.316 88.318" enable-background="new 0 0 88.316 88.318" xml:space="preserve">
<g id="Layer_1_copy">
	<path fill="#E9696E" d="M88.316,73.268c0,8.312-6.738,15.051-15.054,15.051H15.05C6.737,88.319,0,81.581,0,73.268V15.052
		C0,6.74,6.737,0,15.05,0h58.215c8.312,0,15.054,6.74,15.054,15.052L88.316,73.268L88.316,73.268z"/>
</g>
<g id="Layer_5">
	<g>
		<path fill="#FFFFFF" d="M68.883,35.941H19.554c-0.963,0-1.806,0.842-1.806,1.805v29.478c0,2.646,2.166,4.812,4.812,4.812h43.312
			c2.647,0,4.812-2.165,4.812-4.812V37.746C70.687,36.783,69.844,35.941,68.883,35.941z M35.797,62.41
			c0,0.722-0.48,1.203-1.203,1.203h-4.812c-0.722,0-1.203-0.481-1.203-1.203v-4.812c0-0.723,0.481-1.203,1.203-1.203h4.812
			c0.723,0,1.203,0.48,1.203,1.203V62.41z M35.797,50.379c0,0.723-0.48,1.203-1.203,1.203h-4.812c-0.722,0-1.203-0.48-1.203-1.203
			v-4.812c0-0.723,0.481-1.203,1.203-1.203h4.812c0.723,0,1.203,0.48,1.203,1.203V50.379z M47.828,62.41
			c0,0.722-0.48,1.203-1.203,1.203h-4.812c-0.723,0-1.203-0.481-1.203-1.203v-4.812c0-0.723,0.48-1.203,1.203-1.203h4.812
			c0.723,0,1.203,0.48,1.203,1.203V62.41z M47.828,50.379c0,0.723-0.48,1.203-1.203,1.203h-4.812c-0.723,0-1.203-0.48-1.203-1.203
			v-4.812c0-0.723,0.48-1.203,1.203-1.203h4.812c0.723,0,1.203,0.48,1.203,1.203V50.379z M59.859,62.41
			c0,0.722-0.481,1.203-1.203,1.203h-4.812c-0.722,0-1.202-0.481-1.202-1.203v-4.812c0-0.723,0.48-1.203,1.202-1.203h4.812
			c0.722,0,1.203,0.48,1.203,1.203V62.41z M59.859,50.379c0,0.723-0.481,1.203-1.203,1.203h-4.812c-0.722,0-1.202-0.48-1.202-1.203
			v-4.812c0-0.723,0.48-1.203,1.202-1.203h4.812c0.722,0,1.203,0.48,1.203,1.203V50.379z M65.875,20.301h-6.016v-2.405
			c0-1.927-1.563-3.609-3.609-3.609c-1.925,0-3.608,1.564-3.608,3.609v2.405H35.797v-2.405c0-1.927-1.563-3.609-3.608-3.609
			c-1.925,0-3.609,1.564-3.609,3.609v2.405h-6.016c-2.647,0-4.812,2.166-4.812,4.812v3.008c0,0.962,0.842,1.805,1.806,1.805h49.327
			c0.963,0,1.806-0.842,1.806-1.805v-3.008C70.687,22.466,68.522,20.301,65.875,20.301z"/>
	</g>
</g>
</svg>