diff --git a/frontend/allsafe/public/Evening Mood.ogg b/frontend/allsafe/public/Evening Mood.ogg new file mode 100644 index 0000000..1940e5b Binary files /dev/null and b/frontend/allsafe/public/Evening Mood.ogg differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/License.txt b/frontend/allsafe/public/Modern City Backgrounds/License.txt new file mode 100644 index 0000000..673e1aa --- /dev/null +++ b/frontend/allsafe/public/Modern City Backgrounds/License.txt @@ -0,0 +1 @@ +https://craftpix.net/file-licenses/ \ No newline at end of file diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 1/1.png b/frontend/allsafe/public/Modern City Backgrounds/city 1/1.png new file mode 100644 index 0000000..d00de55 Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 1/1.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 1/10.png b/frontend/allsafe/public/Modern City Backgrounds/city 1/10.png new file mode 100644 index 0000000..efa2a01 Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 1/10.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 1/2.png b/frontend/allsafe/public/Modern City Backgrounds/city 1/2.png new file mode 100644 index 0000000..8bbf680 Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 1/2.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 1/3.png b/frontend/allsafe/public/Modern City Backgrounds/city 1/3.png new file mode 100644 index 0000000..4f1c9ca Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 1/3.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 1/4.png b/frontend/allsafe/public/Modern City Backgrounds/city 1/4.png new file mode 100644 index 0000000..8394f6e Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 1/4.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 1/5.png b/frontend/allsafe/public/Modern City Backgrounds/city 1/5.png new file mode 100644 index 0000000..47e27c9 Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 1/5.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 1/6.png b/frontend/allsafe/public/Modern City Backgrounds/city 1/6.png new file mode 100644 index 0000000..99d841a Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 1/6.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 2/1.png b/frontend/allsafe/public/Modern City Backgrounds/city 2/1.png new file mode 100644 index 0000000..97b6d39 Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 2/1.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 2/10.png b/frontend/allsafe/public/Modern City Backgrounds/city 2/10.png new file mode 100644 index 0000000..5fb29e2 Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 2/10.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 2/2.png b/frontend/allsafe/public/Modern City Backgrounds/city 2/2.png new file mode 100644 index 0000000..e4215cd Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 2/2.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 2/3.png b/frontend/allsafe/public/Modern City Backgrounds/city 2/3.png new file mode 100644 index 0000000..21b8d50 Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 2/3.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 2/4.png b/frontend/allsafe/public/Modern City Backgrounds/city 2/4.png new file mode 100644 index 0000000..325375d Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 2/4.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 2/5.png b/frontend/allsafe/public/Modern City Backgrounds/city 2/5.png new file mode 100644 index 0000000..5af7cca Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 2/5.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 2/6.png b/frontend/allsafe/public/Modern City Backgrounds/city 2/6.png new file mode 100644 index 0000000..027a39f Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 2/6.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 2/7.png b/frontend/allsafe/public/Modern City Backgrounds/city 2/7.png new file mode 100644 index 0000000..89d839d Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 2/7.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 3/1.png b/frontend/allsafe/public/Modern City Backgrounds/city 3/1.png new file mode 100644 index 0000000..6039e11 Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 3/1.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 3/2.png b/frontend/allsafe/public/Modern City Backgrounds/city 3/2.png new file mode 100644 index 0000000..8dbc977 Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 3/2.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 3/3.png b/frontend/allsafe/public/Modern City Backgrounds/city 3/3.png new file mode 100644 index 0000000..2667016 Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 3/3.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 3/4.png b/frontend/allsafe/public/Modern City Backgrounds/city 3/4.png new file mode 100644 index 0000000..67fd20a Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 3/4.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 3/5.png b/frontend/allsafe/public/Modern City Backgrounds/city 3/5.png new file mode 100644 index 0000000..34d8cc8 Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 3/5.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 3/6.png b/frontend/allsafe/public/Modern City Backgrounds/city 3/6.png new file mode 100644 index 0000000..310690c Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 3/6.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 3/7.png b/frontend/allsafe/public/Modern City Backgrounds/city 3/7.png new file mode 100644 index 0000000..1485282 Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 3/7.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 4/1.png b/frontend/allsafe/public/Modern City Backgrounds/city 4/1.png new file mode 100644 index 0000000..39cc74d Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 4/1.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 4/2.png b/frontend/allsafe/public/Modern City Backgrounds/city 4/2.png new file mode 100644 index 0000000..e546415 Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 4/2.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 4/3.png b/frontend/allsafe/public/Modern City Backgrounds/city 4/3.png new file mode 100644 index 0000000..67f8f53 Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 4/3.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 4/4.png b/frontend/allsafe/public/Modern City Backgrounds/city 4/4.png new file mode 100644 index 0000000..f09ece1 Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 4/4.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 4/5.png b/frontend/allsafe/public/Modern City Backgrounds/city 4/5.png new file mode 100644 index 0000000..1d3ae57 Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 4/5.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 4/7.png b/frontend/allsafe/public/Modern City Backgrounds/city 4/7.png new file mode 100644 index 0000000..fdcf753 Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 4/7.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 4/8.png b/frontend/allsafe/public/Modern City Backgrounds/city 4/8.png new file mode 100644 index 0000000..57f813e Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 4/8.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 4/9.png b/frontend/allsafe/public/Modern City Backgrounds/city 4/9.png new file mode 100644 index 0000000..3d559d5 Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 4/9.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 5/1.png b/frontend/allsafe/public/Modern City Backgrounds/city 5/1.png new file mode 100644 index 0000000..bdc147b Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 5/1.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 5/2.png b/frontend/allsafe/public/Modern City Backgrounds/city 5/2.png new file mode 100644 index 0000000..679a524 Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 5/2.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 5/3.png b/frontend/allsafe/public/Modern City Backgrounds/city 5/3.png new file mode 100644 index 0000000..f9a1987 Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 5/3.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 5/4.png b/frontend/allsafe/public/Modern City Backgrounds/city 5/4.png new file mode 100644 index 0000000..21d7ec0 Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 5/4.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 5/5.png b/frontend/allsafe/public/Modern City Backgrounds/city 5/5.png new file mode 100644 index 0000000..0eceb3a Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 5/5.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 5/6.png b/frontend/allsafe/public/Modern City Backgrounds/city 5/6.png new file mode 100644 index 0000000..28cc3d6 Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 5/6.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 5/7.png b/frontend/allsafe/public/Modern City Backgrounds/city 5/7.png new file mode 100644 index 0000000..415357b Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 5/7.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 6/1.png b/frontend/allsafe/public/Modern City Backgrounds/city 6/1.png new file mode 100644 index 0000000..658f12b Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 6/1.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 6/2.png b/frontend/allsafe/public/Modern City Backgrounds/city 6/2.png new file mode 100644 index 0000000..8c3a7c9 Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 6/2.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 6/3.png b/frontend/allsafe/public/Modern City Backgrounds/city 6/3.png new file mode 100644 index 0000000..7b1615d Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 6/3.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 6/4.png b/frontend/allsafe/public/Modern City Backgrounds/city 6/4.png new file mode 100644 index 0000000..1738b39 Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 6/4.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 6/5.png b/frontend/allsafe/public/Modern City Backgrounds/city 6/5.png new file mode 100644 index 0000000..d92be90 Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 6/5.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 6/6.png b/frontend/allsafe/public/Modern City Backgrounds/city 6/6.png new file mode 100644 index 0000000..f6f1d05 Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 6/6.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 6/7.png b/frontend/allsafe/public/Modern City Backgrounds/city 6/7.png new file mode 100644 index 0000000..12ca319 Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 6/7.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 6/8.png b/frontend/allsafe/public/Modern City Backgrounds/city 6/8.png new file mode 100644 index 0000000..7524d1e Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 6/8.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 7/1.png b/frontend/allsafe/public/Modern City Backgrounds/city 7/1.png new file mode 100644 index 0000000..dfaa558 Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 7/1.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 7/2.png b/frontend/allsafe/public/Modern City Backgrounds/city 7/2.png new file mode 100644 index 0000000..e4c9f8c Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 7/2.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 7/3.png b/frontend/allsafe/public/Modern City Backgrounds/city 7/3.png new file mode 100644 index 0000000..9697005 Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 7/3.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 7/4.png b/frontend/allsafe/public/Modern City Backgrounds/city 7/4.png new file mode 100644 index 0000000..f70cd27 Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 7/4.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 7/5.png b/frontend/allsafe/public/Modern City Backgrounds/city 7/5.png new file mode 100644 index 0000000..ff6f3f9 Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 7/5.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 7/6.png b/frontend/allsafe/public/Modern City Backgrounds/city 7/6.png new file mode 100644 index 0000000..f224668 Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 7/6.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 7/7.png b/frontend/allsafe/public/Modern City Backgrounds/city 7/7.png new file mode 100644 index 0000000..4c59af3 Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 7/7.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 8/1.png b/frontend/allsafe/public/Modern City Backgrounds/city 8/1.png new file mode 100644 index 0000000..41740c7 Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 8/1.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 8/2.png b/frontend/allsafe/public/Modern City Backgrounds/city 8/2.png new file mode 100644 index 0000000..7b9e461 Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 8/2.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 8/3.png b/frontend/allsafe/public/Modern City Backgrounds/city 8/3.png new file mode 100644 index 0000000..3c2dd46 Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 8/3.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 8/4.png b/frontend/allsafe/public/Modern City Backgrounds/city 8/4.png new file mode 100644 index 0000000..975a541 Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 8/4.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 8/5.png b/frontend/allsafe/public/Modern City Backgrounds/city 8/5.png new file mode 100644 index 0000000..7587e96 Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 8/5.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 8/6.png b/frontend/allsafe/public/Modern City Backgrounds/city 8/6.png new file mode 100644 index 0000000..83e5fe8 Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 8/6.png differ diff --git a/frontend/allsafe/public/Modern City Backgrounds/city 8/7.png b/frontend/allsafe/public/Modern City Backgrounds/city 8/7.png new file mode 100644 index 0000000..55efe96 Binary files /dev/null and b/frontend/allsafe/public/Modern City Backgrounds/city 8/7.png differ diff --git a/frontend/allsafe/public/Retro Gaming Pixel 8.gif b/frontend/allsafe/public/Retro Gaming Pixel 8.gif new file mode 100644 index 0000000..ea37400 Binary files /dev/null and b/frontend/allsafe/public/Retro Gaming Pixel 8.gif differ diff --git a/frontend/allsafe/public/background/Anime Aesthetic.gif b/frontend/allsafe/public/background/Anime Aesthetic.gif new file mode 100644 index 0000000..35c0349 Binary files /dev/null and b/frontend/allsafe/public/background/Anime Aesthetic.gif differ diff --git a/frontend/allsafe/public/background/Lofi Art Aesthetic.gif b/frontend/allsafe/public/background/Lofi Art Aesthetic.gif new file mode 100644 index 0000000..c07c27a Binary files /dev/null and b/frontend/allsafe/public/background/Lofi Art Aesthetic.gif differ diff --git a/frontend/allsafe/public/background/Pixel Art.gif b/frontend/allsafe/public/background/Pixel Art.gif new file mode 100644 index 0000000..6311cde Binary files /dev/null and b/frontend/allsafe/public/background/Pixel Art.gif differ diff --git a/frontend/allsafe/public/background/Retro Gaming Pixel 8.gif b/frontend/allsafe/public/background/Retro Gaming Pixel 8.gif new file mode 100644 index 0000000..ea37400 Binary files /dev/null and b/frontend/allsafe/public/background/Retro Gaming Pixel 8.gif differ diff --git a/frontend/allsafe/public/background/city-aft.png b/frontend/allsafe/public/background/city-aft.png new file mode 100644 index 0000000..5fb29e2 Binary files /dev/null and b/frontend/allsafe/public/background/city-aft.png differ diff --git a/frontend/allsafe/public/background/city-night.png b/frontend/allsafe/public/background/city-night.png new file mode 100644 index 0000000..efa2a01 Binary files /dev/null and b/frontend/allsafe/public/background/city-night.png differ diff --git a/frontend/allsafe/public/background/city-pink.png b/frontend/allsafe/public/background/city-pink.png new file mode 100644 index 0000000..7524d1e Binary files /dev/null and b/frontend/allsafe/public/background/city-pink.png differ diff --git a/frontend/allsafe/public/character/Bridget_cry.png b/frontend/allsafe/public/character/Bridget_cry.png new file mode 100644 index 0000000..0c22f34 Binary files /dev/null and b/frontend/allsafe/public/character/Bridget_cry.png differ diff --git a/frontend/allsafe/public/character/Bridget_happy.png b/frontend/allsafe/public/character/Bridget_happy.png new file mode 100644 index 0000000..fab8796 Binary files /dev/null and b/frontend/allsafe/public/character/Bridget_happy.png differ diff --git a/frontend/allsafe/public/character/Bridget_normal.png b/frontend/allsafe/public/character/Bridget_normal.png new file mode 100644 index 0000000..6f9680e Binary files /dev/null and b/frontend/allsafe/public/character/Bridget_normal.png differ diff --git a/frontend/allsafe/public/character/Bridget_surprise.png b/frontend/allsafe/public/character/Bridget_surprise.png new file mode 100644 index 0000000..9b7d453 Binary files /dev/null and b/frontend/allsafe/public/character/Bridget_surprise.png differ diff --git a/frontend/allsafe/public/src/js/news/lineChart.js b/frontend/allsafe/public/src/js/news/lineChart.js new file mode 100644 index 0000000..d2aed91 --- /dev/null +++ b/frontend/allsafe/public/src/js/news/lineChart.js @@ -0,0 +1,282 @@ +export function createLineChart(data, containerId) { + console.log('Creating line chart...') + + // set up dimensions and margins of the graph + const container = document.getElementById(containerId) + const { width: containerWidth, height: containerHeight } = + container.getBoundingClientRect() + + const lineMargin = { top: 50, right: 0, bottom: 100, left: 100 } + const width = containerWidth + const height = containerHeight + const totalWidth = width * 15 + + // aggregate data by month + function aggData(data) { + const grouped = d3.group(data, (d) => `${d.year}-${d.month}`) + return Array.from(grouped, ([key, value]) => { + const [year, month] = key.split('-').map(Number) + const no_of_reports = d3.sum(value, (d) => d.no_of_reports) + return { + year, + month, + date: new Date(year, month - 1), + no_of_reports, + } + }) + } + + // get data + const monthData = aggData(data) + const sortData = monthData.sort((a, b) => d3.ascending(a.date, b.date)) + + // set x scale + const x = d3 + .scaleTime() + .domain(d3.extent(sortData, (d) => d.date)) + .range([lineMargin.left, totalWidth - lineMargin.right]) + + // set y scale + const y = d3 + .scaleLinear() + .domain([0, d3.max(sortData, (d) => d.no_of_reports)]) + .nice() + .range([height - lineMargin.bottom, lineMargin.top]) + + // create line + const line = d3 + .line() + .x((d) => x(d.date)) + .y((d) => y(d.no_of_reports)) + .curve(d3.curveCatmullRom.alpha(0.5)) + + // create y-axis svg + const yAxisSvg = d3 + .create('svg') + .attr('class', 'y-axis-svg') + .attr('width', lineMargin.left) + .attr('height', height) + .style('position', 'absolute') + .style('left', '0px') // Adjust to ensure it's always visible + .style('top', '0px') // Adjust to ensure it's aligned properly + + // create y-axis + const yAxis = d3.axisLeft(y).ticks(12) + + yAxisSvg + .append('g') + .attr( + 'transform', + `translate(${lineMargin.left - 50}, ${lineMargin.bottom - 10})` + ) + .call(yAxis) + .style('font-size', '16px') + .call((g) => g.select('.domain').remove()) + .call((g) => + g + .append('text') + .attr('x', -50) + //.attr('y', -20) + .style('font-size', '16px') + .attr('fill', 'currentColor') + .attr('text-anchor', 'start') + .text('No of Reports') + ) + + // create main svg + const mainSvg = d3 + .create('svg') + .attr('class', 'chart-svg') + .attr('width', totalWidth) + .attr('height', height) + .attr('viewBox', `0 0 ${totalWidth} ${height}`) + + // create x-axis + const axis = fc + .axisOrdinalBottom(x) + .ticks(d3.timeMonth.every(1)) + .tickFormat(d3.timeFormat('%b %Y')) + + const xAxis = fc.axisLabelRotate(axis).labelRotate(30) // You can adjust this angle as needed + + mainSvg + .append('g') + .attr('transform', `translate(0,${height - lineMargin.bottom})`) + .call(xAxis) + .style('font-size', '20px') + + // define gradient + const defs = mainSvg.append('defs') + const gradientId = 'gradient-line-area' + + const gradient = defs + .append('linearGradient') + .attr('id', gradientId) + .attr('x1', '0%') + .attr('x2', '100%') + .attr('y1', '50%') + .attr('y2', '50%') + + // gradient start + gradient.append('stop').attr('offset', '0%').attr('stop-color', '#f57c00') + + // gradient end + gradient.append('stop').attr('offset', '100%').attr('stop-color', '#d32f2f') + + // draw the line + const linePath = mainSvg + .append('path') + .datum(sortData) + .attr('fill', 'none') + .attr('stroke', `url(#${gradientId})`) + .style('stroke-width', 5) + .style('opacity', 0.4) + .attr('d', line) + + // create area + const area = d3 + .area() + .x((d) => x(d.date)) + .y0(y(0)) + .y1((d) => y(d.no_of_reports)) + .curve(d3.curveCatmullRom.alpha(0.5)) + + const areaPath = mainSvg + .append('path') + .datum(sortData) + .attr('fill', `url(#${gradientId})`) + .attr('stroke', 'none') + .attr('d', area) + .style('opacity', 0.2) + + // create dots + const dots = mainSvg + .append('g') + .selectAll('circle') + .data(sortData) + .enter() + .append('circle') + .attr('class', 'line-chart-dot') + .attr('r', 8) + .attr('fill', '#d32f2f') + .style('opacity', 0.8) + .attr('cx', (d) => x(d.date)) + .attr('cy', (d) => y(d.no_of_reports)) + + // set mouse event handler + function handleMouseOver() { + linePath.style('opacity', 0.8) + dots.style('opacity', 0.5) + } + + function handleMouseOut() { + linePath.style('opacity', 0.4) + dots.style('opacity', 0.8) + } + + // update tooltip position + function updateTooltipPosition(event) { + tooltip + .style('left', `${event.pageX + 5}px`) + .style('top', `${event.pageY - 28}px`) + } + + // get the tooltip data for area (sum the report numbers) + function calculateTooltipData(data) { + const minDate = d3.min(data, (d) => d.date) + const maxDate = d3.max(data, (d) => d.date) + const totalReports = d3.sum(data, (d) => d.no_of_reports) + + return { + duration: `Duration: ${d3.timeFormat('%Y/%m')(minDate)} - ${d3.timeFormat('%Y/%m')(maxDate)}`, + totalReports, + } + } + + // get tooltip + const tooltip = d3 + .select('body') + .append('div') + .attr('class', 'tooltip') + .style('opacity', 0) + + // tooltip functions + function showTooltip(event) { + const data = sortData + const tooltipData = calculateTooltipData(data) + + tooltip + .style('opacity', 1) + .html( + ` + ${tooltipData.duration}
+ Total reports: ${formatNumber.format(tooltipData.totalReports)} + ` + ) + .style('left', `${event.pageX + 5}px`) + .style('top', `${event.pageY - 28}px`) + } + + function hideTooltip() { + tooltip.style('opacity', 0) + } + + // tooltip events + areaPath + .on('mouseover', (event) => { + showTooltip(event) + }) + .on('mousemove', (event) => { + updateTooltipPosition(event) + }) + .on('mouseout', hideTooltip) + + dots.on('mouseover', (event, d) => { + handleMouseOver() + d3.select(event.currentTarget).style('opacity', 1) + tooltip + .style('opacity', 1) + .html( + `Date: ${d3.timeFormat('%b %Y')(d.date)}
Number of Reports: ${formatNumber.format(d.no_of_reports)}` + ) + .style('left', `${event.pageX + 5}px`) + .style('top', `${event.pageY - 28}px`) + }) + .on('mousemove', (event) => { + updateTooltipPosition(event) + }) + .on('mouseout', () => { + handleMouseOut() + tooltip.style('opacity', 0) + }) + + // update report number format + const formatNumber = new Intl.NumberFormat() + + // append the svg to the container + container.appendChild(mainSvg.node()) + container.appendChild(yAxisSvg.node()) + + // set scrolling + container.style.overflowX = 'auto' + container.style.overflowY = 'hidden' + container.style.whiteSpace = 'nowrap' + + // set main svg width + mainSvg.style('width', `${totalWidth}px`) + + // get right most data + const rightmostDate = d3.max(sortData, (d) => d.date) + + // get pixel position + const scrollToDate = x(rightmostDate) + + // get container central position + const containerCenter = width / 2 + container.scrollLeft = scrollToDate - containerCenter + lineMargin.left + + // ensure scrolling correctly after a slight delay + setTimeout(() => { + container.scrollLeft = scrollToDate - containerCenter + lineMargin.left + }, 100) +} diff --git a/frontend/allsafe/src/app/insights/page.tsx b/frontend/allsafe/src/app/insights/page.tsx new file mode 100644 index 0000000..dfce1a0 --- /dev/null +++ b/frontend/allsafe/src/app/insights/page.tsx @@ -0,0 +1,262 @@ +'use client' + +import { useEffect } from 'react' + +import '../style.css' // Assuming your CSS is in the src/styles folder +import { cn } from '@/lib/utils' +import { TypographyH2 } from '@/typography/h2' +import { TypographyLead } from '@/typography/lead' +import { TypographyH1 } from '@/typography/h1' +import Image from 'next/image' +import Link from 'next/link' + +const Insights = () => { + useEffect(() => { + // This will run after the component mounts + const script = document.createElement('script') + script.src = '/src/script.js' + script.type = 'module' + document.body.appendChild(script) + + return () => { + // Clean up the script when the component unmounts + document.body.removeChild(script) + } + }, []) + + return ( +
+
+ {/* Header with margin for spacing */} + + Do you know how fast the scam growth in the past few years? + + +
+ {/* Line chart container with padding and border for emphasis */} +
+
+
+ + {/* Text description with padding and margin for better readability */} +

+ From January 2020 to July 2024, there have been 18,714 + reported social media scams affecting young adults in + Australia. Comparing the whole year of 2023 and 2022, + reported scams increased by about 21%. The scam reported + peak is in January 2023, with 621 scams reported in just + a month. +
+
+ Although the number of scam reports gradually decreased + from then, the monthly reported scams in 2024 are still + around 300. +
+
+ If the scam is an unexploded boom without a trend for us + to prevent, how will scams influence the digital era if + we don’t have related knowledge to take proper action? +
+
+ + User Guide: + {' '} + Scroll to the left to discover the trend of social media + scams that have occurred with young adults since 2020; + hover over the graph to find the number of scams in each + month and throughout the whole period. +

+
+
+ +
+ + Have you ever received this kind of message? + +
+
+ {/* Word Cloud Image */} + Word Cloud Image +
+

+ This word cloud highlights the most common words + scammers use to make their messages sound personal, + urgent, or convincing. These words are designed to trick + you into responding or taking action based on false + promises. +
+
+ Have you ever received a message that seemed too good to + be true? Did it make you pause and wonder if you might + get easy money, or did it leave you feeling unsure? + Scammers use these tricks to either get you to pay for + something or steal your personal information. +
+
+ Take a look at the word cloud. Can you spot the types of + scams that appear most often? +

+
+
+ +
+
+
+ + Do you know what are the top 5 scams in number of + reports? + + + Click inside each section to discover more. + +
+

Filter by year

+ +
+
+
+
+

+ The sunburst chart shows the top 5 scams by the + number of reports, with each section showing their + percentage and sub-types. +
+
+ Buying or Selling scams are the + most common, making up over 44% of the total and + over 427 reports within 2024. + Online Shopping Scams being the + largest sub-type at around 41% and having 1369 + reports over the years. +
+
+ Meanwhile, The smallest section,{' '} + Mobile Premium Service Scams, only + contributes about 1% which also among the{' '} + Buying or Selling.{' '} + Personal Information scams are the + second-largest, with 1643 reports all over the year.{' '} + Investment Scams in the same time + treated as the main sub-type. +
+
+ This highlights how common online shopping scams and + personal data fraud are becoming. +

+
+
+
+ +
+
+ + Does the money lost follow a similar pattern as the + number of reports? + + + {' '} + User Guide: Click on the bars to explore more detailed + information about money lost among the 5 scam types. + +
+
+
+

+ While the top 5 most frequent scams align with the top 5 + scams causing the most financial loss, their patterns + have some differences. +
+
+ In 2024, the top 5 scams alone accounted for + approximately AUD 3,003,916 in losses, representing + about 94.74% of the total amount lost on social media + scams with young adults. Among these years, investment + scams have the highest financial impact, making up 50.4% + of the total losses, followed by dating and romance + scams, which account for around 17.4%. +
+
+ The different patterns from the number of reports and + money loss indicate that no matter which type of scam + you are facing, the potential loss can accumulate into a + vast amount and continuously influence our daily lives. +
+
+

+
+
+ +
+ +
+ + Explore More with Our Scam Simulation Game! + + + Dive deeper into the world of scams and test your knowledge + with our interactive game! + {/* Why Play? Sort and Analyze: */} + {/*
+ Sort scenarios based on different scam categories and + amounts lost. +
+ Test Your Skills: Challenge yourself to identify and + understand various scam types. +
+ Learn & Protect: Gain valuable insights that can help you + recognize and avoid scams in real life. */} +
+ + Play the Scam Simulation Game + +
+
+ ) +} + +export default Insights diff --git a/frontend/allsafe/src/components/game/branchingnarrativecomponent.tsx b/frontend/allsafe/src/components/game/branchingnarrativecomponent.tsx index 7bee387..5502674 100644 --- a/frontend/allsafe/src/components/game/branchingnarrativecomponent.tsx +++ b/frontend/allsafe/src/components/game/branchingnarrativecomponent.tsx @@ -1,3 +1,5 @@ +'use client' + import { gameData } from '@/data/gameData' import React, { useState, useRef, useEffect } from 'react' import { Button } from '../ui/button' @@ -5,6 +7,9 @@ import { Card, CardHeader, CardDescription, CardContent } from '../ui/card' import gifImg from '@/components/assets/Isometric Bar Snowing.gif' import Image from 'next/image' import Link from 'next/link' +import { TypographyH1 } from '@/typography/h1' +import { TypographyLead } from '@/typography/lead' +import { useRouter } from 'next/navigation' const BranchingNarrativeComponent = ({ scenarios, @@ -13,73 +18,59 @@ const BranchingNarrativeComponent = ({ scenarios: any scenario: number }) => { + const router = useRouter() const [gameBegan, setGameBegan] = useState(false) + const [gameOver, setGameOver] = useState(false) const [currentQuestion, setCurrentQuestion] = useState('q0') const [navAnswer, setNavAnswer] = useState(false) - const [isPlaying, setIsPlaying] = useState(false) const choice = gameData[scenario - 1] - const audioRef = useRef(null) // Ref to control the audio element - const handleAnswerClick = (link: React.SetStateAction) => { if (choice[currentQuestion as keyof typeof choice]) { setCurrentQuestion(link) setNavAnswer(false) setGameBegan(true) - if (audioRef.current && !isPlaying) { - audioRef.current.play() - setIsPlaying(true) - } } else { console.error(`Question with link "${link}" not found in gameData.`) } } - const togglePlayPause = () => { - if (audioRef.current) { - if (isPlaying) { - audioRef.current.pause() - } else { - audioRef.current.play() - } - setIsPlaying(!isPlaying) - } - } - const currentQuestionData = choice[currentQuestion as keyof typeof choice] - useEffect(() => { - // Automatically play music when the game begins - if (gameBegan && audioRef.current) { - audioRef.current.play() - setIsPlaying(true) - } - }, [gameBegan]) - - if (!currentQuestionData && gameBegan) { + if ((!currentQuestionData && gameBegan) || gameOver) { return ( -
-

Game over

-

Play again?

-
- - - - - + + - + + +
+
+

+ Have you been a victim to any of these cases? Go to the + help section to find out what to do next.{' '} + + {' '} + Help Section + +

) @@ -91,10 +82,8 @@ const BranchingNarrativeComponent = ({ return (
-
) } diff --git a/frontend/allsafe/src/components/helper/mute.tsx b/frontend/allsafe/src/components/helper/mute.tsx index 4f0c4c8..9fe6d86 100644 --- a/frontend/allsafe/src/components/helper/mute.tsx +++ b/frontend/allsafe/src/components/helper/mute.tsx @@ -20,9 +20,30 @@ export default function Mute() { } return ( -
- + + + + {volume} + +
) diff --git a/frontend/allsafe/src/data/buying-and-selling.tsx b/frontend/allsafe/src/data/buying-and-selling.tsx index 4139929..ec2e1d5 100644 --- a/frontend/allsafe/src/data/buying-and-selling.tsx +++ b/frontend/allsafe/src/data/buying-and-selling.tsx @@ -2,7 +2,7 @@ export const buyingAndSelling = { q0: { id: 0, question: - "You're browsing an online marketplace looking for a great deal on [Item X] (it could be a phone, gaming console, etc.). You come across an offer that looks almost too good to be true — a brand-new item for a significantly lower price than usual. You decide to reach out to the seller. You message the seller, and they reply almost immediately:\n\nScammer (as Seller):\nHey! Thanks for your interest in [Item X]. I'm selling it because I need the cash urgently. It's brand new, and I can ship it to you right away for just $200. Normally it goes for $500, so you're getting a great deal! Let me know if you're ready to buy.", + "You're browsing an online marketplace looking for a great deal on [Item X] (it could be a phone, gaming console, etc.). You come across an offer that looks almost too good to be true — a brand-new item for a significantly lower price than usual. You decide to reach out to the seller. You message the seller, and they reply almost immediately:\n\nSeller:\nHey! Thanks for your interest in [Item X]. I'm selling it because I need the cash urgently. It's brand new, and I can ship it to you right away for just $200. Normally it goes for $500, so you're getting a great deal! Let me know if you're ready to buy.", answers: [ { text: 'Agree to buy the item at $200.', @@ -22,506 +22,249 @@ export const buyingAndSelling = { }, ], }, + q1: { id: 1, question: - "You agree to buy the item and transfer $200 to the seller using their preferred method of payment. After you send the money, the seller responds:\n\nScammer (as Seller):\nThanks for the payment! I'll ship the item today, and you should receive it within the next few days. I'll send you the tracking information as soon as it's available.\n\nAfter a couple of days, you ask for an update, but the seller becomes unresponsive. You check the tracking number they gave you, and it either doesn't work or shows that no package was shipped. You realize you've been scammed.", + "You agree to buy the item at $200. The seller responds:\n\nSeller:\nGreat! To proceed, please send the payment via wire transfer to this account number [Account Number]. Once I receive the payment, I'll ship the item immediately.\n\nWhat do you do next?", answers: [ { - text: 'Try to contact the seller again and demand a refund.', + text: 'Proceed to send the payment via wire transfer.', link: 'q5', }, { - text: 'File a dispute with the payment platform (e.g., PayPal) to try and recover your money.', + text: 'Express concern about using wire transfer and ask for a more secure payment method.', link: 'q6', }, { - text: 'Report the seller to the marketplace and authorities.', + text: 'Decide not to proceed with the purchase and ignore the seller.', link: 'q7', }, ], }, + q2: { id: 2, question: - "Before I send the payment, could you provide more pictures of the item and confirm how you'll ship it to me? I just want to make sure everything is legit.\n\nScammer (as Seller):\nSure! Here are a few more photos. I'll be shipping it via [reputable shipping service], and I'll send you a tracking number as soon as it's shipped. Don't worry, I've sold a few of these before without any problems. You'll get the item within 3 days.\n\nThe photos look genuine, but there's still something that feels off. The price is still too good to be true.", + "You ask for more details about the item and the shipping process. The seller replies:\n\nSeller:\nIt's the latest model, unopened box. As for shipping, I'll send it out as soon as I receive payment. I prefer wire transfer to avoid extra fees. Trust me, you won't regret this deal!\n\nWhat do you do next?", answers: [ { - text: 'Trust the seller and proceed with the payment.', - link: 'q1', + text: 'Agree to proceed with the purchase via wire transfer.', + link: 'q5', }, { - text: 'Ask for proof of past successful transactions or reviews from other buyers.', - link: 'q8', + text: 'Ask if you can use a more secure payment method like PayPal or meet in person.', + link: 'q6', + }, + { + text: 'Decide not to proceed with the purchase and ignore the seller.', + link: 'q7', }, ], }, + q3: { id: 3, question: - "I'd prefer to meet in person to make the purchase. Can we arrange a time to meet so I can inspect the item before I pay?\n\nScammer (as Seller):\nI'd love to, but I'm currently out of town/on a business trip. I can't meet right now, but I can ship it to you immediately. If you don't like it when it arrives, you can always return it.", + "You ask to meet in person before buying. The seller responds:\n\nSeller:\nI'd love to, but I'm currently out of town for work. That's why I'm offering to ship it to you. Don't worry, I'll make sure it gets to you safely after the payment.\n\nWhat do you do next?", answers: [ { - text: "Accept the seller's reasoning and proceed with payment.", - link: 'q1', + text: 'Proceed to agree and send the payment via wire transfer.', + link: 'q5', }, { - text: 'Insist on an in-person meeting or drop the deal.', - link: 'q9', + text: 'Insist on waiting until they return to meet in person.', + link: 'q8', + }, + { + text: 'Decide to cancel the transaction and ignore the seller.', + link: 'q7', }, ], }, + q4: { id: 4, question: - "You take a step back and do some research on the seller, looking for any reviews, previous sales, or comments from other buyers. After a few minutes, you find some alarming signs:\n\n• The seller's account is only a few days old.\n• There are no ratings or reviews, or some reviews mention unfulfilled orders and suspicious activity.\n• The price is much lower than any other listing for the same item, raising red flags.", + 'You conduct your own research on the seller. You find that their profile is new and lacks previous activity. There are no reviews or feedback from other buyers. This raises suspicion.\n\nWhat do you do next?', answers: [ { - text: 'Confront the seller with your findings.', - link: 'q10', + text: 'Proceed with caution and ask the seller for verification or more details.', + link: 'q2', }, { - text: 'Report the seller to the marketplace platform.', - link: 'q11', + text: 'Decide not to proceed with the purchase and ignore the seller.', + link: 'q7', }, ], }, + q5: { id: 5, question: - "You try to contact the seller, but they either stop responding altogether or continue to give excuses like:\n\nScammer (as Seller):\nHey, sorry about the delay! The package is stuck with the shipping company. I'm trying to get it sorted out. Please give me a couple more days.\n\nAfter another week of waiting, it becomes clear that you won't be receiving the item.", + "You send the payment via wire transfer. After confirming the transfer, the seller stops responding to your messages. Days pass and you don't receive the item. You realize you've been scammed.\n\nWhat do you do next?", answers: [ { - text: 'Accept the loss.', - link: 'q12', + text: 'Report the seller to the marketplace platform.', + link: 'q9', }, { - text: 'Escalate the issue with the payment platform.', - link: 'q6', + text: 'Contact your bank to see if the transfer can be reversed.', + link: 'q10', + }, + { + text: 'Do nothing and accept the loss.', + link: 'q11', }, ], }, + q6: { id: 6, question: - "You file a dispute with the payment platform (e.g., PayPal, Venmo, etc.), providing evidence that the seller hasn't shipped the item and that you suspect it's a scam. The platform may initiate an investigation:", + "You express concern about using wire transfer and ask for a more secure payment method. The seller responds:\n\nSeller:\nSorry, I can only accept wire transfers right now. It's the quickest way for me to get the funds. Do you still want to proceed?\n\nWhat do you do next?", answers: [ { - text: 'Wait for the outcome (buyer protection method used).', - link: 'q13', + text: 'Agree to proceed with the wire transfer despite your concerns.', + link: 'q5', }, { - text: 'Wait for the outcome (non-refundable method used).', - link: 'q14', + text: 'Decide not to proceed with the purchase and ignore the seller.', + link: 'q7', }, ], }, + q7: { id: 7, question: - 'You decide to report the seller to the online marketplace and local authorities, providing all the necessary documentation (screenshots of messages, proof of payment, etc.). The marketplace may:', + 'You decide not to proceed with the purchase and ignore the seller. However, you wonder if you should report this person to prevent others from being scammed.\n\nDo you want to report the seller?', answers: [ { - text: "Ban the scammer's account and remove the listing.", - link: 'q15', + text: 'Yes, report the seller to the marketplace platform.', + link: 'q12', }, { - text: 'Provide guidance on how to file a report with authorities.', - link: 'q16', + text: 'No, do nothing further.', + link: 'q15', }, ], }, + q8: { id: 8, question: - "Could you show me proof of any successful sales you've done before? I'd just feel more comfortable if I knew other buyers were happy with their purchases.\n\nScammer (as Seller):\nSure! Here's a screenshot of the last sale I made for the same item. The buyer was really happy, and I can even give you their contact info if you want.\n\nThe screenshot looks convincing, but you're unsure whether it's genuine or doctored.", + "You insist on waiting until they return to meet in person. The seller replies:\n\nSeller:\nI understand, but I really need to sell this quickly. If you're not interested, I might have to offer it to someone else.\n\nWhat do you do next?", answers: [ { - text: 'Trust the proof and proceed with the purchase.', - link: 'q1', - }, - { - text: 'Ask to contact the previous buyer to confirm the sale.', - link: 'q17', - }, - { - text: 'Become suspicious and decide not to go through with the transaction.', - link: 'q18', - }, - ], - }, - q9: { - id: 9, - question: - "I'm sorry, but I'm only comfortable with meeting in person. If we can't meet, I'll have to pass on the deal.\n\nThe seller tries to convince you, but eventually backs off:\n\nScammer (as Seller):\nI understand. If you change your mind, let me know. I'll keep it available for now.", - answers: [ - { - text: 'End the conversation and avoid the scam.', - link: 'q19', - }, - ], - }, - q10: { - id: 10, - question: - "I looked into your account, and there are a lot of red flags. Your account is new, and there are reports from other buyers about missing items. I'm not comfortable moving forward with this.\n\nScammer (as Seller):\nThose are fake reviews left by competitors. I can assure you that I'm legitimate. I've sold many items without any issues. If you don't trust me, that's fine, but you're going to miss out on a great deal.", - answers: [ - { - text: "Trust the seller's explanation and proceed with the payment.", - link: 'q1', - }, - { - text: 'Walk away from the deal entirely, avoiding the scam.', - link: 'q20', - }, - ], - }, - q11: { - id: 11, - question: - "You've reported the seller to the marketplace platform. What would you like to do next?", - answers: [ - { - text: "Wait for the platform's response and avoid further contact with the seller.", - link: 'q21', - }, - { - text: 'Look for a different seller for the item you want.', - link: 'q22', - }, - ], - }, - q12: { - id: 12, - question: - "You've lost the $200, and the scammer has disappeared. You've decided to accept the loss. What would you like to do next?", - answers: [ - { - text: 'Share your experience to warn others about this scam.', - link: 'q23', - }, - { - text: 'Research ways to protect yourself from similar scams in the future.', - link: 'q24', - }, - ], - }, - q13: { - id: 13, - question: - 'After a few days of investigation, the payment platform decides in your favor since you used a method that offers buyer protection. They refund your $200.', - answers: [ - { - text: 'Feel relieved and decide to be more cautious in future online transactions.', - link: 'q25', - }, - { - text: 'Report the scammer to the marketplace to prevent others from being victimized.', - link: 'q7', - }, - ], - }, - q14: { - id: 14, - question: - 'Unfortunately, since you used a non-refundable payment method, the platform denies your request for a refund. Your $200 is gone.', - answers: [ - { - text: 'Accept the loss and learn from the experience.', - link: 'q12', - }, - { - text: 'Explore other options for recourse, such as reporting to authorities.', - link: 'q7', - }, - ], - }, - q15: { - id: 15, - question: - "The marketplace has banned the scammer's account and removed the listing. While this doesn't recover your money, it helps prevent others from falling victim to the same scam.", - answers: [ - { - text: "Feel satisfied that you've helped protect others and move on.", - link: 'q26', - }, - { - text: 'Continue to pursue the case with local authorities.', - link: 'q27', - }, - ], - }, - q16: { - id: 16, - question: - 'The marketplace provides you with guidance on how to file a report with local authorities. They explain that while it may be difficult to track down the scammer, filing a report can help build a case if the scammer is caught in the future.', - answers: [ - { - text: 'Follow through and file a report with the authorities.', - link: 'q27', - }, - { - text: "Decide it's not worth the effort and move on from the experience.", - link: 'q26', - }, - ], - }, - q17: { - id: 17, - question: - 'You contact the "previous buyer," who happens to be an accomplice of the scammer. They tell you how happy they are with the purchase and how everything went smoothly. This reassures you, and you proceed with the transaction, leading to eventual loss.', - answers: [ - { - text: "Realize you've been scammed and try to recover your money.", + text: 'Decide to proceed with the wire transfer to secure the deal.', link: 'q5', }, { - text: 'Accept the loss and report the scammer to prevent future victims.', + text: 'Stick to your decision to meet in person, even if it means losing the deal.', link: 'q7', }, ], }, - q18: { - id: 18, - question: - 'You decide to investigate the photos by doing a reverse image search. After a few moments, you find that the images are from a completely different listing on another website.', - answers: [ - { - text: 'Confront the seller about the stolen images.', - link: 'q28', - }, - { - text: 'Report the seller to the marketplace without confrontation.', - link: 'q11', - }, - ], - }, - q19: { - id: 19, - question: - "You've successfully avoided the scam by insisting on meeting in person. The scammer backed off when they realized you wouldn't fall for their trick. What would you like to do next?", - answers: [ - { - text: 'Look for a legitimate seller for the item you want.', - link: 'q22', - }, - { - text: 'Report the suspicious seller to the marketplace.', - link: 'q11', - }, - ], - }, - q20: { - id: 20, + + q9: { + id: 9, question: - "You've decided to walk away from the deal, successfully avoiding the scam. Your suspicions about the seller's account and the too-good-to-be-true offer were well-founded. What's your next step?", + 'You report the seller to the marketplace platform.\n\nOn which platform do you want to learn how to report this seller?', answers: [ { - text: 'Report the suspicious seller to the marketplace.', - link: 'q11', - }, - { - text: 'Look for a more reputable seller for the item you want.', - link: 'q22', + text: 'Facebook Marketplace', + link: 'q9Facebook', }, - ], - }, - q21: { - id: 21, - question: - "You've successfully prevented the scam from progressing by reporting the seller to the marketplace platform. What would you like to do next?", - answers: [ { - text: "Wait for the platform's response before taking any further action.", - link: 'q29', + text: 'Instagram Marketplace', + link: 'q9Instagram', }, { - text: 'Start looking for a legitimate seller for the item you want.', - link: 'q22', + text: 'TikTok Marketplace', + link: 'q9TikTok', }, ], }, - q22: { - id: 22, - question: - "You've decided to look for a different seller for the item you want. This time, you're more cautious and aware of potential scams. How would you like to proceed?", - answers: [ - { - text: 'Search for sellers with good ratings and reviews.', - link: 'q30', - }, - { - text: 'Look for local sellers to enable in-person transactions.', - link: 'q31', - }, - ], - }, -} -const gameData = { - q0: { - id: 0, - question: - "The scammer reaches out to the player with a direct message, claiming they found the player's profile through a job posting platform, social media, or online résumé. The scammer's offer seems attractive, offering a high salary for remote work or a part-time job that doesn't require special qualifications.", - answers: [ - { - text: 'Show interest and ask for more details about the job.', - link: 'q1', - }, - { - text: "Ask how they found your profile and why they think you're a good fit.", - link: 'q2', - }, - { - text: 'Ignore the message and block the scammer.', - link: 'q3', - }, - ], - }, - q1: { - id: 1, + + q9Facebook: { + id: 9, question: - 'You express interest in the job offer and ask for more details. The scammer responds enthusiastically but quickly shifts focus to the next steps involving personal information.', - answers: [ - { - text: "Agree to provide the information and proceed with the 'hiring process.'", - link: 'q4', - }, - { - text: 'Ask for a company website or references to verify the legitimacy of the job offer.', - link: 'q5', - }, - { - text: 'Recognize the red flags and stop responding.', - link: 'q6', - }, - ], + "You report the seller on Facebook Marketplace.\n\nOpen your Facebook app.\n\nIn the bottom right, tap ☰ **Menu**, then tap **Marketplace**.\n\nTap a listing from the seller that you want to report, then tap the seller's name below Seller information.\n\nTap **more**, then tap **Report**.\n\nFollow the on-screen instructions.\n\nThe platform acknowledges your report and promises to investigate. You've taken the right step to protect yourself and others from potential scams.\n\n**Conclusion:** By reporting the suspicious seller, you help make the online marketplace safer for everyone. Always be cautious when deals seem too good to be true, and prefer secure payment methods.", + answers: [], + end: true, }, - q2: { - id: 2, + + q9Instagram: { + id: 9, question: - "You're cautious and ask the scammer how they found your profile and why they believe you're a good fit.", - answers: [ - { - text: 'Ask for more specific details about where they found your profile.', - link: 'q7', - }, - { - text: "Ask why they're reaching out if you haven't applied for jobs recently.", - link: 'q8', - }, - { - text: 'Express suspicion and end the conversation.', - link: 'q6', - }, - ], + "You report the seller on Instagram Marketplace.\n\nGo to the profile of the seller that you want to report.\n\nTap **… (iPhone)** or **︙(Android)** in the top right.\n\nTap **Report**, then tap **Report account**.\n\nTap **It's posting content that shouldn't be on Instagram**.\n\nScroll down, then select **Misleading or possible scam**.\n\nThe platform acknowledges your report and promises to investigate. You've taken the right step to protect yourself and others from potential scams.\n\n**Conclusion:** By reporting the suspicious seller, you help make the online marketplace safer for everyone. Always be cautious when deals seem too good to be true, and prefer secure payment methods.", + answers: [], + end: true, }, - q3: { - id: 3, + + q9TikTok: { + id: 9, question: - "You decide to ignore the message and block the scammer. You've heard about job scams before and don't want to take any chances.", - answers: [ - { - text: 'End the conversation and block the scammer.', - link: 'end', - }, - ], + "You report the seller on TikTok Marketplace.\n\nIn the TikTok app, tap **Profile** at the bottom.\n\nTap the **Menu ☰** button at the top, then select **Settings and privacy**.\n\nTap **Report a problem**. From here, you can:\n\n ༚ Select a **Topic**. You might be prompted to select a subtopic within each topic. Follow the instructions to resolve the problem. If the suggested steps don't resolve your issue, tap **No** to the question **Is your problem resolved?**, then tap **Need more help?** to contact us with further details.\n\n ༚ Scroll down and tap **Chat with us**.\n\nChat with our helpdesk to resolve the problem.\n\nThe platform acknowledges your report and promises to investigate. You've taken the right step to protect yourself and others from potential scams.\n\n**Conclusion:** By reporting the suspicious seller, you help make the online marketplace safer for everyone. Always be cautious when deals seem too good to be true, and prefer secure payment methods.", + answers: [], + end: true, }, - q4: { - id: 4, + + q10: { + id: 10, question: - "You agree to provide the information and proceed with the 'hiring process.' The scammer continues to ask for more personal details, such as your Social Security number, credit card information, or passwords.", - answers: [ - { - text: "Provide the information, trusting the scammer's promises of a high-paying job.", - link: 'q9', - }, - { - text: 'Become suspicious and refuse to provide any more information.', - link: 'q10', - }, - ], + "You contact your bank to inquire about reversing the wire transfer. The bank informs you that wire transfers are difficult to reverse, but they will investigate. Unfortunately, recovering the funds may not be possible.\n\n**Conclusion:** It's important to use secure payment methods that offer buyer protection. Be wary of sellers who insist on wire transfers.\n\n**Feedback:** While it's unfortunate that you lost money, contacting your bank was a proactive step.", + answers: [], }, - q5: { - id: 5, + + q11: { + id: 11, question: - "You ask for a company website or references to verify the legitimacy of the job offer. The scammer avoids providing this information, claiming that the company is new or that they can't share it for confidentiality reasons.", - answers: [ - { - text: 'Continue to press for more information, suspecting something is wrong.', - link: 'q10', - }, - { - text: 'Trust their explanation and proceed with the job offer.', - link: 'q4', - }, - ], + "You decide to accept the loss and move on, feeling disappointed and more cautious about future online purchases.\n\n**Conclusion:** Scams can happen to anyone. In the future, consider using secure payment methods and verifying sellers before making purchases.\n\n**Feedback:** It's important to learn from this experience to avoid similar situations.", + answers: [], }, - q6: { - id: 6, + + q12: { + id: 12, question: - "You express suspicion and end the conversation. You've heard about job scams before and don't want to take any chances.", + 'You report the seller to the marketplace platform.\n\nOn which platform do you want to learn how to report this seller?', answers: [ { - text: 'End the conversation and block the scammer.', - link: 'end', + text: 'Facebook Marketplace', + link: 'q9Facebook', }, - ], - }, - q7: { - id: 7, - question: - "You ask for more specific details about where they found your profile. The scammer provides a vague answer, such as 'a job board' or 'a database of resumes.'", - answers: [ { - text: 'Continue to press for more information, suspecting something is wrong.', - link: 'q10', + text: 'Instagram Marketplace', + link: 'q9Instagram', }, { - text: 'Trust their explanation and proceed with the job offer.', - link: 'q4', + text: 'TikTok Marketplace', + link: 'q9TikTok', }, ], }, - q8: { - id: 8, + + q15: { + id: 15, question: - "You ask why they're reaching out if you haven't applied for jobs recently. The scammer claims that they were impressed by your profile and think you'd be a great fit.", + "You choose not to report the seller. However, reporting suspicious accounts helps protect others from scams. It's important to report such incidents to keep the community safe.\n\nDo you want to reconsider and report the seller?", answers: [ { - text: 'Continue to press for more information, suspecting something is wrong.', - link: 'q10', - }, - { - text: 'Trust their explanation and proceed with the job offer.', - link: 'q4', + text: 'Yes, I will report the seller now.', + link: 'q12', }, - ], - }, - q9: { - id: 9, - question: - "You provide the information, trusting the scammer's promises of a high-paying job. The scammer disappears after receiving your personal information.", - answers: [ { - text: 'End the conversation and report the scammer to the authorities.', - link: 'end', + text: 'No, I still prefer not to report.', + link: 'q14', }, ], }, - q10: { - id: 10, + + q14: { + id: 14, question: - 'You become suspicious and refuse to provide any more information. You end the conversation and block the scammer.', - answers: [ - { - text: 'End the conversation and block the scammer.', - link: 'end', - }, - ], - }, - end: { - id: 'end', - question: 'You successfully avoided the job scam.', + 'You decide not to take any further action. The seller may continue to operate on the platform and potentially scam others.\n\n**Conclusion:** By not reporting, others may fall victim to the same scam. Consider reporting in the future to help protect the community.\n\n**Feedback:** Next time, reporting suspicious activity can make a significant difference in preventing scams.', answers: [], }, }