Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion scorebored/src/lib/firebase/firebase.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { writable, derived } from "svelte/store";

// Your web app's Firebase configuration (Replace with your actual config)
const firebaseConfig = {
apiKey: import.meta.env.VITE_APIKEY,
apiKey: import.meta.env.VITE_API_KEY,
authDomain: "scorebored2-e7ffd.firebaseapp.com",
databaseURL: "https://scorebored2-e7ffd-default-rtdb.firebaseio.com",
projectId: "scorebored2-e7ffd",
Expand Down
230 changes: 141 additions & 89 deletions scorebored/src/routes/login/username/+page.svelte
Original file line number Diff line number Diff line change
@@ -1,29 +1,22 @@
<script lang="ts">
import AuthCheck from "$lib/components/AuthCheck.svelte";
import { db } from "$lib/firebase/firebase";
import { doc, getDoc, writeBatch } from "firebase/firestore";
import { doc, getDoc, setDoc, onSnapshot, collection } from "firebase/firestore";
import { getAuth, onAuthStateChanged } from "firebase/auth";
import { onMount } from 'svelte';

let BoardID = "";
let BoardName = '';
let datapoints = []; // 예시: [1.0, 2.0, 3.0]
let datapoints = [];
let isQuantity = false;
let X_axis = '';
let Y_axis = '';
let numTarget = 0;
let timeTarget = 0;
let lastEdited = new Date();
let Username = ''; // 사용자 컬렉션에 추가할 필드
let loading = false;
let isAvailable = false;
let debounceTimer;
let Username = '';
let currentUser = null;

const re = /^(?=[a-zA-Z0-9._]{3,16}$)(?!.*[_.]{2})[^_.].*[^_.]$/;
$: isValid = BoardID?.length > 2 && BoardID.length < 16 && re.test(BoardID);
$: isTouched = BoardID.length > 0;
$: isTaken = isValid && !isAvailable && !loading;
let referenceArray = [];

onMount(() => {
const auth = getAuth();
Expand All @@ -36,46 +29,122 @@
});
});

