WoKFlow Gemini Rules — Free Gemini Rules Template
    Neura MarketNeura Market/Gemini
    ChatGPTChatGPTClaudeClaudeGeminiGeminiCursorCursorGrokGrokPerplexityPerplexityDeepSeekDeepSeek
    CoPilotCoPilotStable DiffusionStable DiffusionMidjourneyMidjourney
    View All Directories
    OverviewRulesPromptsMCPsAgentsGamesBlogVideosGuidesCoursesCommunityGemsExtensionsTrending
    GeminiRulesWoKFlow Gemini Rules
    Back to Rules

    WoKFlow Gemini Rules

    howyongheng0313 July 19, 2026
    0 copies 0 downloads
    Rule Content
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Data.Entity;
    using System.Configuration;
    using System.Net.Http;
    using System.Text;
    using System.Web.Script.Services;
    using System.Web.Services;
    using Newtonsoft.Json;
    using Newtonsoft.Json.Linq;
    using WokFlow.Models;
    
    
    namespace WokFlow.Pages.Learner
    {
        public partial class Dashboard : LearnerPage
        {
            private const int PageSize = 6;
            private static readonly HttpClient GeminiClient = new HttpClient
            {
                Timeout = TimeSpan.FromSeconds(20)
            };
    
            // Store current page and total pages in ViewState for pagination
            protected int CurrentPage
            {
                get { return ViewState["CurrentPage"] != null ? (int)ViewState["CurrentPage"] : 1; }
                set { ViewState["CurrentPage"] = value; }
            }
    
            // Calculate total pages based on total course count and page size
            private int TotalPages
            {
                get { return ViewState["TotalPages"] != null ? (int)ViewState["TotalPages"] : 1; }
                set { ViewState["TotalPages"] = value; }
            }
    
            // Page Load
            protected void Page_Load(object sender, EventArgs e)
            {
                if (!IsPostBack)
                {
                    BindCourses();
                }
            }
    
            // Main method to bind courses based on filters, sorting, and pagination
            private void BindCourses()
            {
                using (var db = new WokFlowContext())
                {
                    // Base query for active courses with cuisine data
                    var query = db.Courses
                        .Where(c => c.Status == "Active")
                        .Include("Cuisine")
                        .AsQueryable();
    
                    // Search filter
                    string search = txtSearch.Text.Trim();
                    if (!string.IsNullOrEmpty(search))
                        query = query.Where(c => c.Title.Contains(search));
    
                    // Cuisine filter
                    string cuisine = ddlCuisine.SelectedValue;
                    if (!string.IsNullOrEmpty(cuisine))
                        query = query.Where(c => c.Cuisine.CuisineName == cuisine);
    
                    // Difficulty filter
                    string diff = ddlDifficulty.SelectedValue;
                    int difficulty;
                    if (!string.IsNullOrEmpty(diff) && int.TryParse(diff, out difficulty))
                    {
                        query = query.Where(c => c.Difficulty == difficulty);
                    }
    
                    // Time Posted sort
                    string timeSort = ddlTimePosted.SelectedValue;
                    IQueryable<Course> sortedQuery = timeSort == "oldest"
                        ? query.OrderBy(c => c.CreatedDate)
                        : query.OrderByDescending(c => c.CreatedDate);
    
                    // Pagination
                    int totalCount = sortedQuery.Count();
                    TotalPages = totalCount == 0 ? 1 : (int)Math.Ceiling(totalCount / (double)PageSize);
                    if (CurrentPage > TotalPages) CurrentPage = TotalPages;
                    if (CurrentPage < 1) CurrentPage = 1;
    
                    // Select only necessary fields for display
                    var courses = sortedQuery
                        .Select(c => new
                        {
                            c.CourseId,
                            c.Title,
                            c.Description,
                            CuisineName = c.Cuisine != null ? c.Cuisine.CuisineName : "Unknown",
                            c.Duration,
                            c.Difficulty,
                            c.ImageUrl
                        })
                        .Skip((CurrentPage - 1) * PageSize)
                        .Take(PageSize)
                        .ToList();
    
                    // Get enrolled course IDs for current user
                    ViewState["EnrolledIds"] = db.Enrollments
                        .Where(en => en.UserId == CurrentUserId)
                        .Select(en => en.CourseId)
                        .ToList();
    
                    rptCourses.DataSource = courses;
                    rptCourses.DataBind();
    
                    BindPagination();
                }
            }
    
            // Bind pagination controls based on total pages and current page
            private void BindPagination()
            {
                // Generate page numbers for pagination
                var pages = Enumerable.Range(1, TotalPages)
                    .Select(i => new { PageNumber = i })
                    .ToList();
    
                rptPages.DataSource = pages;
                rptPages.DataBind();
    
                btnPrev.Enabled = CurrentPage > 1;
                btnNext.Enabled = CurrentPage < TotalPages;
            }
    
            // Check user enrollment status
            protected bool IsEnrolled(int courseId)
            {
                var ids = ViewState["EnrolledIds"] as List<int>;
                return ids != null && ids.Contains(courseId);
            }
    
            // Get CSS class for course card based on enrollment status
            protected string GetCardClass(int courseId)
            {
                string baseClass = "glass-panel rounded-2xl overflow-hidden hover:shadow-lg transition-all";
                return IsEnrolled(courseId) ? baseClass + " cursor-pointer" : baseClass;
            }
    
            // Get hyperlink for course card based on enrollment status
            protected string GetCardHref(int courseId)
            {
                if (!IsEnrolled(courseId)) return "";
                return ResolveUrl("~/Pages/Shared/CourseDetail.aspx?id=" + courseId);
            }
    
            // Handle Join button click to enroll user in course
            protected void rptCourses_ItemCommand(object source, RepeaterCommandEventArgs e)
            {
                // Only handle Join command
                if (e.CommandName == "Join")
                {
                    int courseId;
    
                    // Validate course ID from command argument
                    if (!int.TryParse(e.CommandArgument.ToString(), out courseId))
                        return;
    
                    using (var db = new WokFlowContext())
                    {
                        // Check if user is already enrolled in the course
                        bool alreadyEnrolled = db.Enrollments.Any(en =>
                            en.UserId == CurrentUserId && en.CourseId == courseId);
    
                        if (!alreadyEnrolled)
                        {
                            // Create enrollment
                            var enrollment = new Enrollment
                            {
                                UserId = CurrentUserId,
                                CourseId = courseId,
                                EnrollmentDate = DateTime.UtcNow,
                                Progress = 0,
                                Status = "In Progress",
                                CreatedAt = DateTime.UtcNow,
                                UpdatedAt = DateTime.UtcNow
                            };
                            db.Enrollments.Add(enrollment);
                            db.SaveChanges();
    
                            // Unlock first chapter
                            var firstChapter = db.Chapters
                                .Where(ch => ch.CourseId == courseId)
                                .OrderBy(ch => ch.ChapterOrder)
                                .FirstOrDefault();
    
                            if (firstChapter != null)
                            {
                                // Create progress record for the first chapter
                                var progress = new UserChapterProgress
                                {
                                    UserId = CurrentUserId,
                                    EnrollmentId = enrollment.EnrollmentId,
                                    ChapterId = firstChapter.ChapterId,
                                    IsCompleted = false,
                                    CreatedAt = DateTime.UtcNow,
                                    UpdatedAt = DateTime.UtcNow
                                };
                                db.UserChapterProgress.Add(progress);
                                db.SaveChanges();
                            }
                        }
    
                        // Redirect to course detail
                        Response.Redirect("~/Pages/Shared/CourseDetail.aspx?id=" + courseId);
                    }
                }
            }
    
            // Handle filter changes to reset to first page and rebind courses
            protected void Filter_Changed(object sender, EventArgs e)
            {
                CurrentPage = 1;
                BindCourses();
            }
    
            // Handle pagination button clicks to navigate between pages
            protected void btnPrev_Click(object sender, EventArgs e)
            {
                if (CurrentPage > 1)
                {
                    CurrentPage--;
                    BindCourses();
                }
            }
    
            // Handle pagination button clicks to navigate between pages
            protected void btnNext_Click(object sender, EventArgs e)
            {
                if (CurrentPage < TotalPages)
                {
                    CurrentPage++;
                    BindCourses();
                }
            }
    
            // Handle page number clicks in pagination to navigate to specific page
            protected void rptPages_ItemCommand(object source, RepeaterCommandEventArgs e)
            {
                // Only handle Page command
                if (e.CommandName == "Page")
                {
                    int page;
    
                    // Validate page number from command argument
                    if (!int.TryParse(e.CommandArgument.ToString(), out page))
                        return;
    
                    // Ensure page number is within valid range before navigating
                    if (page >= 1 && page <= TotalPages)
                    {
                        CurrentPage = page;
                        BindCourses();
                    }
                }
            }
    
            public class ChatTurn
            {
                public string Role { get; set; }
                public string Text { get; set; }
            }
    
            public class ChatResponse
            {
                public string Reply { get; set; }
                public bool ShowContact { get; set; }
            }
    
            [WebMethod(EnableSession = true)]
            [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
            public static ChatResponse Chat(string message)
            {
                var context = HttpContext.Current;
                if (context == null || context.Session == null || context.Session["UserId"] == null)
                {
                    return new ChatResponse { Reply = "Please log in to use the assistant.", ShowContact = false };
                }
    
                string text = (message ?? string.Empty).Trim();
                if (string.IsNullOrEmpty(text))
                {
                    return new ChatResponse { Reply = "Please enter a question about WokFlow.", ShowContact = false };
                }
    
                if (!IsRelevantToWokFlow(text))
                {
                    return new ChatResponse
                    {
                        Reply = "Sorry, I can only answer questions about WokFlow features, courses, and learning.",
                        ShowContact = false
                    };
                }
    
                string role = (context.Session["UserRole"] as string ?? string.Empty).ToUpperInvariant();
                if (RequiresHigherAuthorization(text, role))
                {
                    return new ChatResponse
                    {
                        Reply = "That request needs higher authorization. Please contact support for help.",
                        ShowContact = true
                    };
                }
    
                string apiKey = ConfigurationManager.AppSettings["GeminiApiKey"];
                if (string.IsNullOrWhiteSpace(apiKey))
                {
                    return new ChatResponse
                    {
                        Reply = "The assistant is not configured. Please contact support.",
                        ShowContact = true
                    };
                }
    
                string model = ConfigurationManager.AppSettings["GeminiModel"];
                if (string.IsNullOrWhiteSpace(model))
                {
                    model = "gemini-2.5-flash";
                }
    
                try
                {
                    var sessionHistory = context.Session["WfChatHistory"] as List<ChatTurn>;
                    if (sessionHistory == null)
                    {
                        sessionHistory = new List<ChatTurn>();
                    }
    
                    sessionHistory.Add(new ChatTurn { Role = "user", Text = text });
    
                    string reply = CallGemini(apiKey, model, text, sessionHistory);
                    if (string.IsNullOrWhiteSpace(reply))
                    {
                        reply = "Sorry, I could not generate a response. Please try again.";
                    }
    
                    sessionHistory.Add(new ChatTurn { Role = "model", Text = reply });
                    context.Session["WfChatHistory"] = sessionHistory;
    
                    return new ChatResponse { Reply = reply, ShowContact = false };
                }
                catch
                {
                    return new ChatResponse
                    {
                        Reply = "Sorry, I could not reach the assistant service right now.",
                        ShowContact = true
                    };
                }
            }
    
            [WebMethod(EnableSession = true)]
            [ScriptMethod(ResponseFormat = ResponseFormat.Json)]
            public static List<ChatTurn> GetChatHistory()
            {
                var context = HttpContext.Current;
                if (context == null || context.Session == null || context.Session["UserId"] == null)
                {
                    return new List<ChatTurn>();
                }
    
                var sessionHistory = context.Session["WfChatHistory"] as List<ChatTurn>;
                return sessionHistory ?? new List<ChatTurn>();
            }
    
            private static bool IsRelevantToWokFlow(string message)
            {
                string text = message.ToLowerInvariant();
    
                string[] quickOk =
                {
                    "hi", "hello", "hey", "help", "support", "wokflow"
                };
                if (quickOk.Any(text.Contains)) return true;
    
                string[] keywords =
                {
                    "course", "courses", "chapter", "chapters", "lesson", "lessons",
                    "recipe", "cuisine", "difficulty", "duration", "enroll", "enrollment",
                    "join", "dashboard", "search", "filter", "progress", "quiz", "question",
                    "answer", "comment", "profile", "my courses", "rating", "stars",
                    "sharer", "learner", "admin", "analytics", "create course", "content",
                    "registration", "upgrade", "report", "reported", "certificate",
                    "system", "use the system", "how to use"
                };
    
                return keywords.Any(text.Contains);
            }
    
            private static bool RequiresHigherAuthorization(string message, string role)
            {
                string text = message.ToLowerInvariant();
    
                string[] adminOnly =
                {
                    "user management", "manage users", "platform analytics",
                    "content management", "reported content", "approve sharer",
                    "reject sharer", "admin dashboard", "ban user", "delete user"
                };
    
                string[] sharerOnly =
                {
                    "create course", "edit course", "delete course", "publish course",
                    "sharer analytics", "manage chapters", "upload recipe"
                };
    
                bool asksAdmin = adminOnly.Any(text.Contains);
                bool asksSharer = sharerOnly.Any(text.Contains);
                bool askingToBecomeSharer = text.Contains("become a sharer") || text.Contains("upgrade to sharer") || text.Contains("sharer registration");
    
                if (askingToBecomeSharer) return false;
    
                if (asksAdmin && role != "ADMIN") return true;
                if (asksSharer && role != "SHARER" && role != "ADMIN") return true;
    
                return false;
            }
    
            private static string CallGemini(string apiKey, string model, string message, List<ChatTurn> history)
            {
                var contents = new List<object>();
    
                string systemPrompt = BuildSystemPrompt();
                contents.Add(new
                {
                    role = "user",
                    parts = new[] { new { text = systemPrompt } }
                });
    
                bool appendedFromHistory = false;
                if (history != null)
                {
                    foreach (var turn in history.Where(t => t != null && !string.IsNullOrWhiteSpace(t.Text)))
                    {
                        string role = (turn.Role ?? "user").ToLowerInvariant();
                        role = role == "model" ? "model" : "user";
                        contents.Add(new
                        {
                            role,
                            parts = new[] { new { text = turn.Text } }
                        });
                        appendedFromHistory = true;
                    }
                }
    
                bool lastIsSame = false;
                if (history != null && history.Count > 0)
                {
                    var last = history[history.Count - 1];
                    if (last != null && string.Equals(last.Text, message, StringComparison.Ordinal) && string.Equals(last.Role, "user", StringComparison.OrdinalIgnoreCase))
                    {
                        lastIsSame = true;
                    }
                }
    
                if (!appendedFromHistory || !lastIsSame)
                {
                    contents.Add(new
                    {
                        role = "user",
                        parts = new[] { new { text = message } }
                    });
                }
    
                var payload = new
                {
                    contents,
                    generationConfig = new
                    {
                        temperature = 0.2,
                        maxOutputTokens = 512,
                        topP = 0.9
                    }
                };
    
                string url = $"https://generativelanguage.googleapis.com/v1beta/models/{model}:generateContent";
                string json = JsonConvert.SerializeObject(payload);
    
                var request = new HttpRequestMessage(HttpMethod.Post, url);
                request.Headers.Add("x-goog-api-key", apiKey);
                request.Content = new StringContent(json, Encoding.UTF8, "application/json");
    
                var response = GeminiClient.SendAsync(request).GetAwaiter().GetResult();
                string body = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
    
                if (!response.IsSuccessStatusCode)
                {
                    return string.Empty;
                }
    
                var root = JObject.Parse(body);
                return root["candidates"]?[0]?["content"]?["parts"]?[0]?["text"]?.ToString() ?? string.Empty;
            }
    
            private static string BuildSystemPrompt()
            {
                return "You are the WokFlow Assistant. WokFlow is a cooking education platform where sharers " +
                       "create courses and recipes, and learners join courses to learn chapter by chapter. " +
                       "Key features: course search and filters (cuisine, difficulty, time posted), join courses, " +
                       "view course details, track progress per chapter, quizzes, comments, and a My Courses page " +
                       "for joined or created courses. Learners can upgrade to sharer by submitting a sharer " +
                       "registration with proof. Sharers can create/edit courses and view their analytics. " +
                       "Admins manage users, content, and sharer registrations, and view platform analytics. " +
                       "Rules: only answer questions about WokFlow features and usage. If a question is unrelated, " +
                       "respond: \"Sorry, I can only answer questions about WokFlow features, courses, and learning.\" " +
                       "If the request requires higher authorization, respond: \"That request needs higher authorization. " +
                       "Please contact support for help.\" Keep answers concise, actionable, and do not invent data.";
            }
        }
    }
    

    Comments

    More Rules

    View all

    Sleepycat Seo Platform Gemini Rules

    A
    acovrp

    LITE IDE Gemini Rules

    H
    Heyz24

    Shadowtagai Monorepo V2 Gemini Rules

    S
    ShadowTag-v2

    MetaPrompter Gemini Rules

    U
    ummerr

    Taskora Gemini Rules

    K
    kabilesh-c

    Iilm Faculty Connect Gemini Rules

    R
    Rudrakshsachdev

    Stay up to date

    Get the latest Gemini prompts, rules, and resources delivered to your inbox weekly.

    Neura Market LogoNeura Market

    Discover the best AI prompts, plugins, and resources for Gemini and more.

    Content Types

    • Rules
    • Prompts
    • MCPs
    • Agents
    • Guides

    Platforms

    • ChatGPT Directory
    • Claude Directory
    • Gemini Directory
    • Cursor Directory
    • Grok Directory
    • Perplexity Directory
    • DeepSeek Directory
    • CoPilot Directory
    • Stable Diffusion Directory
    • Midjourney Directory
    • All Directories

    Resources

    • Blog
    • Documentation
    • Help Center
    • Marketplace

    Legal

    • Privacy Policy
    • Terms of Service

    © 2026 Neura Market. All rights reserved.

    |

    Not affiliated with any AI platform vendors.

    Neura Market

    Custom AI Systems & Services

    Our team of experienced AI builders will help build custom AI systems, workflows, and solutions for your business.

    Request custom work

    Ready-made automations for this

    Workflows from the Neura Market marketplace related to this Gemini resource

    • Process Multiple Media Files in Telegram with Gemini AI & PostgreSQL Databasen8n · $24.99 · Related topic
    • Convert Telegram Messages to Professional LinkedIn Posts with Gemini AI & Approval Workflown8n · $24.99 · Related topic
    • Create Custom PDF Documents from Templates with Gemini & Google Driven8n · $24.99 · Related topic
    • Kubernetes RCA and Alerting Using Gemini, Loki, Prometheus, Slackn8n · $24.99 · Related topic
    Browse all workflows