🥦ローカル🥦 fetch部分のみクリア
[買い物かご]履歴を持って useEffect(() => {
if (!token) {
setIsLoaded(true);
}
fetch(API.cart, {
headers: {
Authorization: token,
},
})
.then(res => res.json())
.then(res => {
if (!!res.result) {
setItems(res.result);
}
})
.catch(e => {
// eslint-disable-next-line no-console
console.error(e);
})
.finally(setIsLoaded(true));
}, [token]);
[カート]の数を変更 const changeItemQuantity = (cart_id, changedQuantity) => {
if (!changedQuantity.toString()) {
return;
}
fetch(API.cart, {
method: 'PATCH',
headers: {
Authorization: token,
},
body: JSON.stringify({
cart_id: cart_id,
quantity: changedQuantity,
}),
})
.then(res =>
res.json().then(res => {
switch (res.message) {
case 'Token not Exist':
alert('로그인을 해주세요');
break;
case 'SUCCESS':
setItems(
items.map(item =>
item.cart_id !== cart_id
? item
: { ...item, quantity: changedQuantity }
)
);
break;
case 'KEY_ERROR':
alert('에러입니다!');
break;
default:
break;
}
})
)
.catch(e => {
// eslint-disable-next-line no-console
console.error(e);
});
};
[買い物かご]商品を削除 const deleteItem = cart_id => {
fetch(API.cart, {
method: 'DELETE',
headers: { Authorization: token },
body: JSON.stringify({
cart_id: [cart_id],
}),
})
.then(res => res.json())
.then(res => {
switch (res.message) {
case 'Token not Exist':
alert('로그인을 해주세요');
break;
case 'SUCCESS':
setItems(items.filter(item => item.cart_id !== cart_id));
break;
case 'INVALID_CART':
alert('삭제할 상품이 없습니다');
break;
case 'KEY_ERROR':
alert('에러 입니다');
break;
default:
break;
}
})
.catch(e => {
// eslint-disable-next-line no-console
console.error(e);
});
};
複数のカートを削除 const deleteAllCheckedItem = () => {
const deleteItemsCartIdArray = items
.filter(item => !item.notChecked)
.map(item => item.cart_id);
fetch(API.cart, {
method: 'DELETE',
headers: { Authorization: token },
body: JSON.stringify({
cart_id: deleteItemsCartIdArray,
}),
})
.then(res => res.json())
.then(res => {
switch (res.message) {
case 'SUCCESS':
setItems(items.filter(item => item.notChecked));
break;
case 'Token not Exist':
alert('로그인을 해주세요');
break;
case 'INVALID_CART':
alert('삭제할 상품이 없습니다');
break;
case 'KEY_ERROR':
alert('에러 입니다');
break;
default:
break;
}
})
.catch(e => {
// eslint-disable-next-line no-console
console.error(e);
});
};
[カート]注文 const orderItems = () => {
if (checkedItemsLength < 1) {
alert('주문하실 상품을 선택해주세요');
return;
}
const orderItemsCartId = items
.filter(item => !item.notChecked)
.map(item => item.cart_id);
fetch(API.orders, {
method: 'POST',
headers: {
Authorization: token,
},
body: JSON.stringify({ cart_ids: orderItemsCartId }),
})
.then(res => res.json())
.then(res => {
switch (res.message) {
case 'Token not Exist':
alert('로그인을 해주세요');
break;
case 'INVALID_ORDER_STATUS':
case 'INVALID_ORDER_ITEMS_STATUS':
case 'DATA_ERROR':
case 'TRANSACTION_ERROR':
case 'KEY_ERROR':
case 'INVALID_CART':
alert('에러 입니다');
break;
case 'CREATE':
setItems(items.filter(item => item.notChecked));
alert('주문이 완료되었습니다.');
break;
default:
break;
}
})
.catch(e => {
// eslint-disable-next-line no-console
console.error(e);
});
};
[オーダー履歴]履歴のロード useEffect(() => {
fetch(API.orders, {
headers: {
Authorization: token,
},
})
.then(res => res.json())
.then(res => {
setOrders(res.result);
})
.catch(e => {
// eslint-disable-next-line no-console
console.error(e);
})
.finally(() => {
setLoaded(true);
});
}, [token]);
[オーダー履歴]オーダーのキャンセル const cancelOrder = order_id => {
fetch(API.orders, {
method: 'PATCH',
headers: {
Authorization: token,
},
body: JSON.stringify({
order_id: order_id,
}),
})
.then(res => res.json())
.then(res => {
switch (res.message) {
case 'INVALID_ORDER_STATUS':
case 'INVALID_ORDER_ITEMS_STATUS':
case 'KEY_ERROR':
// eslint-disable-next-line no-console
console.error('ERROR', res.message);
alert('에러입니다!');
break;
case 'SUCCESS':
changeOrderState(order_id);
alert('주문이 취소되었습니다.');
break;
default:
break;
}
})
.catch(e => {
// eslint-disable-next-line no-console
console.error('catch', e);
});
};
[商品リスト]商品リストに入れる useEffect(() => {
fetch(
`${API.product}?menu=${menu}${
!category.length ? '' : `&category=${category}`
}&sort=${sort}`
)
.then(res => res.json())
.then(res => {
if (!!res.result) {
setProducts(res.result);
}
switch (res.message) {
case 'AttributeError':
case 'KeyError':
case 'TypeError':
case 'DoesNotExits':
alert('에러입니다.');
break;
default:
break;
}
})
.catch(e => {
// eslint-disable-next-line no-console
console.error(e);
})
.finally(setLoaded(true));
}, [category, menu, searchParams, sort]);
[商品リスト]買い物かごに入れる const addProductToCart = () => {
if (!!token) {
fetch(API.cart, {
method: 'POST',
headers: {
Authorization: token,
},
body: JSON.stringify({
product_id: id,
quantity: quantity,
}),
})
.then(res => res.json())
.then(res => {
switch (res.message) {
case 'SUCCESS':
case 'update':
alert('장바구니에 상품이 추가 되었습니다.');
closeModal();
break;
case 'DoesNotExist':
alert('로그인 해주세요');
break;
default:
break;
}
})
.catch(e => {
// eslint-disable-next-line no-console
console.error(e);
});
} else {
alert('로그인해주세요^^');
}
};
Reference
この問題について(🥦ローカル🥦 fetch部分のみクリア), 我々は、より多くの情報をここで見つけました
https://velog.io/@tjdgus0528/브로컬리-fetch-부분만-정리
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
useEffect(() => {
if (!token) {
setIsLoaded(true);
}
fetch(API.cart, {
headers: {
Authorization: token,
},
})
.then(res => res.json())
.then(res => {
if (!!res.result) {
setItems(res.result);
}
})
.catch(e => {
// eslint-disable-next-line no-console
console.error(e);
})
.finally(setIsLoaded(true));
}, [token]);
const changeItemQuantity = (cart_id, changedQuantity) => {
if (!changedQuantity.toString()) {
return;
}
fetch(API.cart, {
method: 'PATCH',
headers: {
Authorization: token,
},
body: JSON.stringify({
cart_id: cart_id,
quantity: changedQuantity,
}),
})
.then(res =>
res.json().then(res => {
switch (res.message) {
case 'Token not Exist':
alert('로그인을 해주세요');
break;
case 'SUCCESS':
setItems(
items.map(item =>
item.cart_id !== cart_id
? item
: { ...item, quantity: changedQuantity }
)
);
break;
case 'KEY_ERROR':
alert('에러입니다!');
break;
default:
break;
}
})
)
.catch(e => {
// eslint-disable-next-line no-console
console.error(e);
});
};
[買い物かご]商品を削除 const deleteItem = cart_id => {
fetch(API.cart, {
method: 'DELETE',
headers: { Authorization: token },
body: JSON.stringify({
cart_id: [cart_id],
}),
})
.then(res => res.json())
.then(res => {
switch (res.message) {
case 'Token not Exist':
alert('로그인을 해주세요');
break;
case 'SUCCESS':
setItems(items.filter(item => item.cart_id !== cart_id));
break;
case 'INVALID_CART':
alert('삭제할 상품이 없습니다');
break;
case 'KEY_ERROR':
alert('에러 입니다');
break;
default:
break;
}
})
.catch(e => {
// eslint-disable-next-line no-console
console.error(e);
});
};
複数のカートを削除 const deleteAllCheckedItem = () => {
const deleteItemsCartIdArray = items
.filter(item => !item.notChecked)
.map(item => item.cart_id);
fetch(API.cart, {
method: 'DELETE',
headers: { Authorization: token },
body: JSON.stringify({
cart_id: deleteItemsCartIdArray,
}),
})
.then(res => res.json())
.then(res => {
switch (res.message) {
case 'SUCCESS':
setItems(items.filter(item => item.notChecked));
break;
case 'Token not Exist':
alert('로그인을 해주세요');
break;
case 'INVALID_CART':
alert('삭제할 상품이 없습니다');
break;
case 'KEY_ERROR':
alert('에러 입니다');
break;
default:
break;
}
})
.catch(e => {
// eslint-disable-next-line no-console
console.error(e);
});
};
[カート]注文 const orderItems = () => {
if (checkedItemsLength < 1) {
alert('주문하실 상품을 선택해주세요');
return;
}
const orderItemsCartId = items
.filter(item => !item.notChecked)
.map(item => item.cart_id);
fetch(API.orders, {
method: 'POST',
headers: {
Authorization: token,
},
body: JSON.stringify({ cart_ids: orderItemsCartId }),
})
.then(res => res.json())
.then(res => {
switch (res.message) {
case 'Token not Exist':
alert('로그인을 해주세요');
break;
case 'INVALID_ORDER_STATUS':
case 'INVALID_ORDER_ITEMS_STATUS':
case 'DATA_ERROR':
case 'TRANSACTION_ERROR':
case 'KEY_ERROR':
case 'INVALID_CART':
alert('에러 입니다');
break;
case 'CREATE':
setItems(items.filter(item => item.notChecked));
alert('주문이 완료되었습니다.');
break;
default:
break;
}
})
.catch(e => {
// eslint-disable-next-line no-console
console.error(e);
});
};
[オーダー履歴]履歴のロード useEffect(() => {
fetch(API.orders, {
headers: {
Authorization: token,
},
})
.then(res => res.json())
.then(res => {
setOrders(res.result);
})
.catch(e => {
// eslint-disable-next-line no-console
console.error(e);
})
.finally(() => {
setLoaded(true);
});
}, [token]);
[オーダー履歴]オーダーのキャンセル const cancelOrder = order_id => {
fetch(API.orders, {
method: 'PATCH',
headers: {
Authorization: token,
},
body: JSON.stringify({
order_id: order_id,
}),
})
.then(res => res.json())
.then(res => {
switch (res.message) {
case 'INVALID_ORDER_STATUS':
case 'INVALID_ORDER_ITEMS_STATUS':
case 'KEY_ERROR':
// eslint-disable-next-line no-console
console.error('ERROR', res.message);
alert('에러입니다!');
break;
case 'SUCCESS':
changeOrderState(order_id);
alert('주문이 취소되었습니다.');
break;
default:
break;
}
})
.catch(e => {
// eslint-disable-next-line no-console
console.error('catch', e);
});
};
[商品リスト]商品リストに入れる useEffect(() => {
fetch(
`${API.product}?menu=${menu}${
!category.length ? '' : `&category=${category}`
}&sort=${sort}`
)
.then(res => res.json())
.then(res => {
if (!!res.result) {
setProducts(res.result);
}
switch (res.message) {
case 'AttributeError':
case 'KeyError':
case 'TypeError':
case 'DoesNotExits':
alert('에러입니다.');
break;
default:
break;
}
})
.catch(e => {
// eslint-disable-next-line no-console
console.error(e);
})
.finally(setLoaded(true));
}, [category, menu, searchParams, sort]);
[商品リスト]買い物かごに入れる const addProductToCart = () => {
if (!!token) {
fetch(API.cart, {
method: 'POST',
headers: {
Authorization: token,
},
body: JSON.stringify({
product_id: id,
quantity: quantity,
}),
})
.then(res => res.json())
.then(res => {
switch (res.message) {
case 'SUCCESS':
case 'update':
alert('장바구니에 상품이 추가 되었습니다.');
closeModal();
break;
case 'DoesNotExist':
alert('로그인 해주세요');
break;
default:
break;
}
})
.catch(e => {
// eslint-disable-next-line no-console
console.error(e);
});
} else {
alert('로그인해주세요^^');
}
};
Reference
この問題について(🥦ローカル🥦 fetch部分のみクリア), 我々は、より多くの情報をここで見つけました
https://velog.io/@tjdgus0528/브로컬리-fetch-부분만-정리
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
const deleteItem = cart_id => {
fetch(API.cart, {
method: 'DELETE',
headers: { Authorization: token },
body: JSON.stringify({
cart_id: [cart_id],
}),
})
.then(res => res.json())
.then(res => {
switch (res.message) {
case 'Token not Exist':
alert('로그인을 해주세요');
break;
case 'SUCCESS':
setItems(items.filter(item => item.cart_id !== cart_id));
break;
case 'INVALID_CART':
alert('삭제할 상품이 없습니다');
break;
case 'KEY_ERROR':
alert('에러 입니다');
break;
default:
break;
}
})
.catch(e => {
// eslint-disable-next-line no-console
console.error(e);
});
};
const deleteAllCheckedItem = () => {
const deleteItemsCartIdArray = items
.filter(item => !item.notChecked)
.map(item => item.cart_id);
fetch(API.cart, {
method: 'DELETE',
headers: { Authorization: token },
body: JSON.stringify({
cart_id: deleteItemsCartIdArray,
}),
})
.then(res => res.json())
.then(res => {
switch (res.message) {
case 'SUCCESS':
setItems(items.filter(item => item.notChecked));
break;
case 'Token not Exist':
alert('로그인을 해주세요');
break;
case 'INVALID_CART':
alert('삭제할 상품이 없습니다');
break;
case 'KEY_ERROR':
alert('에러 입니다');
break;
default:
break;
}
})
.catch(e => {
// eslint-disable-next-line no-console
console.error(e);
});
};
[カート]注文 const orderItems = () => {
if (checkedItemsLength < 1) {
alert('주문하실 상품을 선택해주세요');
return;
}
const orderItemsCartId = items
.filter(item => !item.notChecked)
.map(item => item.cart_id);
fetch(API.orders, {
method: 'POST',
headers: {
Authorization: token,
},
body: JSON.stringify({ cart_ids: orderItemsCartId }),
})
.then(res => res.json())
.then(res => {
switch (res.message) {
case 'Token not Exist':
alert('로그인을 해주세요');
break;
case 'INVALID_ORDER_STATUS':
case 'INVALID_ORDER_ITEMS_STATUS':
case 'DATA_ERROR':
case 'TRANSACTION_ERROR':
case 'KEY_ERROR':
case 'INVALID_CART':
alert('에러 입니다');
break;
case 'CREATE':
setItems(items.filter(item => item.notChecked));
alert('주문이 완료되었습니다.');
break;
default:
break;
}
})
.catch(e => {
// eslint-disable-next-line no-console
console.error(e);
});
};
[オーダー履歴]履歴のロード useEffect(() => {
fetch(API.orders, {
headers: {
Authorization: token,
},
})
.then(res => res.json())
.then(res => {
setOrders(res.result);
})
.catch(e => {
// eslint-disable-next-line no-console
console.error(e);
})
.finally(() => {
setLoaded(true);
});
}, [token]);
[オーダー履歴]オーダーのキャンセル const cancelOrder = order_id => {
fetch(API.orders, {
method: 'PATCH',
headers: {
Authorization: token,
},
body: JSON.stringify({
order_id: order_id,
}),
})
.then(res => res.json())
.then(res => {
switch (res.message) {
case 'INVALID_ORDER_STATUS':
case 'INVALID_ORDER_ITEMS_STATUS':
case 'KEY_ERROR':
// eslint-disable-next-line no-console
console.error('ERROR', res.message);
alert('에러입니다!');
break;
case 'SUCCESS':
changeOrderState(order_id);
alert('주문이 취소되었습니다.');
break;
default:
break;
}
})
.catch(e => {
// eslint-disable-next-line no-console
console.error('catch', e);
});
};
[商品リスト]商品リストに入れる useEffect(() => {
fetch(
`${API.product}?menu=${menu}${
!category.length ? '' : `&category=${category}`
}&sort=${sort}`
)
.then(res => res.json())
.then(res => {
if (!!res.result) {
setProducts(res.result);
}
switch (res.message) {
case 'AttributeError':
case 'KeyError':
case 'TypeError':
case 'DoesNotExits':
alert('에러입니다.');
break;
default:
break;
}
})
.catch(e => {
// eslint-disable-next-line no-console
console.error(e);
})
.finally(setLoaded(true));
}, [category, menu, searchParams, sort]);
[商品リスト]買い物かごに入れる const addProductToCart = () => {
if (!!token) {
fetch(API.cart, {
method: 'POST',
headers: {
Authorization: token,
},
body: JSON.stringify({
product_id: id,
quantity: quantity,
}),
})
.then(res => res.json())
.then(res => {
switch (res.message) {
case 'SUCCESS':
case 'update':
alert('장바구니에 상품이 추가 되었습니다.');
closeModal();
break;
case 'DoesNotExist':
alert('로그인 해주세요');
break;
default:
break;
}
})
.catch(e => {
// eslint-disable-next-line no-console
console.error(e);
});
} else {
alert('로그인해주세요^^');
}
};
Reference
この問題について(🥦ローカル🥦 fetch部分のみクリア), 我々は、より多くの情報をここで見つけました
https://velog.io/@tjdgus0528/브로컬리-fetch-부분만-정리
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
const orderItems = () => {
if (checkedItemsLength < 1) {
alert('주문하실 상품을 선택해주세요');
return;
}
const orderItemsCartId = items
.filter(item => !item.notChecked)
.map(item => item.cart_id);
fetch(API.orders, {
method: 'POST',
headers: {
Authorization: token,
},
body: JSON.stringify({ cart_ids: orderItemsCartId }),
})
.then(res => res.json())
.then(res => {
switch (res.message) {
case 'Token not Exist':
alert('로그인을 해주세요');
break;
case 'INVALID_ORDER_STATUS':
case 'INVALID_ORDER_ITEMS_STATUS':
case 'DATA_ERROR':
case 'TRANSACTION_ERROR':
case 'KEY_ERROR':
case 'INVALID_CART':
alert('에러 입니다');
break;
case 'CREATE':
setItems(items.filter(item => item.notChecked));
alert('주문이 완료되었습니다.');
break;
default:
break;
}
})
.catch(e => {
// eslint-disable-next-line no-console
console.error(e);
});
};
useEffect(() => {
fetch(API.orders, {
headers: {
Authorization: token,
},
})
.then(res => res.json())
.then(res => {
setOrders(res.result);
})
.catch(e => {
// eslint-disable-next-line no-console
console.error(e);
})
.finally(() => {
setLoaded(true);
});
}, [token]);
[オーダー履歴]オーダーのキャンセル const cancelOrder = order_id => {
fetch(API.orders, {
method: 'PATCH',
headers: {
Authorization: token,
},
body: JSON.stringify({
order_id: order_id,
}),
})
.then(res => res.json())
.then(res => {
switch (res.message) {
case 'INVALID_ORDER_STATUS':
case 'INVALID_ORDER_ITEMS_STATUS':
case 'KEY_ERROR':
// eslint-disable-next-line no-console
console.error('ERROR', res.message);
alert('에러입니다!');
break;
case 'SUCCESS':
changeOrderState(order_id);
alert('주문이 취소되었습니다.');
break;
default:
break;
}
})
.catch(e => {
// eslint-disable-next-line no-console
console.error('catch', e);
});
};
[商品リスト]商品リストに入れる useEffect(() => {
fetch(
`${API.product}?menu=${menu}${
!category.length ? '' : `&category=${category}`
}&sort=${sort}`
)
.then(res => res.json())
.then(res => {
if (!!res.result) {
setProducts(res.result);
}
switch (res.message) {
case 'AttributeError':
case 'KeyError':
case 'TypeError':
case 'DoesNotExits':
alert('에러입니다.');
break;
default:
break;
}
})
.catch(e => {
// eslint-disable-next-line no-console
console.error(e);
})
.finally(setLoaded(true));
}, [category, menu, searchParams, sort]);
[商品リスト]買い物かごに入れる const addProductToCart = () => {
if (!!token) {
fetch(API.cart, {
method: 'POST',
headers: {
Authorization: token,
},
body: JSON.stringify({
product_id: id,
quantity: quantity,
}),
})
.then(res => res.json())
.then(res => {
switch (res.message) {
case 'SUCCESS':
case 'update':
alert('장바구니에 상품이 추가 되었습니다.');
closeModal();
break;
case 'DoesNotExist':
alert('로그인 해주세요');
break;
default:
break;
}
})
.catch(e => {
// eslint-disable-next-line no-console
console.error(e);
});
} else {
alert('로그인해주세요^^');
}
};
Reference
この問題について(🥦ローカル🥦 fetch部分のみクリア), 我々は、より多くの情報をここで見つけました
https://velog.io/@tjdgus0528/브로컬리-fetch-부분만-정리
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
const cancelOrder = order_id => {
fetch(API.orders, {
method: 'PATCH',
headers: {
Authorization: token,
},
body: JSON.stringify({
order_id: order_id,
}),
})
.then(res => res.json())
.then(res => {
switch (res.message) {
case 'INVALID_ORDER_STATUS':
case 'INVALID_ORDER_ITEMS_STATUS':
case 'KEY_ERROR':
// eslint-disable-next-line no-console
console.error('ERROR', res.message);
alert('에러입니다!');
break;
case 'SUCCESS':
changeOrderState(order_id);
alert('주문이 취소되었습니다.');
break;
default:
break;
}
})
.catch(e => {
// eslint-disable-next-line no-console
console.error('catch', e);
});
};
useEffect(() => {
fetch(
`${API.product}?menu=${menu}${
!category.length ? '' : `&category=${category}`
}&sort=${sort}`
)
.then(res => res.json())
.then(res => {
if (!!res.result) {
setProducts(res.result);
}
switch (res.message) {
case 'AttributeError':
case 'KeyError':
case 'TypeError':
case 'DoesNotExits':
alert('에러입니다.');
break;
default:
break;
}
})
.catch(e => {
// eslint-disable-next-line no-console
console.error(e);
})
.finally(setLoaded(true));
}, [category, menu, searchParams, sort]);
[商品リスト]買い物かごに入れる const addProductToCart = () => {
if (!!token) {
fetch(API.cart, {
method: 'POST',
headers: {
Authorization: token,
},
body: JSON.stringify({
product_id: id,
quantity: quantity,
}),
})
.then(res => res.json())
.then(res => {
switch (res.message) {
case 'SUCCESS':
case 'update':
alert('장바구니에 상품이 추가 되었습니다.');
closeModal();
break;
case 'DoesNotExist':
alert('로그인 해주세요');
break;
default:
break;
}
})
.catch(e => {
// eslint-disable-next-line no-console
console.error(e);
});
} else {
alert('로그인해주세요^^');
}
};
Reference
この問題について(🥦ローカル🥦 fetch部分のみクリア), 我々は、より多くの情報をここで見つけました
https://velog.io/@tjdgus0528/브로컬리-fetch-부분만-정리
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
const addProductToCart = () => {
if (!!token) {
fetch(API.cart, {
method: 'POST',
headers: {
Authorization: token,
},
body: JSON.stringify({
product_id: id,
quantity: quantity,
}),
})
.then(res => res.json())
.then(res => {
switch (res.message) {
case 'SUCCESS':
case 'update':
alert('장바구니에 상품이 추가 되었습니다.');
closeModal();
break;
case 'DoesNotExist':
alert('로그인 해주세요');
break;
default:
break;
}
})
.catch(e => {
// eslint-disable-next-line no-console
console.error(e);
});
} else {
alert('로그인해주세요^^');
}
};
Reference
この問題について(🥦ローカル🥦 fetch部分のみクリア), 我々は、より多くの情報をここで見つけました https://velog.io/@tjdgus0528/브로컬리-fetch-부분만-정리テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol