Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat/collections #7446

Merged
merged 16 commits into from
Sep 23, 2020
Merged
13 changes: 13 additions & 0 deletions app/assets/v2/css/grants/cart.css
Original file line number Diff line number Diff line change
Expand Up @@ -131,3 +131,16 @@
color: white !important;
font-weight: 600;
}

.middle-line {
width: 100%;
text-align: center;
border-bottom: 1px solid #ccc;
line-height: 0.1em;
margin: 10px 0 20px;
}

.middle-line span {
background-color: white;
padding:0 10px;
}
119 changes: 119 additions & 0 deletions app/assets/v2/css/grants/collection.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
.collection-item {
border-radius: 5px;
display: flex;
flex-direction: column;
border: 1px solid #D3D3D3;
background-color: var(--bg-shade-0);
}

.collection-item__content {
margin-top: 1.0625rem;
}

.collection-item__title {
line-height: 24px;
overflow-y: hidden;
font-weight: bold;
margin-bottom: 15px;
font-size: var(--fs-header);
}

.collection-item__title a {
color: #454545;
}

.collection-item__pitch {
color: #666666;
height: 3.8rem;
overflow: hidden;
line-height: 22px;
text-overflow: ellipsis;
}

.collection-item__owner {
align-items: center;
display: flex;
}

.collection-item__img--grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
}

.collection-item__img {
height: 11rem;
background-color: #0D023B;
overflow: hidden;
padding: 10px 18px;
}

