Как верстать - выбирать вам. А коротенький универсальный скрипт календарика я могу дать.
Пользоваться просто: 2 параметра: год (например, 2020), месяц: (например, 8 (август)); на выходе - массив массивов (недели - дни):
function cal(y,m) {
let[t,r,d,w,l]=[v=>~~v,[],1,0,y%4],c=(t(23*m/9)+(m<3?y--:y-2)+5+t(y/4)-t(y/100)+t(y/400))%7;
for(;d<29+(62648012+16*!l>>m*2&3);++d,c=++c%7,w+=!c)(r[w]||(r[w]=[,,,,,,,]))[c]=d;return r
}
console.log(cal(2020,8));
[
[ , , , , , , 1 ],
[ 2, 3, 4, 5, 6, 7, 8 ],
[ 9, 10, 11, 12, 13, 14, 15 ],
[ 16, 17, 18, 19, 20, 21, 22 ],
[ 23, 24, 25, 26, 27, 28, 29 ],
[ 30, 31, , , , , ]
]
Версия с первым днем недели - понедельником:
function cal(y,m) {
let[t,r,d,w,l]=[v=>~~v,[],1,0,y%4],c=(t(23*m/9)+(m<3?y--:y-2)+5+t(y/4)-t(y/100)+t(y/400))%7||7;
for(;d<29+(62648012+16*!l>>m*2&3);++d,c=++c%7||7,w+=!(c-1))(r[w]||(r[w]=[,,,,,,,]))[c-1]=d;return r
}
console.log(cal(2020,8));
[
[ , , , , , 1, 2 ],
[ 3, 4, 5, 6, 7, 8, 9 ],
[ 10, 11, 12, 13, 14, 15, 16 ],
[ 17, 18, 19, 20, 21, 22, 23 ],
[ 24, 25, 26, 27, 28, 29, 30 ],
[ 31, , , , , , ]
]