Individual Contributions ‐ Ümit Can Evleksiz - bounswe/bounswe2024group11 GitHub Wiki

Ümit Can Evleksiz

Responsibilities

  • Developing frontend features, including Authentication, Quiz, Forum, and Leaderboard functionalities.
  • Deploying the frontend application.
  • Ensuring code quality and adherence to best practices in frontend development, including:
    • Schema validation.
    • Proper usage of Typescript types.
    • API contract development and adherence.
    • State management.
  • Designing and defining API contracts, including request and response schemas.
  • Enhancing the user experience (UX) and user interface (UI) of the frontend application.
  • Enforcing WCAG, WAI-ARIA, and SVG standards in the frontend application to ensure accessibility and compliance.
  • Library/Package management for FE app. Introduce new ones or discard irrelevant ones as per the application needs.

Main Contributions

  • Establishing and defining the standards to be followed in implementing frontend code.
  • Developing API contracts for the Quiz and Forum domains.
  • Refactoring and improving the authentication logic in the frontend.
  • Implementing the Quiz feature in the frontend.
  • Implementing the Forum feature in the frontend.
  • Defining standards for schema validation and data fetching in the frontend.
  • Creating a deployment pipeline for the frontend, including writing a Dockerfile.
  • Implementing the connection between the Quiz and Forum features (e.g., associating relevant quizzes and quiz options) across both frontend and backend.

API Contributions

Created initial quiz and forum schemas. Upon the implementation of backend, refined them over time as we added new features. HTTP API req/res can be found at here

Here is the client code to correctly validate and use responses.

  • Quiz Schema

Forum.schema.ts

const quizTagSchema = object({
    name: string(),
    linked_data_id: string(),
    description: string(),
});

const ratingSchema = object({
    score: nullable(number()),
    count: number(),
});

export const quizQuestionSchema = object({
    id: number(),
    question_text: string(),
    choices: array(
        object({
            id: number(),
            is_correct: boolean(),
            choice_text: string(),
        }),
    ),
    hints: nullable(
        array(
            object({
                id: number(),
                text: string(),
                type: string(),
            }),
        ),
    ),
});


export const questionsSchema = array(quizQuestionSchema);
export const quizOverviewSchema = object({
    id: number(),
    title: string(),
    description: string(),
    author: object({
        full_name: string(),
        username: string(),
        avatar: string(),
        id: number(),
        email: string(),
    }),
    created_at: string(),
    tags: array(quizTagSchema),
    type: number(),
    num_taken: number(),
    is_my_quiz: boolean(),
    is_taken: boolean(),
    questions: questionsSchema,
    //question_count: nullable(number()),
    rating: ratingSchema,
    difficulty: number(),
});

export const quizAnswerSchema = object({
    question: number(),
    answer: number(),
    is_hint_used: boolean(),
});

export const quizAnswersSchema = array(quizAnswerSchema);

export const completedQuizSchema = object({
    quiz: number(),
    answers: quizAnswersSchema,
});

export const quizDetailsSchema = object({
    ...quizOverviewSchema.entries,
    questions: questionsSchema,
});

export const quizSchema = object({
    id: number(),
    title: string(),
    description: string(),
    author: object({
        full_name: string(),
        username: string(),
        avatar: string(),
        id: number(),
        email: string(),
    }),
    created_at: string(),
    tags: array(
        object({
            name: string(),
            linked_data_id: string(),
            description: string(),
        }),
    ),
    type: number(),
    num_taken: number(),
    is_my_quiz: boolean(),
    is_taken: boolean(),
    questions: array(
        object({
            id: number(),
            question_text: string(),
            choices: array(
                object({
                    id: number(),
                    is_correct: boolean(),
                    choice_text: string(),
                }),
            ),
            hints: optional(
                array(
                    object({
                        id: number(),
                        type: string(),
                        text: string(),
                    }),
                ),
            ),
        }),
    ),
    //question_count: nullable(number()),
    difficulty: number(),
    rating: object({
        score: nullable(number()),
        count: number(),
    }),
});


  • Forum Schema

Forum.schema.ts



const tagSchema = object({
    name: string(),
    linked_data_id: string(),
    description: string(),
});

export const answerSchema = object({
    id: number(),
    answer: string(),
    author: authorSchema,
    created_at: string(),
    is_upvoted: nullable(number()),
    is_downvoted: nullable(number()),
    upvotes_count: nullable(number()),
    downvotes_count: nullable(number()),
    forum_question: nullable(number()),
});

export const forumQuestionSchema = object({
    id: number(),
    title: string(),
    question: string(),
    tags: array(tagSchema),
    author: authorSchema,
    created_at: string(),
    answers_count: number(),
    is_bookmarked: nullable(number()),
    is_upvoted: nullable(number()),
    is_downvoted: nullable(number()),
    upvotes_count: number(),
    downvotes_count: number(),
    answers: array(answerSchema),
    is_my_forum_question: boolean(),
    quiz_question: nullable(quizQuestionSchema),
    quiz_question_type: nullable(number()),
});

export const forumSchema = object({
    count: number(),
    next: nullable(string()),
    previous: nullable(string()),
    results: array(forumQuestionSchema),
});

export const forumBookmarkSchema = object({
    id: number(),
    user: number(),
    forum_question: number(),
    created_at: string(), // ISO date string
});