.collection-item__img__cover {
background: linear-gradient(0deg, #FFFFFF, #FFFFFF), linear-gradient(0deg, #FFFFFF, #FFFFFF), linear-gradient(0deg, #FFFFFF, #FFFFFF), linear-gradient(0deg, #FFFFFF, #FFFFFF), #FFFFFF;
border-radius: 2px;
height: 75px;
width: 96%;
margin: 2px;
}

.collection-item__img img {
width: 100%;
object-fit: contain;
height: 100%;
}

.collection-item__logo {
background-color: white;
border-radius: 10px;
display: inline-block;
margin-top: -35px;
}

.collection-item__logo img {
width: 65px;
height: 65px;
object-fit: cover;
border-radius: 50%;
margin: 13px;
}

.collection-item__owner-image--cover {
height: 60px;
width: 60px;
position: absolute;
top: calc(50% - 30px);
left: calc(50% - 30px);
}

.collection-item__owner-image {
height: 20px;
width: 20px;
}

.collection-item__owner-image img, .collection-item__owner-image--cover img {
width: 100%;
border-radius: 50%;
}

.grant-item__footer {
margin-top: auto;
background-color: rgba(156, 255, 213, 0.06);
}

.collection-item__info a {
border-color: white;
background-color: #6144FF;
color: white;
}

.collection-item__info a:hover {
color: white;
text-decoration: underline;
}


.vertica-scroll {
flex-direction: row;
overflow-x: auto;
flex-wrap: nowrap;
margin-bottom: 25px;
}
15 changes: 9 additions & 6 deletions app/assets/v2/js/cart-data.js
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ class CartData {
return bulk_add_cart;
}

static addToCart(grantData) {
static addToCart(grantData, no_report) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Calls to this function don't pass the second input, so right now the no_report input is never used. This input should either be removed, or added to all calls to addToCart

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, i missed this. i used the no_report on bulk operation addAllToCart.

if (this.cartContainsGrantWithId(grantData.grant_id)) {
return;
}
Expand All @@ -57,7 +57,8 @@ class CartData {
if (!network) {
network = 'mainnet';
}
const acceptsAllTokens = (grantData.grant_token_address === '0x0000000000000000000000000000000000000000');
const acceptsAllTokens = (grantData.grant_token_address === '0x0000000000000000000000000000000000000000' ||
grantData.grant_token_address === '0x0');

let accptedTokenName;

Expand Down Expand Up @@ -100,10 +101,12 @@ class CartData {
cartList.push(grantData);
this.setCart(cartList);

fetchData(`/grants/${grantData.grant_id}/activity`, 'POST', {
action: 'ADD_ITEM',
metadata: JSON.stringify(cartList)
}, {'X-CSRFToken': $("input[name='csrfmiddlewaretoken']").val()});
if (!no_report) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to the above comment, no_report is never used so this will always be undefined right now. Is this the expected behavior? If so some comments explaining this would be useful

fetchData(`/grants/${grantData.grant_id}/activity`, 'POST', {
action: 'ADD_ITEM',
metadata: JSON.stringify(cartList)
}, {'X-CSRFToken': $("input[name='csrfmiddlewaretoken']").val()});
}
}

static removeIdFromCart(grantId) {
Expand Down
65 changes: 61 additions & 4 deletions app/assets/v2/js/cart.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,13 @@ Vue.component('grants-cart', {
display_email_option: false,
countDownActive: false,
// BrightID
isBrightIDVerified: false
isBrightIDVerified: false,
// Collection
showCreateCollection: false,
collectionTitle: '',
collectionDescription: '',
collections: [],
selectedCollection: null
};
},

Expand All @@ -94,6 +100,17 @@ Vue.component('grants-cart', {
return document.contxt.github_handle;
},

// Determine when activate the save collection button
isValidCollection() {
if (this.selectedCollection !== null) {
return true;
} else if (this.collectionTitle.length > 3 && this.collectionDescription.length < 140) {
return true;
}

return false;
},

// Returns true of screen size is smaller than 576 pixels (Bootstrap's small size)
isMobileDevice() {
return this.windowWidth < 576;
Expand Down Expand Up @@ -330,7 +347,7 @@ Vue.component('grants-cart', {
// Array of supported tokens
zkSyncSupportedTokens() {
const mainnetTokens = [ 'ETH', 'DAI', 'USDC', 'USDT', 'LINK', 'WBTC', 'PAN', 'SNT' ];

if (!this.selectedNetwork)
return mainnetTokens;
if (this.selectedNetwork === 'rinkeby')
Expand Down Expand Up @@ -2332,13 +2349,50 @@ Vue.component('grants-cart', {
// Final processing
await this.setInterruptStatus(null, this.userAddress);
await this.finalizeCheckout();
}
},


// =============================================================================================
// ==================================== END ZKSYNC METHODS =====================================
// =============================================================================================

// ================== Start collection logic ==================
createCollection: async function() {
const csrfmiddlewaretoken = document.querySelector('[name=csrfmiddlewaretoken]').value;
const cart = CartData.loadCart();
const grantIds = cart.map(grant => grant.grant_id);
let response;

const body = {
collectionTitle: this.collectionTitle,
collectionDescription: this.collectionDescription,
grants: grantIds
};

if (this.selectedCollection) {
body['collection'] = this.selectedCollection;
}

try {

response = await fetchData('/grants/v1/api/collections/new', 'POST', body, {'X-CSRFToken': csrfmiddlewaretoken});
const redirect = `/grants/collections?collection_id=${response.collection.id}`;

_alert('Congratulations, your new collection was created successfully!', 'success');
this.cleanCollectionModal();
this.showCreateCollection = false;

window.location = redirect;

} catch (e) {
_alert(e.msg, 'error');
}
},
cleanCollectionModal: function() {
this.collectionTitle = '';
this.collectionDescription = '';
}
// ================== End collection logic ==================
},

watch: {
Expand Down Expand Up @@ -2503,7 +2557,7 @@ Vue.component('grants-cart', {
// Force re-render so computed properties are updated (some are dependent on
// document.web3network, and Vue cannot watch document.web3network for an update)
this.selectedNetwork = document.web3network;

// Setup zkSync and check balances
this.userAddress = (await web3.eth.getAccounts())[0];
await this.setupZkSync();
Expand All @@ -2520,6 +2574,9 @@ Vue.component('grants-cart', {

}, false);

const collections_response = await fetchData('/grants/v1/api/collections');

this.collections = collections_response.collections;
// Cart is now ready
// this.isLoading = false;
},
Expand Down
102 changes: 102 additions & 0 deletions app/assets/v2/js/grants/components.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
Vue.component('grant-card', {
delimiters: [ '[[', ']]' ],
props: [ 'grant', 'cred', 'token', 'view', 'short', 'show_contributions',
'contributions', 'toggle_following', 'collection', 'has_collections'
],
data: function() {
return {
collections: document.collections,
currentUser: document.contxt.github_handle,
isCurator: false
};
},
methods: {
checkIsCurator: function() {
if (this.currentUser && this.collection && this.collection.curators.length) {
const curators = this.collection.curators.map(collection => collection.handle);

this.isCurator = curators.indexOf(this.currentUser) !== -1;
}
},
get_clr_prediction: function(indexA, indexB) {
if (this.grant.clr_prediction_curve && this.grant.clr_prediction_curve.length) {
return this.grant.clr_prediction_curve[indexA][indexB];
}
},
getContributions: function(grantId) {
return this.contributions[grantId] || [];
},
toggleFollowingGrant: async function(grantId, event) {
event.preventDefault();

const favorite_url = `/grants/${grantId}/favorite`;
let response = await fetchData(favorite_url, 'POST');

if (response.action === 'follow') {
this.grant.favorite = true;
} else {
this.grant.favorite = false;
}

return true;
},
addToCart: async function(grant) {
const grantCartPayloadURL = `v1/api/${grant.id}/cart_payload`;
const response = await fetchData(grantCartPayloadURL, 'GET');

CartData.addToCart(response.grant);

showSideCart();
},
addToCollection: async function({collection, grant}) {
const collectionAddGrantURL = `v1/api/collections/${collection.id}/grants/add`;
const response = await fetchData(collectionAddGrantURL, 'POST', {
'grant': grant.id
});

_alert('Grant added successfully', 'success', 1000);
}
},
mounted() {
this.checkIsCurator();
}
});

Vue.component('grant-collection', {
delimiters: [ '[[', ']]' ],
props: ['collection'],
methods: {
shareCollection: function() {
let testingCodeToCopy = document.querySelector(`#collection-${this.collection.id}`);

testingCodeToCopy.setAttribute('type', 'text');
testingCodeToCopy.select();

try {
const successful = document.execCommand('copy');
const msg = successful ? 'successful' : 'unsuccessful';

alert(`Grant collection was copied ${msg}: ${testingCodeToCopy.value}`);
} catch (err) {
alert('Oops, unable to copy');
}

/* unselect the range */
testingCodeToCopy.setAttribute('type', 'hidden');
window.getSelection().removeAllRanges();
},
addToCart: async function() {
const collectionDetailsURL = `v1/api/collections/${this.collection.id}`;
const collection = await fetchData(collectionDetailsURL, 'GET');

(collection.grants || []).forEach((grant) => {
CartData.addToCart(grant);
});

showSideCart();
},
getGrantLogo(index) {
return this.collection.grants[index].logo;
}
}
});
Loading