async function checkAvailability() {
isAvailable = false;
clearTimeout(debounceTimer);
loading = true;
debounceTimer = setTimeout(async () => {
const ref = doc(db, "user", BoardID);
const docSnap = await getDoc(ref);
isAvailable = !docSnap.exists();
loading = false;
}, 500);
async function loadBoardData() {
if (!BoardID) {
console.error("No BoardID provided");
return;
}

try {
const boardRef = doc(db, "scoreboard", BoardID);
const boardSnap = await getDoc(boardRef);

if (boardSnap.exists()) {
const boardData = boardSnap.data();
BoardName = boardData.BoardName;
datapoints = boardData.datapoints;
isQuantity = boardData.isQuantity;
X_axis = boardData.X_axis;
Y_axis = boardData.Y_axis;
numTarget = boardData.numTarget;
timeTarget = boardData.timeTarget;
referenceArray = boardData.referenceArray || [];
await initializeDatapoints();
monitorChildBoards();
} else {
console.error("No such document!");
}
} catch (error) {
console.error("Error loading board data:", error);
}
}

async function initializeDatapoints() {
if (!isQuantity) {
await Promise.all(referenceArray.map(async (childBoardID, index) => {
if (childBoardID) {
const childBoardRef = doc(db, "scoreboard", childBoardID);
const childBoardSnap = await getDoc(childBoardRef);
if (childBoardSnap.exists()) {
const childBoardData = childBoardSnap.data();
datapoints[index] = childBoardData.isCompleted;
}
}
}));
// 강제 업데이트를 위해 Svelte의 상태를 업데이트
datapoints = [...datapoints];
}
}

function addDatapoint() {
datapoints.push(isQuantity ? 0 : false);
if (!isQuantity) {
referenceArray.push('');
}
}

function removeDatapoint(index) {
datapoints.splice(index, 1);
if (!isQuantity) {
referenceArray.splice(index, 1);
}
}

function updateDatapoint(value, index) {
datapoints[index] = isQuantity ? parseFloat(value) : value === 'true';
}

function monitorChildBoards() {
if (!isQuantity) {
referenceArray.forEach((childBoardID, index) => {
if (childBoardID) {
const childBoardRef = doc(db, "scoreboard", childBoardID);
onSnapshot(childBoardRef, (doc) => {
const childBoardData = doc.data();
if (childBoardData && childBoardData.isCompleted !== undefined) {
datapoints[index] = childBoardData.isCompleted;
// 강제 업데이트를 위해 Svelte의 상태를 업데이트
datapoints = [...datapoints];
}
});
}
});
}
}

async function confirmBoardID() {
if (!currentUser) {
console.error("User not found");
return;
}
const uid = currentUser.uid;

const batch = writeBatch(db);
batch.set(doc(db, "user", uid), { uid: uid, Username: Username });
batch.set(doc(db, "scoreboard", BoardID), {
uid,
let isCompleted = isQuantity ? datapoints.reduce((sum, value) => sum + value, 0) >= numTarget : datapoints.every(value => value === true);

const scoreboardRef = BoardID ? doc(db, "scoreboard", BoardID) : doc(collection(db, "scoreboard"));

await setDoc(scoreboardRef, {
uid: currentUser.uid,
BoardName,
datapoints,
isQuantity,
X_axis,
Y_axis,
numTarget,
timeTarget,
lastEdited: lastEdited.toISOString()
isCompleted,
lastEdited: lastEdited.toISOString(),
referenceArray
});

try {
await batch.commit();
} catch (error) {
console.error("Error in batch commit:", error);
if (!BoardID) {
BoardID = scoreboardRef.id;
}

BoardID = '';
await setDoc(doc(db, "user", currentUser.uid), {
uid: currentUser.uid,
Username: Username
});

BoardName = '';
datapoints = [];
isQuantity = false;
Expand All @@ -85,67 +154,50 @@
timeTarget = 0;
lastEdited = new Date();
Username = '';
isAvailable = false;
}
</script>

<AuthCheck>
<form class="w-2/5" on:submit|preventDefault={confirmBoardID}>
<input
type="text"
placeholder="BoardID"
class="input w-full"
bind:value={BoardID}
on:input={checkAvailability}
class:input-error={(!isValid && isTouched)}
class:input-warning={isTaken}
class:input-success={isAvailable && isValid && !loading}
/>
<input
type="text"
placeholder="Username"
class="input w-full my-2"
bind:value={Username}
/>
<input
type="text"
placeholder="Board Name"
class="input w-full my-2"
bind:value={BoardName}
/>
<!-- datapoints 및 기타 필드를 위한 추가적인 입력 필드가 필요합니다. -->
<!-- 예시: <input type="text" placeholder="Data Points" ...> -->
<input
type="checkbox"
class="checkbox"
bind:checked={isQuantity}
/> Is Quantity?
<input
type="text"
placeholder="X Axis"
class="input w-full my-2"
bind:value={X_axis}
/>
<input
type="text"
placeholder="Y Axis"
class="input w-full my-2"
bind:value={Y_axis}
/>
<input
type="number"
placeholder="Number Target"
class="input w-full my-2"
bind:value={numTarget}
/>
<input
type="number"
placeholder="Time Target"
class="input w-full my-2"
bind:value={timeTarget}
/>
<button class="btn btn-success" type="submit" disabled={!isValid || !isAvailable || loading}>
Confirm BoardID
</button>
<div class="text-lg font-bold my-2">
Board ID:
<input type="text" class="input w-full my-2" bind:value={BoardID} />
<button class="btn btn-primary" type="button" on:click={loadBoardData}>Load Board Data</button>
</div>
<input type="text" placeholder="Board Name" class="input w-full my-2" bind:value={BoardName} />
<input type="checkbox" class="checkbox" bind:checked={isQuantity} /> Is Quantity?
<input type="text" placeholder="X Axis" class="input w-full my-2" bind:value={X_axis} />
<input type="text" placeholder="Y Axis" class="input w-full my-2" bind:value={Y_axis} />
<input type="number" placeholder="Number Target" class="input w-full my-2" bind:value={numTarget} />
<input type="number" placeholder="Time Target" class="input w-full my-2" bind:value={timeTarget} />

<div>
<button type="button" on:click={addDatapoint}>Add Datapoint</button>
{#each datapoints as datapoint, index}
<div class="flex items-center my-2">
{#if isQuantity}
<input
type="number"
class="input"
bind:value={datapoints[index]}
/>
{:else}
<input
type="text"
class="input"
placeholder="Child Board ID"
bind:value={referenceArray[index]}
/>
<select bind:value={datapoints[index]} on:change={(event) => updateDatapoint(event.target.value, index)}>
<option value="true" selected={datapoint === true}>True</option>
<option value="false" selected={datapoint === false}>False</option>
</select>
{/if}
<button type="button" on:click={() => removeDatapoint(index)}>Remove</button>
</div>
{/each}
</div>

<button class="btn btn-success" type="submit">Confirm BoardID</button>
</form>
</AuthCheck>