export const forumUpvoteSchema = object({
    id: number(),
    user: number(),
    forum_question: number(),
    created_at: string(), // ISO date string
});

export const forumDownvoteSchema = object({
    id: number(),
    user: number(),
    forum_question: number(),
    created_at: string(), // ISO date string
});

export const forumAnswerSchema = object({
    answer: string(),
});

export const forumAnswerUpvoteSchema = object({
    id: number(),
    user: number(),
    forum_answer: number(),
    created_at: string(), // ISO date string
});

export const forumAnswerDownvoteSchema = object({
    id: number(),
    user: number(),
    forum_answer: number(),
    created_at: string(), // ISO date string
});

const wordSchema = object({
    id: string(),
    description: string(),
});

export const dictionarySchema = object({
    NOUN: undefinedable(array(wordSchema)),
    VERB: undefinedable(array(wordSchema)),
    ADJ: undefinedable(array(wordSchema)),
    ADV: undefinedable(array(wordSchema)),
});

Code Related Significant Issues

All Issues

Issue Title Description Issue and/or PR Link
Document WAI-ARIA 1.2 Standards for Accessibility Compliance Documented and ensured compliance with WAI-ARIA 1.2 standards for better accessibility. #597
Radio Buttons Accessibility in Quiz Feed Fixed ARIA standards for radio buttons in the Quizzes tab, ensuring proper focus navigation. #599
Replace Generic Error Page Designed and implemented a branded error page for better UX and DX. #562
Accessible Logo SVG Enhanced accessibility by adding appropriate tags and attributes to the logo SVG component. #606
Backend Pagination Dynamic Page Number Fixed the pagination issue by dynamically changing page_number with input values. #658
Wrapper for Axios Requests Implemented a secure wrapper for HTTP requests using Axios for authenticated endpoints. #660
Use Cookies for Auth Tokens Replaced local storage with cookies for storing authentication tokens for better security. #661
Forum Question Tagging Implemented functionality for tagging forum questions on the client. #683
Move Forum Question Creation to New Page Refactored forum question creation to be handled on a separate page. #687
Fix Author Schema Mismatch Unified author schema usage across the client app using schemas.ts. #690
Profile Routes and Avatars Created routes for "My Profile" and "Profile" pages, and connected forum cards to avatars. #712
Language Selection for Tagging Added query parameters to enable language selection for tagging. #702
Render Relevant Quiz Question in Forum Implemented rendering of relevant quiz questions in the forum question creation screen. #700
Render Relevant Question in Feed Implemented rendering of relevant questions in the forum feed. #699
Accessible Hint Component Developed a reusable and accessible hint component. #698
Unify Query Param Structure Unified query parameter structure and implemented a "should revalidate" mechanism. #697
Implement Quiz Review Added a feature to review solved quizzes on the client. #688

Management Related Significant Issues

All Issues

Issue Title Description Issue and/or PR Link
Point Structure for Quiz Questions Developed a detailed point structure for quizzes based on various criteria, documented it in the project’s wiki. #602
CORS Configuration for Backend Resolved the lack of CORS configuration to connect the client and backend services for Milestone 2 demo. #651

PRs

All PRs

PR Summary
#646 (Lab 7: Refined UX decisions, ensured compliance with W3C standards, implemented pagination for the forum, added upvote/downvote/bookmark functionalities, and reorganized file structures for improved maintainability.)
#667 (Introduced authentication checks for client-side actions to provide guest users with appropriate warnings.)
#691 (Implemented tag-based filtering in the forum and resolved inconsistencies in the author schema.)
#693 (Developed functionality to create new forum questions with tagging capabilities and link them to relevant quizzes.)
#701 (Designed and implemented a quiz review page for enhanced user interaction and feedback.)
#704 (Resolved issues with unreliable cva class name hierarchies to ensure consistent styling and functionality.)
#709 (Enhanced the profile page and conducted significant refactoring of quiz-related components to align with the objectives of Milestone 2.)
#719 (Added comprehensive tests for utility functions within the client-side codebase to ensure reliability and accuracy.)

Additional

  • I expanded my responsibilities to include server-side development, particularly focusing on designing and implementing request-response schemas for specific endpoints. Recognizing the inefficiencies of strictly separating client and server roles, I adopted an end-to-end ownership approach for the Forum and Quiz features. This involved working across the entire stack, ensuring seamless integration and functionality. My work encompassed:

    • Client-side development: Building and refining components and application logic.
    • Server-side enhancements: Adjusting and optimizing backend logic and schemas to align with frontend needs.
    • System integrity: Testing and debugging across both domains to ensure a smooth, cohesive user experience.
  • I prioritized the enforcement of W3C standards, including WCAG, WAI-ARIA, and SVG accessibility guidelines, to ensure inclusive and user-friendly interfaces. I conducted comprehensive reviews of code written by Hasan Kerem, focusing on:

    • Accessibility: Ensuring adherence to WCAG and ARIA standards for improved usability.
    • Visual Design: Enhancing aesthetic appeal without compromising usability.
    • Best Practices: Aligning with modern accessibility standards and design principles for robust, future-proof solutions.
  • For key features like forum question tagging, quiz rendering, and profile integration, I took ownership of both the client and server-side work, ensuring they worked together smoothly. I also prioritized creating better error-handling pages and refining schemas to avoid mismatches between the frontend and backend. My goal was to keep things simple, clear, and functional while making the app more secure and accessible for everyone.